|
|
//*************************************************************
//
// Microsoft Confidential. Copyright (c) Microsoft Corporation 1999.
//
// File: MainDll.cpp
//
// Description: Dll registry, get class object functions
//
// History: 8-20-99 leonardm Created
// 1-15-00 NishadM
//
//*************************************************************
#include "uenv.h"
#include "Factory.h"
#include "rsopdbg.h"
#include "initguid.h"
#include <wbemcli.h>
#define SECURITY_WIN32
#include <security.h>
#include <aclapi.h>
#include "smartptr.h"
#include "rsopinc.h"
#include "rsopsec.h"
HRESULT GetRsopSchemaVersionNumber(IWbemServices *pWbemServices, DWORD *dwVersionNumber);
// {B3FF88A4-96EC-4cc1-983F-72BE0EBB368B}
DEFINE_GUID(CLSID_CSnapProv, 0xb3ff88a4, 0x96ec, 0x4cc1, 0x98, 0x3f, 0x72, 0xbe, 0xe, 0xbb, 0x36, 0x8b);
// Count of objects and locks.
long g_cObj = 0; long g_cLock = 0;
CDebug dbgRsop;
extern "C" { STDMETHODIMP RSoPMakeAbsoluteSD(SECURITY_DESCRIPTOR* pSelfRelativeSD, SECURITY_DESCRIPTOR** ppAbsoluteSD); STDMETHODIMP GetNamespaceSD(IWbemServices* pWbemServices, SECURITY_DESCRIPTOR** ppSD); STDMETHODIMP SetNamespaceSD(SECURITY_DESCRIPTOR* pSD, IWbemServices* pWbemServices); STDMETHODIMP FreeAbsoluteSD(SECURITY_DESCRIPTOR* pAbsoluteSD); STDMETHODIMP GetWbemServicesPtr( LPCWSTR, IWbemLocator**, IWbemServices** ); };
/*
LPWSTR GetDomainName(); DWORD MakeUserName( LPWSTR szDomain, LPWSTR szUser, LPWSTR* pszUserName ); STDMETHODIMP SetNameSpaceSecurity( IWbemServices*, PSECURITY_DESCRIPTOR, LPWSTR* pszPrincipals, DWORD nPrincipals ); */ void InitializeSnapProv( void ) { dbgRsop.Initialize( L"Software\\Microsoft\\Windows NT\\CurrentVersion\\winlogon", L"RsopDebugLevel", L"userenv.log", L"userenv.bak", FALSE ); }
extern "C" STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) { if (rclsid != CLSID_CSnapProv) { return CLASS_E_CLASSNOTAVAILABLE; }
CProvFactory* pFactory = new CProvFactory();
if (pFactory == NULL) { return E_OUTOFMEMORY; }
HRESULT hRes = pFactory->QueryInterface(riid, ppv);
pFactory->Release();
return hRes; }
extern "C" STDAPI DllCanUnloadNow() { // It is OK to unload if there are no objects or locks on the class factory.
if( g_cObj == 0L && g_cLock == 0L ) { return S_OK; } else { return S_FALSE; } }
extern "C" STDAPI DllRegisterServer(void) { wchar_t szID[128]; wchar_t szCLSID[128]; wchar_t szModule[MAX_PATH]; wchar_t* pName = L"Rsop Logging Mode Provider"; wchar_t* pModel = L"Both";
HKEY hKey1, hKey2;
// Create the path.
GuidToString( &CLSID_CSnapProv, szID ); wcscpy(szCLSID, TEXT("CLSID\\")); lstrcat(szCLSID, szID);
// Create entries under CLSID
RegCreateKey(HKEY_CLASSES_ROOT, szCLSID, &hKey1); RegSetValueEx(hKey1, NULL, 0, REG_SZ, (BYTE*)pName, (wcslen(pName) + 1) * sizeof(wchar_t));
RegCreateKey(hKey1, L"InprocServer32", &hKey2); GetModuleFileName(g_hDllInstance, szModule, MAX_PATH); RegSetValueEx(hKey2, NULL, 0, REG_SZ, (BYTE*)szModule, (wcslen(szModule) + 1) * sizeof(wchar_t)); RegSetValueEx(hKey2, L"ThreadingModel", 0, REG_SZ, (BYTE*)pModel, (wcslen(pModel) + 1) * sizeof(wchar_t));
CloseHandle(hKey1); CloseHandle(hKey2);
return S_OK; }
extern "C" STDAPI DllUnregisterServer(void) { wchar_t szID[128]; wchar_t szCLSID[128]; HKEY hKey;
// Create the path using the CLSID
GuidToString( &CLSID_CSnapProv, szID ); wcscpy(szCLSID, TEXT("CLSID\\")); wcscat(szCLSID, szID);
// First delete the InProcServer subkey.
DWORD dwRet = RegOpenKey(HKEY_CLASSES_ROOT, szCLSID, &hKey); if(dwRet == ERROR_SUCCESS) { RegDeleteKey(hKey, L"InProcServer32"); CloseHandle(hKey); }
dwRet = RegOpenKey(HKEY_CLASSES_ROOT, L"CLSID", &hKey); if(dwRet == ERROR_SUCCESS) { RegDeleteKey(hKey,szID); CloseHandle(hKey); }
return S_OK; }
BOOL RunningOnWow64() { #if defined(_WIN64)
// 64bit builds don't run in Wow64
return false; #else
// OS version
OSVERSIONINFO osviVersion; osviVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); if (!GetVersionEx(&osviVersion)) { DebugMsg((DM_WARNING, TEXT("RunningOnWow64: Couldn't detect Version with error %d"), GetLastError())); return FALSE; }
// on NT5 or later 32bit build. Check for 64 bit OS
if ((osviVersion.dwPlatformId == VER_PLATFORM_WIN32_NT) && (osviVersion.dwMajorVersion >= 5)) { // QueryInformation for ProcessWow64Information returns a pointer to the Wow Info.
// if running native, it returns NULL.
PVOID pWow64Info = 0; if (NT_SUCCESS(NtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information, &pWow64Info, sizeof(pWow64Info), NULL)) && pWow64Info != NULL) { // running 32bit on Wow64.
return TRUE; } } return FALSE; #endif
}
HRESULT CompileMOF( LPCWSTR szMOFFile, LPCWSTR szMFLFile ) { WCHAR szNamespace[MAX_PATH]; BOOL bUpgrade = FALSE; HRESULT hr;
XInterface<IWbemLocator> xWbemLocator; XInterface<IWbemServices> xWbemServicesOld; DWORD dwCurrentVersion= 0; DWORD dwNewVersion = RSOP_MOF_SCHEMA_VERSION;
//
// On wow64 do nothing
//
if (RunningOnWow64()) { DebugMsg((DM_VERBOSE, TEXT("CompileMof: Running on Wow64. returning without doing anything"))); return S_OK; }
if ( !szMOFFile ) { return E_POINTER; }
wcscpy(szNamespace, RSOP_NS_ROOT); //
// Get the wbem services pointer to the machine namespace
//
hr = GetWbemServicesPtr(RSOP_NS_MACHINE, &xWbemLocator, &xWbemServicesOld );
if (!xWbemLocator) { DebugMsg((DM_WARNING, TEXT("CompileMof: Failed to get IWbemLocator pointer.Error 0x%x"), hr)); return hr; }
if ( (SUCCEEDED(hr)) && (xWbemServicesOld)) { hr = GetRsopSchemaVersionNumber(xWbemServicesOld, &dwCurrentVersion); if (FAILED(hr)) { return hr; } }
if (HIWORD(dwCurrentVersion) != HIWORD(dwNewVersion)) {
//
// We should cleanout the schema and recreate below
//
DebugMsg((DM_VERBOSE, TEXT("CompileMof: Major version schema upgrade detected. Deleting rsop namespace and rebuilding"))); xWbemServicesOld = NULL; hr = DeleteRsopNameSpace(szNamespace, xWbemLocator); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CompileMof: Failed to get delete the rsop namespace. Error 0x%x. Continuing.."), hr)); } //
// Delete the state info on the machine
//
if (!RegDelnode(HKEY_LOCAL_MACHINE, GP_STATE_ROOT_KEY)) { DebugMsg((DM_WARNING, TEXT("CompileMof: Failed to delete the state key. Error 0x%x. Continuing.."), hr)); }
bUpgrade = FALSE; } else { bUpgrade = TRUE; }
XInterface<IMofCompiler> xpMofCompiler; //
// get a handle to IMofCompiler
//
hr = CoCreateInstance( CLSID_MofCompiler, 0, CLSCTX_INPROC_SERVER, IID_IMofCompiler, (LPVOID*) &xpMofCompiler ); if ( FAILED(hr) ) { DebugMsg((DM_WARNING, L"CompileMOF: CoCreateInstance() failed, 0x%X.", hr)); return hr; }
WBEM_COMPILE_STATUS_INFO Info;
hr = xpMofCompiler->CompileFile((LPWSTR)szMOFFile, 0, // no server & namespace
0, // no user
0, // no authority
0, // no password
0, // no options
0, // no class flags
0, // no instance flags
&Info ); if ( FAILED( hr ) ) { DebugMsg((DM_WARNING, L"CompileMOF: IMofCompiler::CompileFile() failed, 0x%X.", hr)); } else { if (hr != S_OK ) { DebugMsg((DM_WARNING, L"CompileMOF: IMofCompiler::CompileFile() returned with 0x%X.", hr)); DebugMsg((DM_WARNING, L"CompileMOF: Details - lPhaseError - %d, hRes = 0x%x, ObjectNum - %d, firstline - %d, LastLine - %d", Info.lPhaseError, Info.hRes, Info.ObjectNum, Info.FirstLine, Info.LastLine )); } else { hr = xpMofCompiler->CompileFile((LPWSTR)szMFLFile, 0, // no server & namespace
0, // no user
0, // no authority
0, // no password
0, // no options
0, // no class flags
0, // no instance flags
&Info ); if ( FAILED( hr ) ) { DebugMsg((DM_WARNING, L"CompileMOF: IMofCompiler::CompileFile() failed, 0x%X.", hr)); } else { if (hr != S_OK ) { DebugMsg((DM_WARNING, L"CompileMOF: IMofCompiler::CompileFile() returned with 0x%X.", hr)); DebugMsg((DM_WARNING, L"CompileMOF: Details - lPhaseError - %d, hRes = 0x%x, ObjectNum - %d, firstline - %d, LastLine - %d", Info.lPhaseError, Info.hRes, Info.ObjectNum, Info.FirstLine, Info.LastLine )); } } } }
//
// if xWbemServicesOld exists, this is an upgrade.
// retain old security.
//
if ( !bUpgrade ) { XPtrLF<SECURITY_DESCRIPTOR> xsd; SECURITY_ATTRIBUTES sa; CSecDesc Csd;
Csd.AddLocalSystem(RSOP_ALL_PERMS, CONTAINER_INHERIT_ACE); Csd.AddAdministrators(RSOP_ALL_PERMS, CONTAINER_INHERIT_ACE); Csd.AddAdministratorsAsOwner(); Csd.AddAdministratorsAsGroup(); Csd.AddAuthUsers(RSOP_READ_PERMS); // no inheritance
xsd = Csd.MakeSelfRelativeSD(); if (!xsd) { dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("CompileMOF::MakeSelfSD failed with %d"), GetLastError()); return HRESULT_FROM_WIN32(GetLastError()); }
if (!SetSecurityDescriptorControl( (SECURITY_DESCRIPTOR *)xsd, SE_DACL_PROTECTED, SE_DACL_PROTECTED )) { dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("CompileMOF::SetSecurityDescriptorControl failed with %d"), GetLastError()); return HRESULT_FROM_WIN32(GetLastError()); }
hr = SetNameSpaceSecurity(szNamespace, xsd, xWbemLocator);
if (FAILED(hr)) { DebugMsg((DM_WARNING, L"CompileMOF: SetNamespaceSecurity() failed, 0x%X.", hr)); return hr; }
hr = SetNameSpaceSecurity(RSOP_NS_USER, xsd, xWbemLocator);
if (FAILED(hr)) { DebugMsg((DM_WARNING, L"CompileMOF: SetNamespaceSecurity() failed, 0x%X.", hr)); return hr; }
hr = SetNameSpaceSecurity(RSOP_NS_MACHINE, xsd, xWbemLocator);
if (FAILED(hr)) { DebugMsg((DM_WARNING, L"CompileMOF: SetNamespaceSecurity() failed, 0x%X.", hr)); return hr; }
} return hr; }
//
// currently this code is intended to be called by regsvr32.
// setup does not call this code.
// "regsvr32 /n /i userenv.dll"
// waiting for WMI gives us a mechanism to install our MOF at setup time.
//
extern "C" STDAPI DllInstall( BOOL, LPCWSTR ) { HRESULT hr = S_OK; WCHAR szMofFile[MAX_PATH]; WCHAR szMflFile[MAX_PATH];
if ( GetSystemDirectory( szMofFile, MAX_PATH ) ) { wcscpy( szMflFile, szMofFile );
LPWSTR szMOF = CheckSlash(szMofFile); LPWSTR szMFL = CheckSlash(szMflFile); wcscat( szMOF, L"Wbem\\RSoP.mof" ); wcscat( szMFL, L"Wbem\\RSoP.mfl" );
hr = CompileMOF( szMofFile, szMflFile ); } else { hr = GetLastError(); } return hr; }
|