joe131
6th December 2006 13:49 UTC
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.
onad
6th December 2006 16:19 UTC
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...
joe131
6th December 2006 17:44 UTC
Excellent idea! I'll try it.
Thanks,
Joe S.
joe131
6th December 2006 19:20 UTC
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;
}
kichik
7th December 2006 18:56 UTC
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.
Anders
7th December 2006 21:29 UTC
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
joe131
8th December 2006 12:27 UTC
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.