800 lines
22 KiB
C++
800 lines
22 KiB
C++
|
//***************************************************************************
|
||
|
//
|
||
|
// 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
|
||
|
_tcsncpy (nwcID, wcID, GUIDSIZE);
|
||
|
#endif
|
||
|
|
||
|
_tcscat (szCLSID, nwcID);
|
||
|
|
||
|
if (0 == StringFromGUID2 (LIBID_WbemScripting, tlID, GUIDSIZE))
|
||
|
{
|
||
|
delete [] szCLSID;
|
||
|
return ERROR;
|
||
|
}
|
||
|
|
||
|
#ifndef UNICODE
|
||
|
wcstombs (ntlID, tlID, GUIDSIZE);
|
||
|
#else
|
||
|
_tcsncpy (ntlID, tlID, GUIDSIZE);
|
||
|
#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];
|
||
|
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
|
||
|
_tcsncpy (nwcID, wcID, GUIDSIZE);
|
||
|
#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;
|
||
|
}
|
||
|
|
||
|
|