/*++ Copyright (C) 1999-2001 Microsoft Corporation Module Name: Abstract: History: --*/ #include "baseloc.h" static long g_cObj = 0; static long g_cLock = 0; static HMODULE ghModule; static BOOL g_bInit = FALSE; struct CClassInfo { const CLSID* m_pClsid; IClassFactory* m_pFactory; LPSTR m_szName; BOOL m_bFreeThreaded; }; static CClassInfo g_ClassInfo; void ObjectCreated() { InterlockedIncrement(&g_cObj); } void ObjectDestroyed() { InterlockedDecrement(&g_cObj); } void LockServer(BOOL fLock) { if(fLock) InterlockedIncrement(&g_cLock); else InterlockedDecrement(&g_cLock); } void SetClassInfo(REFCLSID rclsid, IClassFactory* pFactory, LPSTR szName, BOOL bFreeThreaded) { pFactory->AddRef(); if(g_ClassInfo.m_pFactory) g_ClassInfo.m_pFactory->Release(); g_ClassInfo.m_pFactory = pFactory; g_ClassInfo.m_pClsid = &rclsid; g_ClassInfo.m_szName = new char[strlen(szName) + 1]; strcpy(g_ClassInfo.m_szName, szName); g_ClassInfo.m_bFreeThreaded = bFreeThreaded; } void SetModuleHandle(HMODULE hModule) { ghModule = hModule; } //*************************************************************************** // // DllGetClassObject // // Purpose: Called by Ole when some client wants a a class factory. Return // one only if it is the sort of class this DLL supports. // //*************************************************************************** STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, PPVOID ppv) { if(!g_bInit) // protect // TBD!!!!! { DllInitialize(); g_bInit = TRUE; } HRESULT hr; if (*g_ClassInfo.m_pClsid!=rclsid) return E_FAIL; IClassFactory* pObj = g_ClassInfo.m_pFactory; if (NULL==pObj) return ResultFromScode(E_OUTOFMEMORY); hr=pObj->QueryInterface(riid, ppv); return hr; } //*************************************************************************** // // DllCanUnloadNow // // Purpose: Called periodically by Ole in order to determine if the // DLL can be freed.// // Return: TRUE if there are no objects in use and the class factory // isn't locked. //*************************************************************************** STDAPI DllCanUnloadNow(void) { SCODE sc; //It is OK to unload if there are no objects or locks on the // class factory. sc=(0L==g_cObj && 0L==g_cLock) ? S_OK : S_FALSE; return sc; } //*************************************************************************** // // DllRegisterServer // // Purpose: Called during initialization or by regsvr32. // // Return: NOERROR if registration successful, error otherwise. //*************************************************************************** STDAPI DllRegisterServer(void) { if(!g_bInit) // protect // TBD!!!!! { DllInitialize(); g_bInit = TRUE; } char szID[128]; WCHAR wcID[128]; char szCLSID[128]; char szModule[MAX_PATH]; HKEY hKey1, hKey2; // Create the path. StringFromGUID2(*g_ClassInfo.m_pClsid, wcID, 128); wcstombs(szID, wcID, 128); lstrcpy(szCLSID, TEXT("CLSID\\")); lstrcat(szCLSID, szID); // Create entries under CLSID RegCreateKey(HKEY_CLASSES_ROOT, szCLSID, &hKey1); RegSetValueEx(hKey1, NULL, 0, REG_SZ, (BYTE *)g_ClassInfo.m_szName, lstrlen(g_ClassInfo.m_szName)+1); RegCreateKey(hKey1,"InprocServer32",&hKey2); GetModuleFileName(ghModule, szModule, MAX_PATH); RegSetValueEx(hKey2, NULL, 0, REG_SZ, (BYTE *)szModule, lstrlen(szModule)+1); const char* szModel; if(g_ClassInfo.m_bFreeThreaded) { szModel = "Both"; } else { szModel = "Apartment"; } RegSetValueEx(hKey2, "ThreadingModel", 0, REG_SZ, (BYTE *)szModel, lstrlen(szModel)+1); CloseHandle(hKey1); CloseHandle(hKey2); return NOERROR; } //*************************************************************************** // // DllUnregisterServer // // Purpose: Called when it is time to remove the registry entries. // // Return: NOERROR if registration successful, error otherwise. //*************************************************************************** STDAPI DllUnregisterServer(void) { if(!g_bInit) // protect // TBD!!!!! { DllInitialize(); g_bInit = TRUE; } char szID[128]; WCHAR wcID[128]; char szCLSID[128]; HKEY hKey; // Create the path using the CLSID StringFromGUID2(*g_ClassInfo.m_pClsid, wcID, 128); wcstombs(szID, wcID, 128); lstrcpy(szCLSID, TEXT("CLSID\\")); lstrcat(szCLSID, szID); // First delete the InProcServer subkey. DWORD dwRet = RegOpenKey(HKEY_CLASSES_ROOT, szCLSID, &hKey); if(dwRet == NO_ERROR) { RegDeleteKey(hKey, "InProcServer32"); CloseHandle(hKey); } dwRet = RegOpenKey(HKEY_CLASSES_ROOT, "CLSID", &hKey); if(dwRet == NO_ERROR) { RegDeleteKey(hKey,szID); CloseHandle(hKey); } return NOERROR; }