/*
CMikeDll.c

Contains routines primarily of interest
to the DLL: it exports the "DllGetClassObject"
method, the "DllCanUnloadNow" method, and
both DllRegisterServer and DllUnregisterServer

The following line should be added to the "Settings"
dialog so that we actually export the DLL entry points:

/export:DllGetClassObject /export:DllCanUnloadNow /export:DllRegisterServer /export:DllUnregisterServer

Back to the "COM Inproc Server in C" tutorial.

*/
#include <stdio.h> /*for sprintf*/
#include "IMike.h"
#include "CMikeCF.h"
#include "CMike.h"

/*incremented each time another CMike is created, and
// decremented each time one is Release()'d away */
UINT cCMike = 0;

extern struct IClassFactoryVtbl ICFVT;
extern HRESULT _stdcall CMikeCFQueryInterface( IClassFactory *pCF, REFIID iid, void **ppvObject);

STDAPI DllGetClassObject(
REFCLSID rclsid, /*CLSID for the class object*/
REFIID riid, /*Reference to the identifier of the interface that communicates with the class object*/
LPVOID * ppv /* Indirect pointer to the communicating interface */
)
{
static CMikeCF *pMikeCF = NULL;

if( IsEqualCLSID( &CMike_CLSID, rclsid ) )
{
/* we only need a single class factory, so if we've
already created one, use that. Otherwise
build a new factory */
if( NULL == pMikeCF)
{
if( NULL == (pMikeCF = malloc( sizeof( CMikeCF ) ) ) )
{
return E_OUTOFMEMORY;
}
pMikeCF->icf.lpVtbl = &(ICFVT);
pMikeCF->cRef = 0;
}
return CMikeCFQueryInterface( (IClassFactory *)pMikeCF, riid, ppv );
}
return CLASS_E_CLASSNOTAVAILABLE ;
}


STDAPI DllCanUnloadNow()
{
DebugBreak();
return (0==cCMike)?S_OK:S_FALSE;
}


char *szClsidCMike = "{21143C01-DDDF-11d0-AB8F-0000C0148FDB}";


STDAPI DllRegisterServer( void )
{
HKEY hKey;
HRESULT hRes;
char szTemp[90];

sprintf( szTemp, "CLSID\\%s", szClsidCMike );
hRes = RegCreateKey( HKEY_CLASSES_ROOT, szTemp, &hKey);
if( ERROR_SUCCESS != hRes )
{
FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM,
NULL /*Source string*/,
hRes,
0 /*LangID*/,
szTemp,
80, NULL );
MessageBox( NULL, szTemp, "Fatal Error!", MB_OK );
return hRes;
}
hRes = RegSetValueEx( hKey, NULL, /*address of value to set*/ 0, REG_SZ, "CMike Class", strlen( "CMike Class" ) );
if( ERROR_SUCCESS != hRes)
{
FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL /*Source string*/, hRes, 0/*LangID*/, szTemp, 80 , NULL);
MessageBox( NULL, szTemp, "Fatal Error!", MB_OK );
return hRes;
}
RegCloseKey( hKey );

sprintf( szTemp, "CLSID\\%s\\InprocServer32", szClsidCMike );
hRes = RegCreateKey( HKEY_CLASSES_ROOT, szTemp, &hKey);
if( ERROR_SUCCESS != hRes)
{
FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL /*Source string*/, hRes, 0 /*LangID*/, szTemp, 80, NULL );
MessageBox( NULL, szTemp, "Fatal Error!", MB_OK );
return hRes;
}
strcpy( szTemp, "D:\\winnt\\system32\\SCOMS.DLL" );
hRes = RegSetValueEx( hKey, NULL, /*address of value to set*/ 0, REG_SZ, szTemp, strlen( szTemp ) );
if( ERROR_SUCCESS != hRes)
{
FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL /*Source string*/, hRes, 0 /*LangID*/, szTemp, 80, NULL );
MessageBox( NULL, szTemp, "Fatal Error!", MB_OK );
return hRes;
}
RegCloseKey( hKey );
return S_OK;
}

STDAPI DllUnregisterServer( void )
{
HKEY hKey;
HRESULT hRes;
char szTemp[90];

hRes = RegOpenKey( HKEY_CLASSES_ROOT, "CLSID", &hKey);
if( ERROR_SUCCESS != hRes)
{
FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL /*Source string*/, hRes, 0 /*LangID*/, szTemp, 80, NULL );
MessageBox( NULL, szTemp, "Fatal Error!", MB_OK );
return hRes;
}
sprintf( szTemp, "%s\\InprocServer32", szClsidCMike );
hRes = RegDeleteKey( hKey, szTemp);
if( ERROR_SUCCESS != hRes)
{
FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL /*Source string*/, hRes, 0 /*LangID*/, szTemp, 80, NULL );
MessageBox( NULL, szTemp, "Fatal Error!", MB_OK );
return hRes;
}

sprintf( szTemp, "%s", szClsidCMike );
hRes = RegDeleteKey( hKey, szTemp );
if( ERROR_SUCCESS != hRes)
{
FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL /*Source string*/, hRes, 0 /*LangID*/, szTemp, 80, NULL );
MessageBox( NULL, szTemp, "Fatal Error!", MB_OK );
return hRes;
}
RegCloseKey( hKey );
return S_OK;
}

/* ////////// End of CMikeDll.c //////// */