Need help with COM dll registration at runtime
Hello All,
I have only recently started getting my feet wet with COM and have run
into a couple of issues.
I'd appreciate any help that you provide. My reference will be one
article found at:
http://www.codeproject.com/com/com_in_c1.asp
Now, I downloaded the zip, compiled and ran it and everything went
well. Next, I tried to get
smart: I thought of putting the CLSID in a file (instead of having it
in the header file for the plug-in).
Here's where you'd find some background a little helpful. Atleast, so
I hope.
The idea is my clients would give me a set of such COM dlls, each with
its own CLSID, and
perhaps some other meta-information in a text file (XML, if I want to
be whacky!). I intend to parse
this configuration file (dlls would be placed in a predestined folder)
and load the dlls and ask them
do stuff from time to time.
So I changed the main enough to read the CLSID as a string from the
file, converted it to a CLSID
using a custon function (I do know about CLSIDFromString() but somehow
just couldn't get past
converting char [] to OLESTR or some such stupid problem) and passed
it to CoGetClassObject().
Note, I call a function to do register this dll, and uptio this,
things work fine. Actually, the CustomRegister() function
is also taken from the codeproject tutorial. However,
CoGetClassObject() fails saying:
"ClassFactory cannot supply requested class".
I'll put up some code as well:
------------
<-------------------------------------------------------------------------------------------------
<-------------------------------------
demoapp.cpp
--------------------
#include <windows.h>
#include <objbase.h>
#include <stdio.h>
#include "iptplugin.h"
#include "reg.h"
#include "clsid.h"
// Copyright: Wine sources...
void CLSIDFromstring(LPTSTR s, LPCLSID id)
{
int i;
BYTE table[256];
/* quick lookup table */
memset(table, 0, 256);
for (i = 0; i < 10; i++) {
table['0' + i] = i;
}
for (i = 0; i < 6; i++) {
table['A' + i] = i+10;
table['a' + i] = i+10;
}
/* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
id->Data1 = (table[s[1]] << 28 | table[s[2]] << 24 | table[s[3]]
<< 20 | table[s[4]] << 16 |
table[s[5]] << 12 | table[s[6]] << 8 | table[s[7]] <<
4 | table[s[8]]);
id->Data2 = table[s[10]] << 12 | table[s[11]] << 8 | table[s[12]]
<< 4 | table[s[13]];
id->Data3 = table[s[15]] << 12 | table[s[16]] << 8 | table[s[17]]
<< 4 | table[s[18]];
/* these are just sequential bytes */
id->Data4[0] = table[s[20]] << 4 | table[s[21]];
id->Data4[1] = table[s[22]] << 4 | table[s[23]];
id->Data4[2] = table[s[25]] << 4 | table[s[26]];
id->Data4[3] = table[s[27]] << 4 | table[s[28]];
id->Data4[4] = table[s[29]] << 4 | table[s[30]];
id->Data4[5] = table[s[31]] << 4 | table[s[32]];
id->Data4[6] = table[s[33]] << 4 | table[s[34]];
id->Data4[7] = table[s[35]] << 4 | table[s[36]];
}
void GetCLSIDFromFile(const char *path, char *out)
{
if (out) {
//*out = 0;
FILE *fp = fopen(path, "r");
if (fp) {
fscanf(fp, "CLSID=%s%*", out);
fclose(fp);
}
}
}
int main(int argc, char **argv)
{
IPTPlugin *exampleObj;
IClassFactory *classFactory;
HRESULT hr;
char guidBuf[ 80 ];
GetCLSIDFromFile("C:\\users\\cplugins\\dlls\\plugin-conf.txt",
guidBuf);
printf("CLSID (from config file) = %s\n", guidBuf);
CLSID pluginCLSID = CLSID_NULL;
//CLSIDFromstring(guidBuf, pluginCLSID);
CLSIDFromstring(guidBuf, &pluginCLSID);
stringFromCLSID(guidBuf, pluginCLSID);
printf("Check: CLSID (from config file) = %s\n", guidBuf);
REFCLSID ri = pluginCLSID;
CustomRegister(ri);
// We must initialize OLE before we do anything with COM objects.
NOTE:
// some COM components, such as the IE browser engine, require that
you
// use OleInitialize() instead. But our COM component doesn't require
this
if (!CoInitialize(0))
{
// Get IPTPlugin.DLL's IClassFactory
if ((hr = CoGetClassObject(ri
/*ri*/,
CLSCTX_INPROC_SERVER,
0,
IID_IClassFactory,
(LPVOID *)&classFactory))) {
MessageBox(0, "Can't get IClassFactory", "CoGetClassObject
error", MB_OK|MB_ICONEXCLAMATION);
CustomUnregister();
}
else
{
// Create an IPTPlugin object
if ((hr = classFactory->CreateInstance(0, IID_IPTPlugin, (LPVOID
*)&exampleObj)))
{
classFactory->Release();
MessageBox(0, "Can't create IPTPlugin object", "CreateInstance
error", MB_OK|MB_ICONEXCLAMATION);
}
else
{
//char buffer[80];
// Release the IClassFactory. We don't need it now that we have
the one
// IPTPlugin we want
classFactory->Release();
// Call SetString to set the text "Hello world!"
exampleObj->Initialize();
exampleObj->Translate();
exampleObj->Cleanup();
// Release the IPTPlugin now that we're done with it
exampleObj->Release();
}
}
// When finally done with OLE, free it
CoUninitialize();
}
else
MessageBox(0, "Can't initialize COM", "CoInitialize error", MB_OK|
MB_ICONEXCLAMATION);
CustomUnregister();
return(0);
}
-----------------------------------
------------
<-------------------------------------------------------------------------------------------------
<-------------------------------------