Issue Number | 3307 |
---|---|
Summary | Eliminate need to register cdr.dll each time user starts XMetaL |
Created | 2011-02-15 16:00:26 |
Issue Type | Bug |
Submitted By | Englisch, Volker (NIH/NCI) [C] |
Assigned To | Kline, Bob (NIH/NCI) [C] |
Status | Closed |
Resolved | 2013-07-11 18:57:10 |
Resolution | Fixed |
Path | /home/bkline/backups/jira/ocecdr/issue.107635 |
BZISSUE::4999
BZDATETIME::2011-02-15 16:00:26
BZCREATOR::Volker Englisch
BZASSIGNEE::Bob Kline
BZQACONTACT::William Osei-Poku
The upcoming removal of administrative rights that has been announced
by the NIH will make it impossible for our users to run our CDRLoader in
order to start and setup XMetaL.
We would need to modify the way our CDRLoader is currently working in
order to allow it to function properly once the administrative rights
have been removed on the users workstations running XP.
BZDATETIME::2011-02-15 16:25:26
BZCOMMENTOR::Volker Englisch
BZCOMMENT::1
Reassigning to Alan.
BZDATETIME::2011-02-15 16:31:24
BZCOMMENTOR::Bob Kline
BZCOMMENT::2
Volker:
Please sweep through this list and remove anyone you know to be gone (also, please set their expired column to some date in the past in the usr table on Bach). Then send the modified spreadsheet to Jonathan and Rick.
Attachment CDRUsers.xls has been added with description: List of active CDR users
BZDATETIME::2011-02-15 17:43:28
BZCOMMENTOR::Alan Meyer
BZCOMMENT::3
I'll try to come up with a list of alternative solutions.
BZDATETIME::2011-02-15 23:54:03
BZCOMMENTOR::Alan Meyer
BZCOMMENT::4
Here's one possible solution.
I've done some research on creating a proxy dll that would
stand
between our Javascript code and our C++ Cdr.dll. It involves
many techniques that I've never used before, and a fair amount of
Windows specific technology. I've barely begun to understand the
details of how to do it.
Conceptually, it would work something like this:
Create a new C++ program that we might call CdrProxy.cpp.
This would compile to CdrProxy.dll, which would be
registered in the normal way on each user's machine by
someone with administrative privileges.
Cdr.mcr would be modified to load CdrProxy.dll as an
ActiveXObject instead of Cdr.dll.
CdrProxy.cpp includes the Commands.h header file that is
also included by many of the modules that make up Cdr.dll.
I don't know if anything else need be shared between the
two.
CdrProxy.cpp would do the following:
Dynamically load Cdr.dll from some known place that is
user writable without administrative permissions.
For each public function in Cdr.dll:
Create a function pointer that points to that function.
Initialize the pointer using a Windows system call
(GetProcAddress) that returns a pointer to the Cdr.dll
function. For example, let's say that "proxyLogon"
contains a pointer to the "logon" function in Cdr.dll.
Create a function with the same name and signature as
the function in Cdr.dll. The function has the form:
... logon(...)
{
return (*proxyLogon) (...);
}
The work for all 31 or so public functions is the same.
If we figure out how to do one, it's just a matter of
some cutting, pasting, and editing to implement all of
them. Each one is just a pass through to a call
through a function pointer.
We might also add a dozen or more new stub functions with a
variety of common signatures to Commands.h and Commands.cpp (or
maybe NewFuncs.cpp). Their purpose would simply be as
placeholders for any new functions we need but don't know what
they might be yet. We could give them standard names like
newFunc01, newFunc02, ... newFuncNN, etc.
It seems conceivable to me (an ignorant person can often
conceive
a lot more than someone who knows the real state of affairs) that
we can do this with no significant changes either to any Cdr.mcr
or Cdr.dll code, except maybe to add a NewFuncs.cpp file with
stub functions in it for future expansion.
All interactions between Cdr.mcr and Cdr.dll look like they
pass
and return primitive data types. That should continue to work
with a proxy in between. Any state currently stored in the
Cdr.dll objects would continue to be stored there. I'm not
seeing any obvious barrier to making this work except that we
have to get down the right C++ and Windows declarations and
system calls.
Then, as long as the calling signatures don't change, we can
change anything we like in Cdr.dll and re-download the executable
from a server over top of whatever Cdr.dll was already there.
If we need something new, we can implement it by providing a
real
function body in place of one of the newFuncNN stubs, and just
comment the code as a substitute for having a meaningful name
(ugly but it obviates requiring administrative privileges to add
a new function.)
Hopefully, we won't need anything like this. It may be that the
"Privilege Manager" program will provide a better and simpler
solution. I won't do any more work on this task until we decide
we need more.
BZDATETIME::2011-02-15 23:55:45
BZCOMMENTOR::Alan Meyer
BZCOMMENT::5
It looks like Bob and Volker weren't on the CC list. I've added
them. Please see comment #4.
BZDATETIME::2011-02-16 10:07:14
BZCOMMENTOR::Volker Englisch
BZCOMMENT::6
(In reply to comment #4)
> Hopefully, we won't need anything like this. It may be that
the
> "Privilege Manager" program will provide a better and simpler
> solution.
It seems that way. Creating the new rule was a 2 minute task plus additional 5 minutes of testing.
BZDATETIME::2011-02-17 22:05:48
BZCOMMENTOR::Alan Meyer
BZCOMMENT::7
I don't want to pursue this much since it looks like we have a
solution, however Bob came up with a very creative idea today
that is worth recording
Bob's idea simplifies the proxy DLL approach and makes it much
more readable and straightforward. It can be used to handle new
functions much more easily than my newFuncXX method and, if we
want to do some work in the JavaScript and C++, we can also
retrofit it for more straightforward communication with all of
the existing functions.
His idea was to communicate between the JavaScript and the DLL
using a universal single string argument call from JavaScript to
C++. The most straightforward form for the string would be XML,
in the spirit of our communication with the CdrServer or with
many AJAX, SOAP, and other client/server communication protocols.
In the most thorough implementation of this idea there would be
only one JavaScript function that calls the ActiveXObject (which
fronts for the proxy, which then fronts for the real C++ DLL.)
That one function would pass an XML string with a command name
and all the command arguments that need to be passed to the C++.
One function in the pre-registered CdrProxy.dll would in turn
only need to know the name of one function in the real Cdr.dll
and need only one pointer to that function. It would call that
one function and get back an XML string which it would return to
the JavaScript.
For this thorough implementation we would need to re-write all
of
the JavaScript DLL calls to instead construct an XML string and
call the single pass-through function, passing it in. They'd
also need to parse the output XML to get any required return
codes and results. Similarly, at the DLL end there would need to
be something that parses all of the input XML, calls the actual
functions to do the work, then packages the results in XML for
return. Actual XML construction and parsing could be centralized
in functions that handle the details, so the burden of doing this
wouldn't necessarily be very great.
An alternative solution is to implement the CdrProxy.dll
exactly
as I described it except, instead of a set of newFuncXX stubs, we
would implement a single function with a name like callCmd() that
would handle all new functions using Bob's technique. This
requires no significant change to JavaScript or C++. Only new
functions would be affected.
BZDATETIME::2011-02-17 22:14:18
BZCOMMENTOR::Alan Meyer
BZCOMMENT::8
I also did a little more research on the issue of loading a DLL
dynamically from within JavaScript.
I haven't found any hope of doing it without registering the
DLL.
Client side JavaScript was intended for execution within a web
browser and so has more security restrictions than most
programming environments. Although I still haven't found a flat
statement anywhere that says we absolutely can't dynamically load
an unregistered DLL, I haven't found any way to do it and I'm not
hopeful that I ever will. It looks like it may actually have
been possible to do this with VBScript in the past, but there
were so many hacking attacks that exploited it that Microsoft
changed their approach and forbade it. So it looks like we'll
either need the Privilege Manager or the CdrProxy.dll approach -
unless there's another approach I haven't thought of.
BZDATETIME::2011-03-14 11:54:38
BZCOMMENTOR::Alan Meyer
BZCOMMENT::9
Since we have a fix for this using Privilege Manager software, I'm marking this issue as resolved-fixed.
BZDATETIME::2011-07-14 14:01:43
BZCOMMENTOR::Bob Kline
BZCOMMENT::10
Please ignore previous comment: this still needs to be addressed.
BZDATETIME::2011-07-26 21:41:49
BZCOMMENTOR::Alan Meyer
BZCOMMENT::11
Doing more research, it appears to me that Microsoft put a back door into Internet Explorer versions 7 and 8 that allows non-administrative users to download and install ActiveX controls from the Internet. They may have taken significant heat from their own community about the number of IE extensions that were broken by Vista, so they opened a path to enable OCX and DLL files to be installed and registered by Internet Explorer running for a user without admin rights - and with other ways for administrators to clamp down if they need to.
See: http://msdn.microsoft.com/en-us/library/dd433049%28VS.85%29.aspx
There may be a way for us to take advantage of this but there appears to be a learning curve (for me anyway) to climb before we can find out if we can use it, and with no reason to believe it will work better than, or even as well as, the other plan. I'm going to pursue the plan outlined in comment 4 and 7 and only look at this alternative if that one runs into trouble.
BZDATETIME::2011-07-26 23:15:42
BZCOMMENTOR::Alan Meyer
BZCOMMENT::12
Windows is smart. It blocked my test program from running using the "Data Execution Prevention" subsystem. I can easily overcome that. All I need is my administrative password, just what we're trying to avoid requiring users to have.
This is going to take more Windows OS security research.
BZDATETIME::2011-07-26 23:31:12
BZCOMMENTOR::Alan Meyer
BZCOMMENT::13
The data execution prevention (DEP) block seems to apply to the calling program, not the called (dll) program. That may mean that we need an administrator to bless the program one time, but not to bless each new dll that we download. That's progress and may be okay. It's possible that the local security people just have to be involved once for the lifetime of a machine - though I'm not near being able to confirm that yet.
I appear to have gotten past the DEP. Now I have to get past the next hurdle in getting the test program to work.
It's been many years since I did any Windows API programming, and I never did a lot of it, so I'm feeling my way through.
BZDATETIME::2011-07-28 20:56:43
BZCOMMENTOR::Alan Meyer
BZCOMMENT::14
I wrote some test programs using the following pattern
A.exe loads B.dll.
B.dll loads C.dll.
A calls a function in B which calls a function in C that
returns a value to B that returns the same value to A.
There were no paths in any of the LoadLibrary calls to load the
DLLs. Everything was just in the same directory.
In order to make this work, I had to tell Windows to allow an
exemption for A in "Data Execution Prevention" (DEP). I presume
I was only able to do that because I am an administrator on my
machine.
Having done that, I could change B and C as much as I wanted,
and
even A too, since the exemption was on the name, not the bytes in
the program. I never had to tell Windows again to exempt A.
I think that if we adopt a solution like that in comments 4
&
7, we'll only need to make the exemption once for XMetal and then
we'll be okay on that machine for as long as we use it.
However, before I do any further work on this, I'd like to talk
to Bob to better understand how we're loading cdr.dll now - just
in case there's a way to load the DLL dynamically and use the
DEP exemption to enable Windows 7 to allow it to be invoked.
BZDATETIME::2011-12-29 16:22:11
BZCOMMENTOR::Alan Meyer
BZCOMMENT::15
Lowering priority to P6.
BZDATETIME::2012-09-13 13:17:07
BZCOMMENTOR::Bob Kline
BZCOMMENT::16
We've come up with a solution for this problem, registering the DLL in the Current User hive of the registry.
BZDATETIME::2012-10-11 15:59:18
BZCOMMENTOR::Bob Kline
BZCOMMENT::17
I've got a new package for CDR client file installation, which I will install on the software drive as soon as the directory for the package has been created. The new version of the installation instructions is at
I'd like to get this rolled out on as many client machines as possible, with the corresponding files on Mahler (they're already there) and Franck (not yet there). Here's how it will work: during the testing period only those users with the new CDR client loader installed will connect with Mahler and Franck, and they'll do so using a new shortcut on their desktops labeled simply "CDR." When they connect with Bach they'll use the old CdrXMetaL45 shortcut. When we're satisfied that the new loader is working correctly, we'll roll it out to all CDR users' workstations and laptops, remove the old shortcut, and everyone will use the new "CDR" desktop shortcut to connect to any of the CDR servers. My hope is that all of the IT support staff who are involved in installing CDR/XMetaL will review the setup configuration, participate in the shakedown testing, and provide feedback on how it can be improved.
BZDATETIME::2012-10-12 14:16:37
BZCOMMENTOR::Bob Kline
BZCOMMENT::18
The new client file installation package is now in place on the OCE Software drive:
imbncipf01\software$\CDRClientSetup
According to Carbie, only my account and the account for the TerpSys engineer who is responsible for installing the CDR have been granted permission to run this installer (though I wouldn't be surprised if Volker and Alan can run it also).
Once we've discussed a plan for testing and rollout I will provide William and Lockheed with a copy of the package and instructions.
I have checked in the source code modifications for the CdrClient executable (that's the program which refreshes the CDR client files and launches XMetaL); these modifications include:
using the new DLL registration approach
preliminary support for XMetaL 7.0 [currently disabled]
modifications needed for building with Visual Studio 2010
I have also checked in the source code for the program I created to launch the script which installs the CDR client files. This program passes the script the location of the files, eliminating the need to run the script from a specific location, or from a console window which has the current working directory set to the location of the files to be installed. The source code for this program is InstallCdrClientFiles.c and it's checked into the same directory as the source code for the CdrClient program (/trunk/XMetaL/CdrClient).
BZDATETIME::2012-10-17 11:03:41
BZCOMMENTOR::William Osei-Poku
BZCOMMENT::19
(In reply to comment #17)
> I've got a new package for CDR client file installation, which I
will install
> on the software drive as soon as the directory for the package has
been
> created. The new version of the installation instructions is
at
>
> http://mahler.nci.nih.gov/cgi-bin/cdr/Filter.py?DocId=CDR0000000263&Filter=name:Documentation+Help+Screens+Filter
>
The installation instructions look good to me. We do have a customized
version for our environment so I will update it appropriately. I will
also replace the old CDR Loader files with the new one in the copy of
the installation files we have.
BZDATETIME::2012-10-25 15:28:53
BZCOMMENTOR::Bob Kline
BZCOMMENT::20
I reached out to Nick King, but haven't gotten a response from him to my email message, so I filed a ticket with the NIH help desk in order to get assistance with making the setup process for the new CDR client files configuration to work correctly under as many sets of conditions as possible. Here's what I wrote when I created the ticket:
"ICRDB at NCI uses a customized version of XMetaL, which is an off-the-shelf XML editing computer program. We are working to eliminate problems which prevent the software from working properly on workstations which have restricted rights for the users and/or are running more recent versions of Windows that that for which the editor and our customizations were originally written. We need to work with the IT staff responsible for installing this program and our customizations in order for us to understand the restrictions imposed on the users' workstations, and to ensure that the setup package we put together meets the requirements and needs of the staff doing the installation."
BZDATETIME::2012-12-12 12:17:50
BZCOMMENTOR::William Osei-Poku
BZCOMMENT::21
I am getting a dll error on a new W7 laptop that we just did a new XMetal installation. The installation itself went well without any problems. However, when the user logs in, the client files attempt to refresh for about a minute or so and then comes up with "Failure registering Cdr.dll:No error" message. I have attached a screenshot of the error message which also has the path to the location of the CdrClient20121012-1038.exe file.
Attachment CDR_DLL_ERROR.doc has been added with description: CDR DLL error
BZDATETIME::2012-12-12 12:30:04
BZCOMMENTOR::Bob Kline
BZCOMMENT::22
Can you bring the laptop to tomorrow's status meeting?
BZDATETIME::2012-12-12 13:09:33
BZCOMMENTOR::Volker Englisch
BZCOMMENT::23
Maybe you could attach the log file (not necessary if you're bringing the machine tomorrow)?
BZDATETIME::2012-12-12 13:38:55
BZCOMMENTOR::William Osei-Poku
BZCOMMENT::24
I have attached the file even though I may be able to bring the laptop with me tomorrow.
Attachment CdrClient.log has been added with description: CDR log
BZDATETIME::2012-12-13 12:12:23
BZCOMMENTOR::William Osei-Poku
BZCOMMENT::25
After a little bit of troubleshooting I found out what the problem was. Rather, I think I found a way around it. We are running the XMetal on W7 in XP SP3 compatibility mode because we experience frequent CDR freezes when not running in XP SP3 compatibility mode.
The problem is that, if you set the program to run in XP SP3 mode while not already logged into the CDR, you get the unable to register Cdr.dll error. However, when you first log in to the CDR before setting the program to run in XP SP3 compatibility mode, it works fine and you don't have to do it each time you login to the CDR. You just have to do it once. So for now everything seems to be working well on the laptop.
Per discussion at the status meeting this issue can now be closed since we've moved to the CBIIT environment.
File Name | Posted | User |
---|---|---|
CDR_DLL_ERROR.doc | 2012-12-12 12:17:50 | Osei-Poku, William (NIH/NCI) [C] |
CdrClient.log | 2012-12-12 13:38:55 | Osei-Poku, William (NIH/NCI) [C] |
CDRUsers.xls | 2011-02-15 16:31:24 |
Elapsed: 0:00:00.001070