//*************************************************************************** // // Copyright (c) 1998-2000 Microsoft Corporation // // MAINDLL.CPP // // alanbos 13-Feb-98 Created. // // Contains DLL entry points. // //*************************************************************************** #include "precomp.h" #include "objsink.h" #include "initguid.h" // SWbemLocator registry strings #define WBEMS_LOC_DESCRIPTION _T("WBEM Scripting Locator") #define WBEMS_LOC_PROGID _T("WbemScripting.SWbemLocator") #define WBEMS_LOC_PROGIDVER _T("WbemScripting.SWbemLocator.1") #define WBEMS_LOC_VERSION _T("1.0") #define WBEMS_LOC_VERDESC _T("WBEM Scripting Locator 1.0") // SWbemNamedValueSet registry strings #define WBEMS_CON_DESCRIPTION _T("WBEM Scripting Named Value Collection") #define WBEMS_CON_PROGID _T("WbemScripting.SWbemNamedValueSet") #define WBEMS_CON_PROGIDVER _T("WbemScripting.SWbemNamedValueSet.1") #define WBEMS_CON_VERSION _T("1.0") #define WBEMS_CON_VERDESC _T("WBEM Scripting Named Value Collection 1.0") // SWbemObjectPath registry settings #define WBEMS_OBP_DESCRIPTION _T("WBEM Scripting Object Path") #define WBEMS_OBP_PROGID _T("WbemScripting.SWbemObjectPath") #define WBEMS_OBP_PROGIDVER _T("WbemScripting.SWbemObjectPath.1") #define WBEMS_OBP_VERSION _T("1.0") #define WBEMS_OBP_VERDESC _T("WBEM Scripting Object Path 1.0") // SWbemParseDN registry settings #define WBEMS_PDN_DESCRIPTION _T("Wbem Scripting Object Path") #define WBEMS_PDN_PROGID _T("WINMGMTS") #define WBEMS_PDN_PROGIDVER _T("WINMGMTS.1") #define WBEMS_PDN_VERSION _T("1.0") #define WBEMS_PDN_VERDESC _T("Wbem Object Path 1.0") // SWbemLastError registry settings #define WBEMS_LER_DESCRIPTION _T("Wbem Scripting Last Error") #define WBEMS_LER_PROGID _T("WbemScripting.SWbemLastError") #define WBEMS_LER_PROGIDVER _T("WbemScripting.SWbemLastError.1") #define WBEMS_LER_VERSION _T("1.0") #define WBEMS_LER_VERDESC _T("Wbem Last Error 1.0") // SWbemSink registry strings #define WBEMS_SINK_DESCRIPTION _T("WBEM Scripting Sink") #define WBEMS_SINK_PROGID _T("WbemScripting.SWbemSink") #define WBEMS_SINK_PROGIDVER _T("WbemScripting.SWbemSink.1") #define WBEMS_SINK_VERSION _T("1.0") #define WBEMS_SINK_VERDESC _T("WBEM Scripting Sink 1.0") // SWbemDateTime registry settings #define WBEMS_DTIME_DESCRIPTION _T("WBEM Scripting DateTime") #define WBEMS_DTIME_PROGID _T("WbemScripting.SWbemDateTime") #define WBEMS_DTIME_PROGIDVER _T("WbemScripting.SWbemDateTime.1") #define WBEMS_DTIME_VERSION _T("1.0") #define WBEMS_DTIME_VERDESC _T("WBEM Scripting DateTime 1.0") // SWbemRefresher registry settings #define WBEMS_REF_DESCRIPTION _T("WBEM Scripting Refresher") #define WBEMS_REF_PROGID _T("WbemScripting.SWbemRefresher") #define WBEMS_REF_PROGIDVER _T("WbemScripting.SWbemRefresher.1") #define WBEMS_REF_VERSION _T("1.0") #define WBEMS_REF_VERDESC _T("WBEM Scripting Refresher 1.0") // Standard registry key/value names #define WBEMS_RK_SCC _T("SOFTWARE\\CLASSES\\CLSID\\") #define WBEMS_RK_SC _T("SOFTWARE\\CLASSES\\") #define WBEMS_RK_THRDMODEL _T("ThreadingModel") #define WBEMS_RV_APARTMENT _T("Apartment") #define WBEMS_RK_PROGID _T("ProgID") #define WBEMS_RK_VERPROGID _T("VersionIndependentProgID") #define WBEMS_RK_TYPELIB _T("TypeLib") #define WBEMS_RK_VERSION _T("Version") #define WBEMS_RK_INPROC32 _T("InProcServer32") #define WBEMS_RK_CLSID _T("CLSID") #define WBEMS_RK_CURVER _T("CurVer") #define WBEMS_RK_PROGRAMMABLE _T("Programmable") // Other values #define WBEMS_RK_WBEM _T("Software\\Microsoft\\Wbem") #define WBEMS_SK_SCRIPTING _T("Scripting") #define GUIDSIZE 128 // Count number of objects and number of locks. long g_cObj = 0 ; ULONG g_cLock = 0 ; HMODULE ghModule = NULL; // Used for error object storage CWbemErrorCache *g_pErrorCache = NULL; /* * This object is used to protect the global pointer: * * - g_pErrorCache * * Note that it is the pointer variables that are protected by * this CS, rather than the addressed objects. */ CRITICAL_SECTION g_csErrorCache; // Used to protect security calls CRITICAL_SECTION g_csSecurity; // CLSID for our implementation of IParseDisplayName // {172BDDF8-CEEA-11d1-8B05-00600806D9B6} DEFINE_GUID(CLSID_SWbemParseDN, 0x172bddf8, 0xceea, 0x11d1, 0x8b, 0x5, 0x0, 0x60, 0x8, 0x6, 0xd9, 0xb6); // Forward defs static void UnregisterTypeLibrary (unsigned short wVerMajor, unsigned short wVerMinor); //*************************************************************************** // // BOOL WINAPI DllMain // // DESCRIPTION: // // Entry point for DLL. Good place for initialization. // // PARAMETERS: // // hInstance instance handle // ulReason why we are being called // pvReserved reserved // // RETURN VALUE: // // TRUE if OK. // //*************************************************************************** BOOL WINAPI DllMain ( IN HINSTANCE hInstance, IN ULONG ulReason, LPVOID pvReserved ) { _RD(static char *me = "DllMain";) switch (ulReason) { case DLL_PROCESS_DETACH: { _RPrint(me, "DLL_PROCESS_DETACH", 0, ""); DeleteCriticalSection (&g_csErrorCache); DeleteCriticalSection (&g_csSecurity); CSWbemLocator::Shutdown (); CIWbemObjectSinkMethodCache::TidyUp (); } return TRUE; case DLL_THREAD_DETACH: { _RPrint(me, "DLL_THREAD_DETACH", 0, ""); } return TRUE; case DLL_PROCESS_ATTACH: { _RPrint(me, "DLL_PROCESS_DETACH", 0, ""); if(ghModule == NULL) ghModule = hInstance; InitializeCriticalSection (&g_csErrorCache); InitializeCriticalSection (&g_csSecurity); CIWbemObjectSinkMethodCache::Initialize (); } return TRUE; case DLL_THREAD_ATTACH: { _RPrint(me, "DLL_THREAD_ATTACH", 0, ""); } return TRUE; } return TRUE; } //*************************************************************************** // // STDAPI DllGetClassObject // // DESCRIPTION: // // Called when Ole wants a class factory. Return one only if it is the sort // of class this DLL supports. // // PARAMETERS: // // rclsid CLSID of the object that is desired. // riid ID of the desired interface. // ppv Set to the class factory. // // RETURN VALUE: // // S_OK all is well // E_FAILED not something we support // //*************************************************************************** STDAPI DllGetClassObject( IN REFCLSID rclsid, IN REFIID riid, OUT LPVOID *ppv ) { HRESULT hr; CSWbemFactory *pObj = NULL; if (CLSID_SWbemLocator == rclsid) pObj=new CSWbemFactory(CSWbemFactory::LOCATOR); else if (CLSID_SWbemSink == rclsid) pObj=new CSWbemFactory(CSWbemFactory::SINK); else if (CLSID_SWbemNamedValueSet == rclsid) pObj=new CSWbemFactory(CSWbemFactory::CONTEXT); else if (CLSID_SWbemObjectPath == rclsid) pObj=new CSWbemFactory(CSWbemFactory::OBJECTPATH); else if (CLSID_SWbemParseDN == rclsid) pObj = new CSWbemFactory(CSWbemFactory::PARSEDN); else if (CLSID_SWbemLastError == rclsid) pObj = new CSWbemFactory(CSWbemFactory::LASTERROR); else if (CLSID_SWbemDateTime == rclsid) pObj = new CSWbemFactory(CSWbemFactory::DATETIME); else if (CLSID_SWbemRefresher == rclsid) pObj = new CSWbemFactory(CSWbemFactory::REFRESHER); if(NULL == pObj) return E_FAIL; hr=pObj->QueryInterface(riid, ppv); if (FAILED(hr)) delete pObj; return hr ; } //*************************************************************************** // // STDAPI DllCanUnloadNow // // DESCRIPTION: // // Answers if the DLL can be freed, that is, if there are no // references to anything this DLL provides. // // RETURN VALUE: // // S_OK if it is OK to unload // S_FALSE if still in use // //*************************************************************************** STDAPI DllCanUnloadNow () { // It is OK to unload if there are no objects or locks on the // class factory. HRESULT status = S_FALSE; _RD(static char *me = "DllCanUnloadNow";) _RPrint(me, "Called", 0, ""); if (0L==g_cObj && 0L==g_cLock) { _RPrint(me, "Unloading", 0, ""); /* * Release the error object on this thread, if any */ status = S_OK; EnterCriticalSection (&g_csErrorCache); if (g_pErrorCache) { delete g_pErrorCache; g_pErrorCache = NULL; } LeaveCriticalSection (&g_csErrorCache); CSWbemSecurity::Uninitialize (); } return status; } //*************************************************************************** // // STDAPI RegisterProgID // STDAPI RegisterCoClass // STDAPI RegisterTypeLibrary // STDAPI RegisterDefaultNamespace // // DESCRIPTION: // // Helpers for the tiresome business of registry setup // // RETURN VALUE: // // ERROR alas // NOERROR rejoice // //*************************************************************************** STDAPI RegisterProgID (LPCTSTR wcID, LPCTSTR desc, LPCTSTR progid, LPCTSTR descVer, LPCTSTR progidVer) { HKEY hKey1 = NULL; HKEY hKey2 = NULL; TCHAR *szProgID = new TCHAR [_tcslen (WBEMS_RK_SC) + _tcslen (progid) + 1]; if (!szProgID) return E_OUTOFMEMORY; TCHAR *szProgIDVer = new TCHAR [_tcslen (WBEMS_RK_SC) + _tcslen (progidVer) + 1]; if (!szProgIDVer) { delete [] szProgID; return E_OUTOFMEMORY; } _tcscpy (szProgID, WBEMS_RK_SC); _tcscat (szProgID, progid); _tcscpy (szProgIDVer, WBEMS_RK_SC); _tcscat (szProgIDVer, progidVer); // Add the ProgID (Version independent) if(ERROR_SUCCESS == RegCreateKey(HKEY_LOCAL_MACHINE, szProgID, &hKey1)) { RegSetValueEx(hKey1, NULL, 0, REG_SZ, (BYTE *)desc, (_tcslen(desc)+1) * sizeof(TCHAR)); if(ERROR_SUCCESS == RegCreateKey(hKey1,WBEMS_RK_CLSID, &hKey2)) { RegSetValueEx(hKey2, NULL, 0, REG_SZ, (BYTE *)wcID, (_tcslen(wcID)+1) * sizeof(TCHAR)); RegCloseKey(hKey2); hKey2 = NULL; } if(ERROR_SUCCESS == RegCreateKey(hKey1, WBEMS_RK_CURVER, &hKey2)) { RegSetValueEx(hKey2, NULL, 0, REG_SZ, (BYTE *)progidVer, (_tcslen(progidVer)+1) * sizeof(TCHAR)); RegCloseKey(hKey2); hKey2 = NULL; } RegCloseKey(hKey1); } // Add the ProgID (Versioned) if(ERROR_SUCCESS == RegCreateKey(HKEY_LOCAL_MACHINE, szProgIDVer, &hKey1)) { RegSetValueEx(hKey1, NULL, 0, REG_SZ, (BYTE *)descVer, (_tcslen(descVer)+1) * sizeof(TCHAR)); if(ERROR_SUCCESS == RegCreateKey(hKey1, WBEMS_RK_CLSID, &hKey2)) { RegSetValueEx(hKey2, NULL, 0, REG_SZ, (BYTE *)wcID, (_tcslen(wcID)+1) * sizeof(TCHAR)); RegCloseKey(hKey2); hKey2 = NULL; } RegCloseKey(hKey1); } delete [] szProgID; delete [] szProgIDVer; return NOERROR; } STDAPI RegisterCoClass (REFGUID clsid, LPCTSTR desc, LPCTSTR progid, LPCTSTR progidVer, LPCTSTR ver, LPCTSTR descVer) { HRESULT hr = S_OK; OLECHAR wcID[GUIDSIZE]; OLECHAR tlID[GUIDSIZE]; TCHAR nwcID[GUIDSIZE]; TCHAR ntlID[GUIDSIZE]; TCHAR szModule[MAX_PATH]; HKEY hKey1 = NULL, hKey2 = NULL; TCHAR *szCLSID = new TCHAR [_tcslen (WBEMS_RK_SCC) + GUIDSIZE + 1]; if (!szCLSID) return E_OUTOFMEMORY; // Create the path. if(0 ==StringFromGUID2(clsid, wcID, GUIDSIZE)) { delete [] szCLSID; return ERROR; } _tcscpy (szCLSID, WBEMS_RK_SCC); #ifndef UNICODE wcstombs(nwcID, wcID, GUIDSIZE); #else _tcscpy (nwcID, wcID); #endif _tcscat (szCLSID, nwcID); if (0 == StringFromGUID2 (LIBID_WbemScripting, tlID, GUIDSIZE)) { delete [] szCLSID; return ERROR; } #ifndef UNICODE wcstombs (ntlID, tlID, GUIDSIZE); #else _tcscpy (ntlID, tlID); #endif if(0 == GetModuleFileName(ghModule, szModule, MAX_PATH)) { delete [] szCLSID; return ERROR; } // Create entries under CLSID if(ERROR_SUCCESS == RegCreateKey(HKEY_LOCAL_MACHINE, szCLSID, &hKey1)) { // Description (on main key) RegSetValueEx(hKey1, NULL, 0, REG_SZ, (BYTE *)desc, (_tcslen(desc)+1) * sizeof(TCHAR)); // Register as inproc server if (ERROR_SUCCESS == RegCreateKey(hKey1, WBEMS_RK_INPROC32 ,&hKey2)) { RegSetValueEx(hKey2, NULL, 0, REG_SZ, (BYTE *)szModule, (_tcslen(szModule)+1) * sizeof(TCHAR)); RegSetValueEx(hKey2, WBEMS_RK_THRDMODEL, 0, REG_SZ, (BYTE *)WBEMS_RV_APARTMENT, (_tcslen(WBEMS_RV_APARTMENT)+1) * sizeof(TCHAR)); RegCloseKey(hKey2); } // Give a link to the type library (useful for statement completion in scripting tools) if (ERROR_SUCCESS == RegCreateKey(hKey1, WBEMS_RK_TYPELIB, &hKey2)) { RegSetValueEx(hKey2, NULL, 0, REG_SZ, (BYTE *)ntlID, (_tcslen(ntlID)+1) * sizeof(TCHAR)); RegCloseKey(hKey2); } // Register the ProgID if (ERROR_SUCCESS == RegCreateKey(hKey1, WBEMS_RK_PROGID ,&hKey2)) { RegSetValueEx(hKey2, NULL, 0, REG_SZ, (BYTE *)progidVer, (_tcslen(progidVer)+1) * sizeof(TCHAR)); RegCloseKey(hKey2); } // Register the version-independent ProgID if (ERROR_SUCCESS == RegCreateKey(hKey1, WBEMS_RK_VERPROGID, &hKey2)) { RegSetValueEx(hKey2, NULL, 0, REG_SZ, (BYTE *)progid, (_tcslen(progid)+1) * sizeof(TCHAR)); RegCloseKey(hKey2); } // Register the version if (ERROR_SUCCESS == RegCreateKey(hKey1, WBEMS_RK_VERSION, &hKey2)) { RegSetValueEx(hKey2, NULL, 0, REG_SZ, (BYTE *)ver, (_tcslen(ver)+1) * sizeof(TCHAR)); RegCloseKey(hKey2); } // Register this control as programmable if (ERROR_SUCCESS == RegCreateKey(hKey1, WBEMS_RK_PROGRAMMABLE ,&hKey2)) { RegCloseKey(hKey2); } RegCloseKey(hKey1); } else { delete [] szCLSID; return ERROR; } delete [] szCLSID; return RegisterProgID (nwcID, desc, progid, descVer, progidVer); } STDAPI RegisterTypeLibrary () { // AUTOMATION. register type library TCHAR cPath[MAX_PATH+1]; cPath[MAX_PATH] = 0; if(GetModuleFileName(ghModule,cPath,MAX_PATH)) { // Replace final 3 characters "DLL" by "TLB" TCHAR *pExt = _tcsrchr (cPath, _T('.')); if (pExt && (0 == _tcsicmp (pExt, _T(".DLL")))) { _tcscpy (pExt + 1, _T("TLB")); OLECHAR wPath [MAX_PATH]; #ifndef UNICODE mbstowcs (wPath, cPath, MAX_PATH-1); #else _tcsncpy (wPath, cPath, MAX_PATH-1); #endif ITypeLib FAR* ptlib = NULL; SCODE sc = LoadTypeLib(wPath, &ptlib); if(sc == 0 && ptlib) { sc = RegisterTypeLib(ptlib,wPath,NULL); ptlib->Release(); // Unregister the previous library version(s) UnregisterTypeLibrary (1, 1); UnregisterTypeLibrary (1, 0); } } } return NOERROR; } STDAPI RegisterScriptSettings () { HKEY hKey; if(ERROR_SUCCESS != RegCreateKey(HKEY_LOCAL_MACHINE, WBEMS_RK_SCRIPTING, &hKey)) return ERROR; // Need to know what O/S we are to set up the right registry keys OSVERSIONINFO osVersionInfo; osVersionInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); GetVersionEx (&osVersionInfo); bool bIsNT = (VER_PLATFORM_WIN32_NT == osVersionInfo.dwPlatformId); DWORD dwNTMajorVersion = osVersionInfo.dwMajorVersion; // Default namespace value - exists on all platforms RegSetValueEx(hKey, WBEMS_RV_DEFNS, 0, REG_SZ, (BYTE *)WBEMS_DEFNS, (_tcslen(WBEMS_DEFNS)+1) * sizeof(TCHAR)); // Enable for ASP - on NT 4.0 or less only if (bIsNT && (dwNTMajorVersion <= 4)) { DWORD defaultEnableForAsp = 0; RegSetValueEx(hKey, WBEMS_RV_ENABLEFORASP, 0, REG_DWORD, (BYTE *)&defaultEnableForAsp, sizeof (defaultEnableForAsp)); } // Default impersonation level - NT only if (bIsNT) { DWORD defaultImpersonationLevel = (DWORD) wbemImpersonationLevelImpersonate; RegSetValueEx(hKey, WBEMS_RV_DEFAULTIMPLEVEL, 0, REG_DWORD, (BYTE *)&defaultImpersonationLevel, sizeof (defaultImpersonationLevel)); } RegCloseKey(hKey); return NOERROR; } //*************************************************************************** // // DllRegisterServer // // Purpose: Called during setup or by regsvr32. // // Return: NOERROR if registration successful, error otherwise. //*************************************************************************** STDAPI DllRegisterServer(void) { HRESULT hr; if ( (NOERROR == (hr = RegisterScriptSettings ())) && (NOERROR == (hr = RegisterCoClass (CLSID_SWbemLocator, WBEMS_LOC_DESCRIPTION, WBEMS_LOC_PROGID, WBEMS_LOC_PROGIDVER, WBEMS_LOC_VERSION, WBEMS_LOC_VERDESC))) && (NOERROR == (hr = RegisterCoClass (CLSID_SWbemSink, WBEMS_SINK_DESCRIPTION, WBEMS_SINK_PROGID, WBEMS_SINK_PROGIDVER, WBEMS_SINK_VERSION, WBEMS_SINK_VERDESC))) && (NOERROR == (hr = RegisterCoClass (CLSID_SWbemNamedValueSet, WBEMS_CON_DESCRIPTION, WBEMS_CON_PROGID, WBEMS_CON_PROGIDVER, WBEMS_CON_VERSION, WBEMS_CON_VERDESC))) && (NOERROR == (hr = RegisterCoClass (CLSID_SWbemParseDN, WBEMS_PDN_DESCRIPTION, WBEMS_PDN_PROGID, WBEMS_PDN_PROGIDVER, WBEMS_PDN_VERSION, WBEMS_PDN_VERDESC))) && (NOERROR == (hr = RegisterCoClass (CLSID_SWbemObjectPath, WBEMS_OBP_DESCRIPTION, WBEMS_OBP_PROGID, WBEMS_OBP_PROGIDVER, WBEMS_OBP_VERSION, WBEMS_OBP_VERDESC))) && (NOERROR == (hr = RegisterCoClass (CLSID_SWbemLastError, WBEMS_LER_DESCRIPTION, WBEMS_LER_PROGID, WBEMS_LER_PROGIDVER, WBEMS_LER_VERSION, WBEMS_LER_VERDESC))) && (NOERROR == (hr = RegisterCoClass (CLSID_SWbemDateTime, WBEMS_DTIME_DESCRIPTION, WBEMS_DTIME_PROGID, WBEMS_DTIME_PROGIDVER, WBEMS_DTIME_VERSION, WBEMS_DTIME_VERDESC))) && (NOERROR == (hr = RegisterCoClass (CLSID_SWbemRefresher, WBEMS_REF_DESCRIPTION, WBEMS_REF_PROGID, WBEMS_REF_PROGIDVER, WBEMS_REF_VERSION, WBEMS_REF_VERDESC))) ) hr = RegisterTypeLibrary (); return hr; } //*************************************************************************** // // STDAPI UnregisterProgID // STDAPI UnregisterCoClass // STDAPI UnregisterTypeLibrary // STDAPI UnregisterDefaultNamespace // // DESCRIPTION: // // Helpers for the tiresome business of registry cleanup // // RETURN VALUE: // // ERROR alas // NOERROR rejoice // //*************************************************************************** void UnregisterProgID (LPCTSTR progid, LPCTSTR progidVer) { HKEY hKey = NULL; TCHAR *szProgID = new TCHAR [_tcslen (WBEMS_RK_SC) + _tcslen (progid) + 1]; TCHAR *szProgIDVer = new TCHAR [_tcslen (WBEMS_RK_SC) + _tcslen (progidVer) + 1]; if (szProgID && szProgIDVer) { _tcscpy (szProgID, WBEMS_RK_SC); _tcscat (szProgID, progid); _tcscpy (szProgIDVer, WBEMS_RK_SC); _tcscat (szProgIDVer, progidVer); // Delete the subkeys of the versioned HKCR\ProgID entry if (NO_ERROR == RegOpenKey(HKEY_LOCAL_MACHINE, szProgIDVer, &hKey)) { RegDeleteKey(hKey, WBEMS_RK_CLSID); RegCloseKey(hKey); } // Delete the versioned HKCR\ProgID entry RegDeleteKey (HKEY_LOCAL_MACHINE, szProgIDVer); // Delete the subkeys of the HKCR\VersionIndependentProgID entry if (NO_ERROR == RegOpenKey(HKEY_LOCAL_MACHINE, szProgID, &hKey)) { RegDeleteKey(hKey, WBEMS_RK_CLSID); DWORD dwRet = RegDeleteKey(hKey, WBEMS_RK_CURVER); RegCloseKey(hKey); } // Delete the HKCR\VersionIndependentProgID entry RegDeleteKey (HKEY_LOCAL_MACHINE, szProgID); } if (szProgID) delete [] szProgID; if (szProgIDVer) delete [] szProgIDVer; } void UnregisterCoClass (REFGUID clsid, LPCTSTR progid, LPCTSTR progidVer) { OLECHAR wcID[GUIDSIZE]; TCHAR nwcID[GUIDSIZE]; HKEY hKey = NULL; TCHAR *szCLSID = new TCHAR [_tcslen (WBEMS_RK_SCC) + GUIDSIZE + 1]; if (szCLSID) { // Create the path using the CLSID if(0 != StringFromGUID2(clsid, wcID, GUIDSIZE)) { #ifndef UNICODE wcstombs(nwcID, wcID, GUIDSIZE); #else _tcscpy (nwcID, wcID); #endif _tcscpy (szCLSID, WBEMS_RK_SCC); _tcscat (szCLSID, nwcID); // First delete the subkeys of the HKLM\Software\Classes\CLSID\{GUID} entry if(NO_ERROR == RegOpenKey(HKEY_LOCAL_MACHINE, szCLSID, &hKey)) { RegDeleteKey(hKey, WBEMS_RK_INPROC32); RegDeleteKey(hKey, WBEMS_RK_TYPELIB); RegDeleteKey(hKey, WBEMS_RK_PROGID); RegDeleteKey(hKey, WBEMS_RK_VERPROGID); RegDeleteKey(hKey, WBEMS_RK_VERSION); RegDeleteKey(hKey, WBEMS_RK_PROGRAMMABLE); RegCloseKey(hKey); } // Delete the HKLM\Software\Classes\CLSID\{GUID} key if(NO_ERROR == RegOpenKey(HKEY_LOCAL_MACHINE, WBEMS_RK_SCC, &hKey)) { RegDeleteKey(hKey, nwcID); RegCloseKey(hKey); } } delete [] szCLSID; } UnregisterProgID (progid, progidVer); } static void UnregisterTypeLibrary (unsigned short wVerMajor, unsigned short wVerMinor) { // Unregister the type library. The UnRegTypeLib function is not available in // in some of the older version of the ole dlls and so it must be loaded // dynamically HRESULT (STDAPICALLTYPE *pfnUnReg)(REFGUID, WORD, WORD , LCID , SYSKIND); TCHAR path[ MAX_PATH+20 ]; GetSystemDirectory(path, MAX_PATH); _tcscat(path, _T("\\oleaut32.dll")); HMODULE g_hOle32 = LoadLibraryEx(path, NULL, 0); if(g_hOle32 != NULL) { (FARPROC&)pfnUnReg = GetProcAddress(g_hOle32, "UnRegisterTypeLib"); if(pfnUnReg) pfnUnReg (LIBID_WbemScripting, wVerMajor, wVerMinor, 0, SYS_WIN32); FreeLibrary(g_hOle32); } } void UnregisterScriptSettings () { HKEY hKey; if(NO_ERROR == RegOpenKey(HKEY_LOCAL_MACHINE, WBEMS_RK_WBEM, &hKey)) { RegDeleteKey(hKey, WBEMS_SK_SCRIPTING); RegCloseKey (hKey); } } //*************************************************************************** // // DllUnregisterServer // // Purpose: Called when it is time to remove the registry entries. // // Return: NOERROR if registration successful, error otherwise. //*************************************************************************** STDAPI DllUnregisterServer(void) { UnregisterScriptSettings (); UnregisterCoClass (CLSID_SWbemLocator, WBEMS_LOC_PROGID, WBEMS_LOC_PROGIDVER); UnregisterCoClass (CLSID_SWbemSink, WBEMS_SINK_PROGID, WBEMS_SINK_PROGIDVER); UnregisterCoClass (CLSID_SWbemNamedValueSet, WBEMS_CON_PROGID, WBEMS_CON_PROGIDVER); UnregisterCoClass (CLSID_SWbemLastError, WBEMS_LER_PROGID, WBEMS_LER_PROGIDVER); UnregisterCoClass (CLSID_SWbemObjectPath, WBEMS_OBP_PROGID, WBEMS_OBP_PROGIDVER); UnregisterCoClass (CLSID_SWbemParseDN, WBEMS_PDN_PROGID, WBEMS_PDN_PROGIDVER); UnregisterCoClass (CLSID_SWbemDateTime, WBEMS_DTIME_PROGID, WBEMS_DTIME_PROGIDVER); UnregisterCoClass (CLSID_SWbemRefresher, WBEMS_REF_PROGID, WBEMS_REF_PROGIDVER); UnregisterTypeLibrary (1, 2); return NOERROR; }