Archive: Plugin problem, CoInitialize() fails..


Plugin problem, CoInitialize() fails..
Hi All,

I'm trying to get a plugin DLL working that uses several
"functions", but it has problems..

The first call to CoInitialize() fails..

hr = CoInitialize(NULL);
if ( hr != S_OK )
{
printf("CoInitialize() Failed\n");
reply = "CoInitialize() Failed";
goto Create_Exit;
}

I first wrote, compiled, and ran them all, by themselves,
and they all worked.

for each I use:

extern "C" void __declspec(dllexport) CreateUser(HWND hwndParent, int string_size,
char *variables, stack_t **stacktop)
{
char *reply = "Failed"; // Default..

g_hwndParent = hwndParent;

EXDLL_INIT();

}

And finish with:

BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
{
g_hInstance = (HINSTANCE)hInst;
return TRUE;
}

It has all the right includes, and the DLL compiles and
links okay.

So is there anything special that I need to add to it
to get it to "work"?

The file is .cpp, because the compiler and linker seem
to be much happier with that than using a .c

None of the functions require any input.

I'm using a Microsoft compiler and linker..


Thanks,

Joe S.


IMHO, it is best to compile an NSIS example plugin first.
For this download the NSIS source! via nightly TARball or cvs.

then take a look in ( \cvs\nsis\NSIS\Contrib\ExDLL\ )

.. and see if you can get that exmaple working.
add some of your code to this plugin and see if all still works... then move on to your own full plugin...


Excellent idea! I'll try it.

Thanks,

Joe S.


No luck.. :-(

Here's a "simple" full example that compiles and links
okay, but will fail..


#include <windows.h>

#define _WIN32_DCOM

#include <Wbemidl.h>
#include "activeds.h"
#include <objbase.h> // Co..
#include <oleauto.h> // SysAllocString()

#include "stdio.h"

#include "exdll.h"



HINSTANCE g_hInstance;

HWND g_hwndParent;

extern "C" void __declspec(dllexport) getComputerName(HWND hwndParent, int string_size,
char *variables, stack_t **stacktop)
{
g_hwndParent=hwndParent;

EXDLL_INIT();

char computerNameBuf[100];

HRESULT hr = S_OK;

IADsWinNTSystemInfo *pNtSys = NULL;

BSTR bstrComputer = NULL;
hr = CoInitialize(NULL);
if ( hr != S_OK )
{
// printf("CoInitialize() Failed\n");
goto GetComputerName_Exit;
}

hr = CoCreateInstance(CLSID_WinNTSystemInfo,
NULL,
CLSCTX_INPROC_SERVER,
IID_IADsWinNTSystemInfo,
(void**)&pNtSys);
if ( hr != S_OK )
{
// printf("CoCreateInstance() Failed\n");
goto GetComputerName_Exit;
}

// printf("CoCreateInstance() OK\n");

hr = pNtSys->get_ComputerName(&bstrComputer);
if ( hr != S_OK )
{
// printf("get_ComputerName() Failed\n");
goto GetComputerName_Exit;
}

// printf("get_ComputerName() OK\n");

sprintf(computerNameBuf, "%s", bstrComputer);
// printf("computerNameBuf: '%S'\n", computerNameBuf);


SysFreeString(bstrComputer);

pushstring(computerNameBuf);


GetComputerName_Exit:

if ( pNtSys != NULL )
{
pNtSys->Release();
}

CoUninitialize();
}



BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
{
g_hInstance = (HINSTANCE)hInst;
return TRUE;
}


NSIS already calls OleInitialize for plug-ins, which internally calls CoInitializeEx. When COM is already initialized for a certain thread, CoInitlaize returns S_FALSE. It's not a real failure, just a notice so you won't call CoUninitialize.


Actually, you should call CoUninitialize for each time you call CoInitialize[Ex]. If you test with the SUCCEEDED macro instead of testing for S_OK everything should be ok


Man! You're right!

I changed all my:

if ( hr != S_OK )

tests to use

if ( ! SUCCEEDED(hr) )

and most everything started to work! lol Doh! :-)

Sometimes I'd rather use what the macro tries to
do internally, directly, testing for S_OK,
but I guess in this case it came back and bit me.. lol :-)

Thanks so much everybody!!

Joe S.