Archive: Plugin not accepted after recompilation


Plugin not accepted after recompilation
Hello,

I am in the situation of taking ownership of software not developed by myself, and make the whole thing buildable through scripts, both on 32 bit and 64 bit platforms.

Among the files part of the build is a NSIS plugin dll whose an existing 32 bits version works fine (makeNSIS builds the nsi script without problem, and the generated installer works fine).
When I recompile the plugin dll however, makeNSIS complains about the first call to the plugin dll function, saying it is an "Invalid command". Whereas this is usually due to a wrong plugin directory, this is definitively because of the dll itself in my case, as replacing the dll by the old one make the thing work.
So my question is: what could lead makeNSIS to say "invalid command" when the dll is found? Some compilation options? a DLL format issue?
Checking with previous versions of the sources, I cannot see differences in them. The only differences are that I'm using VC++ 2010 to compile (instead of 2008) and that I'm compiling on a Win7 64 bits platform (but the problem arises both in compiling a Win32 or x64 configuration).

A last clue : when looking at the exports (using dumpbin) on the existing dll that is accepted, i can see:

00000000 characteristics
4BC6D78A time date stamp Thu Apr 15 11:08:26 2010
0.00 version
1 ordinal base
4 number of functions
4 number of names

ordinal hint RVA name

1 0 0000F390 BrowserRunning
2 1 0000F530 CheckSerial
3 2 0000F1E0 KillProc
4 3 0000F3F0 SHA1

Summary

3000 .data
3000 .rdata
2000 .reloc
1000 .rsrc
F000 .text
Whereas when looking at the newly compiled version, I can see a slight difference in the exported names ("name = _name", what does it mean?):
00000000 characteristics
4CC99565 time date stamp Thu Oct 28 17:23:17 2010
0.00 version
1 ordinal base
4 number of functions
4 number of names

ordinal hint RVA name

1 0 00001170 BrowserRunning = _BrowserRunning
2 1 00001240 CheckSerial = _CheckSerial
3 2 00001A00 KillProc = _KillProc
4 3 00001000 SHA1 = _SHA1

Summary

3000 .data
4000 .rdata
2000 .reloc
1000 .rsrc
E000 .text
Thank you for your help.

In case you don't have any clue, is there any NSIS debug option that would help me to understand why the recompiled DLL is considered invalid whereas the old one is not?
Thanks


It looks that the problem occurs only when running on Windows (7) 64 bits, not on Windows (7) 32 bits.
Any idea? Is it a NSIS bug?


NSIS just does LoadLibrary and GetProcAddress. If it fails, it either can't load the dll, or find the export.

You should probably start by fixing the exports, are you using a .def file or __declspec ?

Maybe post your function declaration so we can have a look...


Thanks for replying Anders.

First of all a correction: the problem only occurs when trying to load a DLL/plugin compiled for a 64-bits platform (NSIS doesn't complain packaging the same DLL compiled for 32 bits, even when running makeNSIS on 64 bits).

The DLL uses __declspec. Here is an example declaration in the .c file:

void __declspec(dllexport) SHA1(HWND hwndParent, int string_size,
char *variables, stack_t **stacktop,
extra_parameters *extra) {

which is loaded fine when compiled for 32 bits, when running makeNSIS either or 32 bits or (almost paradoxally as the 32-bits dll won't be able to be loaded) on 64 bits.

So right now I'm thinking about a simple explanation of the problem : how can 32-bits compiled NSIS could load a 64 bits DLL ? Isn't it normal that it fails to do so (even if the message should be more explicit that "Invalid command", like "cannot load plugin Xxx because it is 64 bits and you're using a 32 bits NSIS").
For example a 64 bits java virtual machine cannot load 32 bits dlls using the Java Native Interface. The DLLs have to be 64 bits.

Or maybe I'm missing something. If not, my next question is: is there a 64-bits compiled NSIS, and where can I find it?

Thank you for your help.


For the record, the problem can be workarounded by compiling all plugins for 32 bits and running NSIS with them on a 64 bits platform.

So why would I need to run a 64 bits compatible version a NSIS (and associated plugins) then, would you ask? Because I expected that such a version would allow to properly kill a 64-bits running process, which I need to. But it looks my expectation was wrong, as stated in http://forums.winamp.com/showthread.php?t=318977