Source code of Windows XP (NT5)
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.

435 lines
12 KiB

  1. //*************************************************************
  2. //
  3. // Microsoft Confidential. Copyright (c) Microsoft Corporation 1999.
  4. //
  5. // File: MainDll.cpp
  6. //
  7. // Description: Dll registry, get class object functions
  8. //
  9. // History: 8-20-99 leonardm Created
  10. // 1-15-00 NishadM
  11. //
  12. //*************************************************************
  13. #include "uenv.h"
  14. #include "Factory.h"
  15. #include "rsopdbg.h"
  16. #include "initguid.h"
  17. #include <wbemcli.h>
  18. #define SECURITY_WIN32
  19. #include <security.h>
  20. #include <aclapi.h>
  21. #include "smartptr.h"
  22. #include "rsopinc.h"
  23. #include "rsopsec.h"
  24. HRESULT GetRsopSchemaVersionNumber(IWbemServices *pWbemServices, DWORD *dwVersionNumber);
  25. // {B3FF88A4-96EC-4cc1-983F-72BE0EBB368B}
  26. DEFINE_GUID(CLSID_CSnapProv, 0xb3ff88a4, 0x96ec, 0x4cc1, 0x98, 0x3f, 0x72, 0xbe, 0xe, 0xbb, 0x36, 0x8b);
  27. // Count of objects and locks.
  28. long g_cObj = 0;
  29. long g_cLock = 0;
  30. CDebug dbgRsop;
  31. extern "C"
  32. {
  33. STDMETHODIMP RSoPMakeAbsoluteSD(SECURITY_DESCRIPTOR* pSelfRelativeSD, SECURITY_DESCRIPTOR** ppAbsoluteSD);
  34. STDMETHODIMP GetNamespaceSD(IWbemServices* pWbemServices, SECURITY_DESCRIPTOR** ppSD);
  35. STDMETHODIMP SetNamespaceSD(SECURITY_DESCRIPTOR* pSD, IWbemServices* pWbemServices);
  36. STDMETHODIMP FreeAbsoluteSD(SECURITY_DESCRIPTOR* pAbsoluteSD);
  37. STDMETHODIMP GetWbemServicesPtr( LPCWSTR, IWbemLocator**, IWbemServices** );
  38. };
  39. /*
  40. LPWSTR GetDomainName();
  41. DWORD MakeUserName( LPWSTR szDomain, LPWSTR szUser, LPWSTR* pszUserName );
  42. STDMETHODIMP SetNameSpaceSecurity( IWbemServices*, PSECURITY_DESCRIPTOR, LPWSTR* pszPrincipals, DWORD nPrincipals );
  43. */
  44. void
  45. InitializeSnapProv( void )
  46. {
  47. dbgRsop.Initialize( L"Software\\Microsoft\\Windows NT\\CurrentVersion\\winlogon",
  48. L"RsopDebugLevel",
  49. L"userenv.log",
  50. L"userenv.bak",
  51. FALSE );
  52. }
  53. extern "C"
  54. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
  55. {
  56. if (rclsid != CLSID_CSnapProv)
  57. {
  58. return CLASS_E_CLASSNOTAVAILABLE;
  59. }
  60. CProvFactory* pFactory = new CProvFactory();
  61. if (pFactory == NULL)
  62. {
  63. return E_OUTOFMEMORY;
  64. }
  65. HRESULT hRes = pFactory->QueryInterface(riid, ppv);
  66. pFactory->Release();
  67. return hRes;
  68. }
  69. extern "C"
  70. STDAPI DllCanUnloadNow()
  71. {
  72. // It is OK to unload if there are no objects or locks on the class factory.
  73. if( g_cObj == 0L && g_cLock == 0L )
  74. {
  75. return S_OK;
  76. }
  77. else
  78. {
  79. return S_FALSE;
  80. }
  81. }
  82. extern "C"
  83. STDAPI DllRegisterServer(void)
  84. {
  85. wchar_t szID[128];
  86. wchar_t szCLSID[128];
  87. wchar_t szModule[MAX_PATH];
  88. wchar_t* pName = L"Rsop Logging Mode Provider";
  89. wchar_t* pModel = L"Both";
  90. HKEY hKey1, hKey2;
  91. // Create the path.
  92. GuidToString( &CLSID_CSnapProv, szID );
  93. wcscpy(szCLSID, TEXT("CLSID\\"));
  94. lstrcat(szCLSID, szID);
  95. // Create entries under CLSID
  96. RegCreateKey(HKEY_CLASSES_ROOT, szCLSID, &hKey1);
  97. RegSetValueEx(hKey1, NULL, 0, REG_SZ, (BYTE*)pName, (wcslen(pName) + 1) * sizeof(wchar_t));
  98. RegCreateKey(hKey1, L"InprocServer32", &hKey2);
  99. GetModuleFileName(g_hDllInstance, szModule, MAX_PATH);
  100. RegSetValueEx(hKey2, NULL, 0, REG_SZ, (BYTE*)szModule, (wcslen(szModule) + 1) * sizeof(wchar_t));
  101. RegSetValueEx(hKey2, L"ThreadingModel", 0, REG_SZ, (BYTE*)pModel, (wcslen(pModel) + 1) * sizeof(wchar_t));
  102. CloseHandle(hKey1);
  103. CloseHandle(hKey2);
  104. return S_OK;
  105. }
  106. extern "C"
  107. STDAPI DllUnregisterServer(void)
  108. {
  109. wchar_t szID[128];
  110. wchar_t szCLSID[128];
  111. HKEY hKey;
  112. // Create the path using the CLSID
  113. GuidToString( &CLSID_CSnapProv, szID );
  114. wcscpy(szCLSID, TEXT("CLSID\\"));
  115. wcscat(szCLSID, szID);
  116. // First delete the InProcServer subkey.
  117. DWORD dwRet = RegOpenKey(HKEY_CLASSES_ROOT, szCLSID, &hKey);
  118. if(dwRet == ERROR_SUCCESS)
  119. {
  120. RegDeleteKey(hKey, L"InProcServer32");
  121. CloseHandle(hKey);
  122. }
  123. dwRet = RegOpenKey(HKEY_CLASSES_ROOT, L"CLSID", &hKey);
  124. if(dwRet == ERROR_SUCCESS)
  125. {
  126. RegDeleteKey(hKey,szID);
  127. CloseHandle(hKey);
  128. }
  129. return S_OK;
  130. }
  131. BOOL RunningOnWow64()
  132. {
  133. #if defined(_WIN64)
  134. // 64bit builds don't run in Wow64
  135. return false;
  136. #else
  137. // OS version
  138. OSVERSIONINFO osviVersion;
  139. osviVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  140. if (!GetVersionEx(&osviVersion)) {
  141. DebugMsg((DM_WARNING, TEXT("RunningOnWow64: Couldn't detect Version with error %d"), GetLastError()));
  142. return FALSE;
  143. }
  144. // on NT5 or later 32bit build. Check for 64 bit OS
  145. if ((osviVersion.dwPlatformId == VER_PLATFORM_WIN32_NT) &&
  146. (osviVersion.dwMajorVersion >= 5))
  147. {
  148. // QueryInformation for ProcessWow64Information returns a pointer to the Wow Info.
  149. // if running native, it returns NULL.
  150. PVOID pWow64Info = 0;
  151. if (NT_SUCCESS(NtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information, &pWow64Info, sizeof(pWow64Info), NULL))
  152. && pWow64Info != NULL)
  153. {
  154. // running 32bit on Wow64.
  155. return TRUE;
  156. }
  157. }
  158. return FALSE;
  159. #endif
  160. }
  161. HRESULT
  162. CompileMOF( LPCWSTR szMOFFile, LPCWSTR szMFLFile )
  163. {
  164. WCHAR szNamespace[MAX_PATH];
  165. BOOL bUpgrade = FALSE;
  166. HRESULT hr;
  167. XInterface<IWbemLocator> xWbemLocator;
  168. XInterface<IWbemServices> xWbemServicesOld;
  169. DWORD dwCurrentVersion= 0;
  170. DWORD dwNewVersion = RSOP_MOF_SCHEMA_VERSION;
  171. //
  172. // On wow64 do nothing
  173. //
  174. if (RunningOnWow64()) {
  175. DebugMsg((DM_VERBOSE, TEXT("CompileMof: Running on Wow64. returning without doing anything")));
  176. return S_OK;
  177. }
  178. if ( !szMOFFile )
  179. {
  180. return E_POINTER;
  181. }
  182. wcscpy(szNamespace, RSOP_NS_ROOT);
  183. //
  184. // Get the wbem services pointer to the machine namespace
  185. //
  186. hr = GetWbemServicesPtr(RSOP_NS_MACHINE,
  187. &xWbemLocator,
  188. &xWbemServicesOld );
  189. if (!xWbemLocator) {
  190. DebugMsg((DM_WARNING, TEXT("CompileMof: Failed to get IWbemLocator pointer.Error 0x%x"), hr));
  191. return hr;
  192. }
  193. if ( (SUCCEEDED(hr)) && (xWbemServicesOld)) {
  194. hr = GetRsopSchemaVersionNumber(xWbemServicesOld, &dwCurrentVersion);
  195. if (FAILED(hr)) {
  196. return hr;
  197. }
  198. }
  199. if (HIWORD(dwCurrentVersion) != HIWORD(dwNewVersion)) {
  200. //
  201. // We should cleanout the schema and recreate below
  202. //
  203. DebugMsg((DM_VERBOSE, TEXT("CompileMof: Major version schema upgrade detected. Deleting rsop namespace and rebuilding")));
  204. xWbemServicesOld = NULL;
  205. hr = DeleteRsopNameSpace(szNamespace, xWbemLocator);
  206. if (FAILED(hr)) {
  207. DebugMsg((DM_WARNING, TEXT("CompileMof: Failed to get delete the rsop namespace. Error 0x%x. Continuing.."), hr));
  208. }
  209. //
  210. // Delete the state info on the machine
  211. //
  212. if (!RegDelnode(HKEY_LOCAL_MACHINE, GP_STATE_ROOT_KEY)) {
  213. DebugMsg((DM_WARNING, TEXT("CompileMof: Failed to delete the state key. Error 0x%x. Continuing.."), hr));
  214. }
  215. bUpgrade = FALSE;
  216. }
  217. else {
  218. bUpgrade = TRUE;
  219. }
  220. XInterface<IMofCompiler> xpMofCompiler;
  221. //
  222. // get a handle to IMofCompiler
  223. //
  224. hr = CoCreateInstance( CLSID_MofCompiler,
  225. 0,
  226. CLSCTX_INPROC_SERVER,
  227. IID_IMofCompiler,
  228. (LPVOID*) &xpMofCompiler );
  229. if ( FAILED(hr) )
  230. {
  231. DebugMsg((DM_WARNING, L"CompileMOF: CoCreateInstance() failed, 0x%X.", hr));
  232. return hr;
  233. }
  234. WBEM_COMPILE_STATUS_INFO Info;
  235. hr = xpMofCompiler->CompileFile((LPWSTR)szMOFFile,
  236. 0, // no server & namespace
  237. 0, // no user
  238. 0, // no authority
  239. 0, // no password
  240. 0, // no options
  241. 0, // no class flags
  242. 0, // no instance flags
  243. &Info );
  244. if ( FAILED( hr ) )
  245. {
  246. DebugMsg((DM_WARNING, L"CompileMOF: IMofCompiler::CompileFile() failed, 0x%X.", hr));
  247. }
  248. else
  249. {
  250. if (hr != S_OK )
  251. {
  252. DebugMsg((DM_WARNING, L"CompileMOF: IMofCompiler::CompileFile() returned with 0x%X.", hr));
  253. DebugMsg((DM_WARNING, L"CompileMOF: Details - lPhaseError - %d, hRes = 0x%x, ObjectNum - %d, firstline - %d, LastLine - %d",
  254. Info.lPhaseError, Info.hRes, Info.ObjectNum, Info.FirstLine, Info.LastLine ));
  255. }
  256. else
  257. {
  258. hr = xpMofCompiler->CompileFile((LPWSTR)szMFLFile,
  259. 0, // no server & namespace
  260. 0, // no user
  261. 0, // no authority
  262. 0, // no password
  263. 0, // no options
  264. 0, // no class flags
  265. 0, // no instance flags
  266. &Info );
  267. if ( FAILED( hr ) )
  268. {
  269. DebugMsg((DM_WARNING, L"CompileMOF: IMofCompiler::CompileFile() failed, 0x%X.", hr));
  270. }
  271. else
  272. {
  273. if (hr != S_OK )
  274. {
  275. DebugMsg((DM_WARNING, L"CompileMOF: IMofCompiler::CompileFile() returned with 0x%X.", hr));
  276. DebugMsg((DM_WARNING, L"CompileMOF: Details - lPhaseError - %d, hRes = 0x%x, ObjectNum - %d, firstline - %d, LastLine - %d",
  277. Info.lPhaseError, Info.hRes, Info.ObjectNum, Info.FirstLine, Info.LastLine ));
  278. }
  279. }
  280. }
  281. }
  282. //
  283. // if xWbemServicesOld exists, this is an upgrade.
  284. // retain old security.
  285. //
  286. if ( !bUpgrade )
  287. {
  288. XPtrLF<SECURITY_DESCRIPTOR> xsd;
  289. SECURITY_ATTRIBUTES sa;
  290. CSecDesc Csd;
  291. Csd.AddLocalSystem(RSOP_ALL_PERMS, CONTAINER_INHERIT_ACE);
  292. Csd.AddAdministrators(RSOP_ALL_PERMS, CONTAINER_INHERIT_ACE);
  293. Csd.AddAdministratorsAsOwner();
  294. Csd.AddAdministratorsAsGroup();
  295. Csd.AddAuthUsers(RSOP_READ_PERMS); // no inheritance
  296. xsd = Csd.MakeSelfRelativeSD();
  297. if (!xsd) {
  298. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("CompileMOF::MakeSelfSD failed with %d"), GetLastError());
  299. return HRESULT_FROM_WIN32(GetLastError());
  300. }
  301. if (!SetSecurityDescriptorControl( (SECURITY_DESCRIPTOR *)xsd, SE_DACL_PROTECTED, SE_DACL_PROTECTED )) {
  302. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("CompileMOF::SetSecurityDescriptorControl failed with %d"), GetLastError());
  303. return HRESULT_FROM_WIN32(GetLastError());
  304. }
  305. hr = SetNameSpaceSecurity(szNamespace, xsd, xWbemLocator);
  306. if (FAILED(hr)) {
  307. DebugMsg((DM_WARNING, L"CompileMOF: SetNamespaceSecurity() failed, 0x%X.", hr));
  308. return hr;
  309. }
  310. hr = SetNameSpaceSecurity(RSOP_NS_USER, xsd, xWbemLocator);
  311. if (FAILED(hr)) {
  312. DebugMsg((DM_WARNING, L"CompileMOF: SetNamespaceSecurity() failed, 0x%X.", hr));
  313. return hr;
  314. }
  315. hr = SetNameSpaceSecurity(RSOP_NS_MACHINE, xsd, xWbemLocator);
  316. if (FAILED(hr)) {
  317. DebugMsg((DM_WARNING, L"CompileMOF: SetNamespaceSecurity() failed, 0x%X.", hr));
  318. return hr;
  319. }
  320. }
  321. return hr;
  322. }
  323. //
  324. // currently this code is intended to be called by regsvr32.
  325. // setup does not call this code.
  326. // "regsvr32 /n /i userenv.dll"
  327. // waiting for WMI gives us a mechanism to install our MOF at setup time.
  328. //
  329. extern "C"
  330. STDAPI DllInstall( BOOL, LPCWSTR )
  331. {
  332. HRESULT hr = S_OK;
  333. WCHAR szMofFile[MAX_PATH];
  334. WCHAR szMflFile[MAX_PATH];
  335. if ( GetSystemDirectory( szMofFile, MAX_PATH ) )
  336. {
  337. wcscpy( szMflFile, szMofFile );
  338. LPWSTR szMOF = CheckSlash(szMofFile);
  339. LPWSTR szMFL = CheckSlash(szMflFile);
  340. wcscat( szMOF, L"Wbem\\RSoP.mof" );
  341. wcscat( szMFL, L"Wbem\\RSoP.mfl" );
  342. hr = CompileMOF( szMofFile, szMflFile );
  343. }
  344. else
  345. {
  346. hr = GetLastError();
  347. }
  348. return hr;
  349. }