Broken COM object registration

3

This is a continuation of Register implementation of a com interface ; only now I've got actual code that needs debugging.

I've got two COM objects, one that implements IAudioSessionEvents and one that implements IClassFactory and produces the first object.

The following code registers those objects (in accordance with my understanding of COM registration):

BOOL RegisterClassManually(WCHAR* szGuid, WCHAR* szDllPath)
{
WCHAR szKeyName[1024];
wsprintf(szKeyName, TEXT("Software\\Classes\\CLSID\\%s"), szGuid);

if(!RegisterKeyValue(HKEY_CURRENT_USER, szKeyName, NULL, TEXT(DESCRIPTION_CONST))) return false;

wsprintf(szKeyName, TEXT("Software\\Classes\\CLSID\\%s\\InprocServer32"), szGuid);

if(!RegisterKeyValue(HKEY_CURRENT_USER, szKeyName, NULL, szDllPath)) return false;
if(!RegisterKeyValue(HKEY_CURRENT_USER, szKeyName, TEXT("ThreadingModel"), TEXT("Apartment"))) return false;

return true;
}

STDAPI DllRegisterServer()
{
//Write data to HKEY_CURRENT_USER\\Software\\Classes\\CLSID\\{GUID}
// Also ""\\InProcServer32
// Also "".ThreadingModel = "Apartment"

WCHAR* szGuid;
WCHAR szDllPath[512];
StringFromCLSID(CLSID_AudioEventsFactory, &szGuid);

if(g_dllModule == NULL) return SELFREG_E_CLASS;

GetModuleFileName(g_dllModule, szDllPath, 512);

if(!RegisterClassManually(szGuid, szDllPath)) return SELFREG_E_CLASS;

StringFromCLSID(CLSID_AudioEvents, &szGuid);

if(!RegisterClassManually(szGuid, szDllPath)) return SELFREG_E_CLASS;

return S_OK;
}

I've omitted RegisterKeyValue(...), its simple registry code that I've confirmed works as intended.

This code attempts to use these COM objects:

IAudioSessionEvents* listener = NULL;

IClassFactory* factory = NULL;

//Fails on this call
hr = CoGetClassObject(CLSID_AudioEventsFactory, CLSCTX_ALL, NULL, __uuidof(IClassFactory), (void**)&factory);

if(hr != S_OK)
{
    ... Report Error ...
}

hr = factory->CreateInstance(NULL, __uuidof(IAudioSessionEvents), (void**)&listener);

The call to CoGetClassObject(...) returns hr = 0x80040111 (ClassFactory cannot supply requested class).

Implementation of DllGetClassObject (per 1800 INFORMATION pointing out the ommision):

STDAPI DllGetClassObject(const CLSID& clsid,
                     const IID& iid,
                     void** ppv)
{

if (clsid == __uuidof(IClassFactory))
{
    AudioEventsFactory *pFact = new AudioEventsFactory;
    if (pFact == NULL)
        return E_OUTOFMEMORY;
    else
    {
        return pFact->QueryInterface(iid , ppv);
    }
}

return CLASS_E_CLASSNOTAVAILABLE;
}

What am I doing wrong here? I suspect its in the COM registration, but can't find anything that actually lays out exactly what is required in the registry. I've sort of reverse-engineered what I store at the moment.

c++
windows
com
asked on Stack Overflow Apr 4, 2009 by Kevin Montrose • edited May 23, 2017 by Community

1 Answer

2

This article COM in plain C has a pretty good description how you have to implement a COM dll without using ATL. As pointed by 1800 DllGetClassObject will be called to create a COM object. Also The COM Programmer's Cookbook is nice reference about COM.

answered on Stack Overflow Apr 4, 2009 by Ismael

User contributions licensed under CC BY-SA 3.0