Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

338 lines
8.8 KiB

//***************************************************************************
//
// MAINDLL.CPP
//
// Module: WBEM Instance provider sample code
//
// Purpose: Contains DLL entry points. Also has code that controls
// when the DLL can be unloaded by tracking the number of
// objects and locks as well as routines that support
// self registration.
//
// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
//
//***************************************************************************
#include "precomp.h"
#include <tchar.h>
#include <objbase.h>
#include <initguid.h>
#include <msiprov.h>
#include "classfac.h"
#include "genericclass.h"
#include "requestobject.h"
// Function pointer type used with LoadMofFiles entrypoint in wbemupgd.dll
typedef BOOL ( WINAPI *PFN_LOAD_MOF_FILES )(wchar_t* pComponentName, const char* rgpszMofFilename[]);
HMODULE ghModule;
DEFINE_GUID(CLSID_MSIprov,0xbe0a9830, 0x2b8b, 0x11d1, 0xa9, 0x49, 0x0, 0x60, 0x18, 0x1e, 0xbb, 0xad);
// {BE0A9830-2B8B-11D1-A949-0060181EBBAD}
//Count number of objects and number of locks.
long g_cObj=0;
long g_cLock=0;
//***************************************************************************
//
// LibMain32
//
// Purpose: Entry point for DLL.
//
// Return: TRUE if OK.
//
//***************************************************************************
BOOL WINAPI DllMain(HINSTANCE hInstance, ULONG ulReason
, LPVOID pvReserved)
{
BOOL retVal = TRUE;
if(DLL_PROCESS_DETACH == ulReason){
DeleteCriticalSection(&g_msi_prov_cs);
DeleteCriticalSection(&(CRequestObject::m_cs));
DeleteCriticalSection(&(CGenericClass::m_cs));
}else if(DLL_PROCESS_ATTACH == ulReason){
InitializeCriticalSection(&(CRequestObject::m_cs));
InitializeCriticalSection(&(CGenericClass::m_cs));
DisableThreadLibraryCalls(hInstance); // 158024
try
{
//for this one we can't afford to throw on lock failure.
retVal = InitializeCriticalSectionAndSpinCount(&g_msi_prov_cs, 0x80000000);
}
catch(...)
{
retVal = FALSE;
}
}
return retVal;
}
//***************************************************************************
//
// DllGetClassObject
//
// Purpose: Called by Ole when some client wants a class factory. Return
// one only if it is the sort of class this DLL supports.
//
//***************************************************************************
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID * ppv)
{
HRESULT hr = 0;
CProvFactory *pObj;
if(CLSID_MSIprov!=rclsid) return E_FAIL;
pObj = new CProvFactory();
if(NULL == pObj) return E_OUTOFMEMORY;
hr = pObj->QueryInterface(riid, ppv);
if(FAILED(hr)) delete pObj;
return hr;
}
//***************************************************************************
//
// DllCanUnloadNow
//
// Purpose: Called periodically by Ole in order to determine if the
// DLL can be freed.
//
// Return: S_OK 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;
if ( sc == S_OK )
{
UnloadMsiDll();
if ( g_wcpLoggingDir )
{
delete [] g_wcpLoggingDir;
g_wcpLoggingDir = NULL;
}
}
return sc;
}
BOOL IsLessThan4()
{
OSVERSIONINFO os;
os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if(!GetVersionEx(&os))
return FALSE; // should never happen
return os.dwMajorVersion < 4;
}
//***************************************************************************
//
// DllRegisterServer
//
// Purpose: Called during setup or by regsvr32.
//
// Return: NOERROR if registration successful, error otherwise.
//***************************************************************************
STDAPI DllRegisterServer(void)
{
#ifndef UNICODE
TCHAR szID[265];
#else UNICODE
TCHAR* szID = NULL;
#endif UNICODE
WCHAR wcID[265];
TCHAR szCLSID[265];
TCHAR szModule[MAX_PATH+1];
TCHAR * pName = _T("WMI MSI Provider");
TCHAR * pModel;
HKEY hKey1, hKey2;
ghModule = GetModuleHandle(_T("MSIPROV"));
// Normally we want to use "Both" as the threading model since
// the DLL is free threaded, but NT 3.51 Ole doesnt work unless
// the model is "Aparment"
if(IsLessThan4()) pModel = _T("Apartment");
else pModel = _T("Both");
// Create the path.
StringFromGUID2(CLSID_MSIprov, wcID, 128);
#ifndef UNICODE
WideCharToMultiByte(CP_OEMCP, WC_COMPOSITECHECK, wcID, (-1), szID, 256, NULL, NULL);
#else UNICODE
szID = wcID;
#endif UNICODE
_tcscpy(szCLSID, _T("Software\\classes\\CLSID\\"));
_tcscat(szCLSID, szID);
#ifdef LOCALSERVER
HKEY hKey;
TCHAR szProviderCLSIDAppID[128];
_tcscpy(szProviderCLSIDAppID, _T("SOFTWARE\\CLASSES\\APPID\\"));
_tcscat(szProviderCLSIDAppID, szID);
RegCreateKey(HKEY_LOCAL_MACHINE, szProviderCLSIDAppID, &hKey);
RegSetValueEx(hKey, NULL, 0, REG_SZ, (BYTE *)pName, (_tcslen(pName)+1) * sizeof ( TCHAR ));
CloseHandle(hKey);
#endif
RegCreateKey(HKEY_LOCAL_MACHINE, szCLSID, &hKey1);
RegSetValueEx(hKey1, NULL, 0, REG_SZ, (BYTE *)pName, (_tcslen(pName)+1) * sizeof ( TCHAR ));
// Create entries under CLSID
#ifdef LOCALSERVER
RegCreateKey(hKey1, _T("LocalServer32"), &hKey2);
#else
RegCreateKey(hKey1, _T("InprocServer32"), &hKey2);
#endif
szModule[MAX_PATH] = 0;
GetModuleFileName(ghModule, szModule, MAX_PATH/*length in TCHARS*/);
RegSetValueEx(hKey2, NULL, 0, REG_SZ, (BYTE *)szModule, (_tcslen(szModule)+1) * sizeof ( TCHAR ));
RegSetValueEx(hKey2, _T("ThreadingModel"), 0, REG_SZ, (BYTE *)pModel, (_tcslen(pModel)+1) * sizeof ( TCHAR ));
CloseHandle(hKey1);
CloseHandle(hKey2);
// load the MOF files for this component
HRESULT hr = NOERROR;
HINSTANCE hinstWbemupgd = LoadLibrary(L"wbemupgd.dll");
if (hinstWbemupgd)
{
PFN_LOAD_MOF_FILES pfnLoadMofFiles = (PFN_LOAD_MOF_FILES) GetProcAddress(hinstWbemupgd, "LoadMofFiles"); // no wide version of GetProcAddress
if (pfnLoadMofFiles)
{
wchar_t* wszComponentName = L"MSI Provider";
const char* rgpszMofFilename[] =
{
"msi.mof",
"msi.mfl",
NULL
};
if (!pfnLoadMofFiles(wszComponentName, rgpszMofFilename))
{
hr = WBEM_E_FAILED;
}
}
else
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
FreeLibrary(hinstWbemupgd);
}
else
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
return hr;
}
//***************************************************************************
//
// DllUnregisterServer
//
// Purpose: Called when it is time to remove the registry entries.
//
// Return: NOERROR if registration successful, error otherwise.
//***************************************************************************
STDAPI DllUnregisterServer(void)
{
WCHAR wcID[256];
#ifndef UNICODE
TCHAR szID[265];
#else UNICODE
TCHAR* szID = NULL;
#endif UNICODE
TCHAR wcCLSID[256];
HKEY hKey;
// Create the path using the CLSID
StringFromGUID2(CLSID_MSIprov, wcID, 128);
#ifndef UNICODE
WideCharToMultiByte(CP_OEMCP, WC_COMPOSITECHECK, wcID, (-1), szID, 256, NULL, NULL);
#else UNICODE
szID = wcID;
#endif UNICODE
_tcscpy(wcCLSID, _T("Software\\classes\\CLSID\\"));
_tcscat(wcCLSID, szID);
#ifdef LOCALSERVER
TCHAR szProviderCLSIDAppID[128];
_tcscpy(szProviderCLSIDAppID, _T("SOFTWARE\\CLASSES\\APPID\\"));
_tcscat(szProviderCLSIDAppID,wcCLSID);
//Delete entries under APPID
RegDeleteKey(HKEY_LOCAL_MACHINE, szProviderCLSIDAppID);
TCHAR szTemp[128];
_tcscpy(szTemp, wcCLSID);
_tcscat(szTemp,_T("\\"));
_tcscat(szTemp,_T("LocalServer32"));
RegDeleteKey(HKEY_CLASSES_ROOT, szTemp);
#endif
// First delete the InProcServer subkey.
DWORD dwRet = RegOpenKey(HKEY_LOCAL_MACHINE, wcCLSID, &hKey);
if(dwRet == NO_ERROR){
RegDeleteKey(hKey, _T("InprocServer32"));
CloseHandle(hKey);
}
dwRet = RegOpenKey(HKEY_LOCAL_MACHINE, _T("Software\\classes\\CLSID"), &hKey);
if(dwRet == NO_ERROR){
RegDeleteKey(hKey,szID);
CloseHandle(hKey);
}
return NOERROR;
}