LoadLibrary giving system err 183 while loading Crypto dll
We are facing some issue with crypto dll (C++ dll distributed by Wei Dai)and would really appreciate if you could help on this. We are using cryptopp version 5.6.1.0.
We have 2 separate java programs, both use the system.load()function to load a Cryptowrapper dll (it’s a CPP program which acts as a JNI). This Cryptowrapper inturn calls encrypt/decrypt functions in Crypto.dll.
For one of the Java program it works without any issue. The password gets encrypted properly.
But the other Java program when it invokes the JNI Cryptowrapper dll which further tries to load the crypto.dll. The crypto.dll loading fails; did a GetLastError()and got the system error code as 183.
myCrypto = LoadLibrary (cryptoPath1);
here cryptoPath1 points to the complete path to crypto.dll.
Tried using both Loadlibrary() and LoadlibraryEx(), still it didn’t work.
myCrypto =LoadLibraryEx(cryptoPath1, NULL, LOAD_IGNORE_CODE_AUTHZ_LEVEL);
Details about environment – Win XP/ MS Visual studio 2010 runtime environment. This issue is replicated consistently on multiple test machines.
Thanks in advance..
Re: LoadLibrary giving system err 183 while loading Crypto dll
Is this "cryptoPath1" a full pathname?
Re: LoadLibrary giving system err 183 while loading Crypto dll
Error code 183 means 'Cannot create a file when that file already exists.'
Re: LoadLibrary giving system err 183 while loading Crypto dll
@VictorN - yes, "cryptoPath1" a full pathname (including the dll name).
@2kaud - yes, 183 means 'Cannot create a file when that file already exists.' ..I am not sure what it means. Does it mean my dll is aleardy loaded in memory, so it cann't load it again? If so, then why don't I see this error when the other Java program tries to load the same dll? In that case, the LoadLibrary is successful; further it gets the handle of the function and executes the function from the dll to give the correct result in return.
That is what is confusing the same JNI being refered by two Java program in similar way - in one case the JNI successfully loads the crypto dll while in another case it gives err 183.
Thanks..
Re: LoadLibrary giving system err 183 while loading Crypto dll
A slight correction in the last line of my original post. This issue is Not recreated on all the test machines. However, on multiple machines where it does gets recreated, I am able to replicate it consistently.
Thanks..
Re: LoadLibrary giving system err 183 while loading Crypto dll
Quote:
Originally Posted by
RituP
here cryptoPath1 points to the complete path to crypto.dll.
And maybe it doesn't. How would we know if this is true or not?
Why not actually hard-code the name into your application and see what happens? That would have been the first thing I would have tried. Right now, you're showing us a variable, and there is no way we can look inside that variable to verify your claim that the name is correct. Maybe you have a stray character in there in the string somewhere, who knows?
That's why you should test by hardcoding the path to ensure that the error is not because of faulty coding in setting up that variable.
Quote:
Tried using both Loadlibrary() and LoadlibraryEx(), still it didn’t work.
An error 183 can also mean that the DLL is trying to load dependent DLL's and it can't find those DLL's or those DLL's are giving this error. Use DependencyWalker or some other application to see what other DLL's are dependent on this DLL at load time.
Regards,
Paul McKenzie
Re: LoadLibrary giving system err 183 while loading Crypto dll
Quote:
Originally Posted by
RituP
@2kaud - yes, 183 means 'Cannot create a file when that file already exists.' ..I am not sure what it means. Does it mean my dll is aleardy loaded in memory, so it cann't load it again?
It depends on the DLL. Some DLL's may not allow multiple loading and in DllMain() return FALSE.
If your DLL has a DllMain(), you can debug it by placing a breakpoint in the DllMain() function to see if DllMain() gets called, but for some reason returns FALSE.
Regards,
Paul McKenzie
Re: LoadLibrary giving system err 183 while loading Crypto dll
Hi Paul,
Thats the very first thing even we tried out - hardcoding the path and then also it gave us the same error 183. Moreover we are writing all the variable values in a log file, so we do know that the path is correct. Had the path been incorrect, the first Java appliaction wouldnt have given correct results as it uses the same JNI (aCPP program named as CryptoWrapper which is trying to load crypto.dll using LoadLibrary).
Nevertheless the harcoded path in CryptoWrapper also results in the same error when referred from the second Java program.
I will give a try to the dependency walker and see if we could figure out something from that.
Thanks..
Quote:
Originally Posted by
Paul McKenzie
And maybe it doesn't. How would we know if this is true or not?
Why not actually hard-code the name into your application and see what happens? That would have been the first thing I would have tried. Right now, you're showing us a variable, and there is no way we can look inside that variable to verify your claim that the name is correct. Maybe you have a stray character in there in the string somewhere, who knows?
That's why you should test by hardcoding the path to ensure that the error is not because of faulty coding in setting up that variable.
An error 183 can also mean that the DLL is trying to load dependent DLL's and it can't find those DLL's. Use DependencyWalker or some other application to see what other DLL's are dependent on this DLL at load time.
Regards,
Paul McKenzie
Re: LoadLibrary giving system err 183 while loading Crypto dll
I suspect that you are getting error 183 because the DllMain function of Crypto.dll is returning FALSE when it is called with DLL_PROCESS_ATTACH.
On the computers on which it fails, have you tried re-registering crypto using regsvr32?
Re: LoadLibrary giving system err 183 while loading Crypto dll
hi 2kaud,
The JNI Cryptowrapper program has a reference of the two functions encrypt/decrypt of crypto.dll.
typedef int (*ENCRYPT) (char *, char *, char *);
typedef int (*DECRYPT) (char *, char *, char *);
The usual process is - after loading the crypto dll,
Code:
HINSTANCE myCrypto = (HINSTANCE)NULL;
myCrypto = LoadLibrary(cryptoPath1); T
It should retrieve the address of decrypt function defined in the crypto.dll
Code:
DECRYPT decryptAddress;
decryptAddress= (DECRYPT)GetProcAddress(myCrypto, "decrypt");
Once the address is retrieved, the respective function call is done with the parameters and the output is returned in the 'out' variable.
Code:
int code = (decryptAddress)((char *) pswd, (char *) out, (char*)key);
This 'out' variable is then formatted and returned to the calling Java program.
In our case it fails at the LoadLibrary step, further it doesnt retrieve the proc address for decrypt function.
I believe the Crypto.dll is to be loaded implictly. When I try to register it using regsvr32, it gives the following message:
'<dll_name (full path)> was loaded, but the DllUnregisterServer entry point was not found. The file can not be registered.'
Thanks..
Re: LoadLibrary giving system err 183 while loading Crypto dll
Try using LoadLibraryEx with dwFlags DONT_RESOLVE_DLL_REFERENCES and see what the error code is then.
Re: LoadLibrary giving system err 183 while loading Crypto dll
Try a simple test. Create a new test program that just does LoadLibrary("crypto"); See if this works or fails on the machines where your original program failed. If this simple test does fail, try using a different one to test - say advapi32.dll and see what happens.
Code:
int main()
{
HINSTANCE hi = LoadLibrary("crypto");
if (hi == NULL) {
printf("bad ret: %i\n", GetLastError());
} else {
puts("ok");
}
return (0);
}
Code:
myCrypto = LoadLibrary(cryptoPath1); T
What does T do? Does this just test GetLastError() or does it also test myCrypto for NULL? When LoadLibrary works, you can't rely upon GetLastError() being 0. On my test program I get GetLastError() as 126 when LoadLibray succeeds.
Re: LoadLibrary giving system err 183 while loading Crypto dll
Thanks 2kaud, I tried your suggestion with the dwFlags DONT_RESOLVE_DLL_REFERENCES and even that didn’t work. It didn’t give me error 183 this time while loading the crypto.dll. As per my log file, it even got the address for the decrypt function as well, but it didn’t return me the decrypted password in the 'out' variable. Nothing was written beyond this point in my log file.
Code:
int code = (decryptAddress)((char *) pswd, (char *) out, (char*)key);
Sorry, that 'T' in the end was a typo..it must have got added while I was formatting the post, I didn’t realize it. The code statement is:
Code:
myCrypto = LoadLibrary(cryptoPath1);
Meanwhile, I was able to setup Eclipse Galileo on one of the machine where the issue is getting recreated. And surprisingly, in debug mode, the same Java program was able to get the decrypted password from the crypto.dll with just LoadLibrary(). So it means the crypto.dll got loaded from the CryptoWrapper program. The Cryptowrapper log file shows all the variable values and the decrypted password in the ‘out’ variable as well.
So we now have one more data point-in debug mode the Java program loads the crypto dll but fails to do so in runtime mode (jar file).
Thanks..
Re: LoadLibrary giving system err 183 while loading Crypto dll
1)Are you sure you are checking for error from LoadLibrary correctly as you have not posted here any real code just the odd line.
2) On the computers that are giving you the problem, have you tried the simple program from post #12 to verify that on those computers you can actually load crypto.dll?
3) Assuming that 2) does work (and if it doesn't you have a whole new set of problems!) then you need to either produce the simplest program possible that demonstrates the problem that can reproduced and post it here or alternatively start with the simplest program that does work and then incremently enhance it to that required and check after every enhancement that it still works. Once an enhancement does not work then you know the area of code causing the problem.
Re: LoadLibrary giving system err 183 while loading Crypto dll
Quote:
Originally Posted by
RituP
Thanks 2kaud, I tried your suggestion with the dwFlags DONT_RESOLVE_DLL_REFERENCES and even that didn’t work. It didn’t give me error 183 this time while loading the crypto.dll. As per my log file, it even got the address for the decrypt function as well, but it didn’t return me the decrypted password in the 'out' variable.
First, what compiler are you using? Is it Visual Studio?
If so, then you should be debugging the DLL as I stated earlier. It doesn't matter what application is calling LoadLibrary, or even what language is using your DLL. Which brings up the main point -- how do you debug the DLL now? What if your DLL exported function is buggy, as it seems to be now? How do you step into the function to see what is going on?
If you're using Visual Studio, then you can load the DLL project, and then Attach to the process that is calling your DLL function, or you can start the process that will call your DLL from Visual Studio.
Also, you need to make sure that you don't have multiple versions of your DLL floating around on your computer. Having multiple versions is a high source of failures, as the version of the DLL you think is being loaded isn't the right version.
Code:
int code = (decryptAddress)((char *) pswd, (char *) out, (char*)key);
This is not the usual way that a C++ (or C) programmer calls a function. Why are there parentheses around the name of the function? Where does "out" get initialized? Why do you need to do all of the casting to char*? If the function requires a char*, then why aren't you providing the proper argument types so that casting is not necessary? That right there is a red flag that things just do not seem right on the surface.
Regards,
Paul McKenzie