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.

517 lines
15 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. #include <strsafe.h>
  25. HRESULT GetRsopSchemaVersionNumber(IWbemServices *pWbemServices, DWORD *dwVersionNumber);
  26. // {B3FF88A4-96EC-4cc1-983F-72BE0EBB368B}
  27. DEFINE_GUID(CLSID_CSnapProv, 0xb3ff88a4, 0x96ec, 0x4cc1, 0x98, 0x3f, 0x72, 0xbe, 0xe, 0xbb, 0x36, 0x8b);
  28. // Count of objects and locks.
  29. long g_cObj = 0;
  30. long g_cLock = 0;
  31. CDebug dbgRsop;
  32. extern "C"
  33. {
  34. STDMETHODIMP RSoPMakeAbsoluteSD(SECURITY_DESCRIPTOR* pSelfRelativeSD, SECURITY_DESCRIPTOR** ppAbsoluteSD);
  35. STDMETHODIMP GetNamespaceSD(IWbemServices* pWbemServices, SECURITY_DESCRIPTOR** ppSD);
  36. STDMETHODIMP SetNamespaceSD(SECURITY_DESCRIPTOR* pSD, IWbemServices* pWbemServices);
  37. STDMETHODIMP FreeAbsoluteSD(SECURITY_DESCRIPTOR* pAbsoluteSD);
  38. STDMETHODIMP GetWbemServicesPtr( LPCWSTR, IWbemLocator**, IWbemServices** );
  39. };
  40. void
  41. InitializeSnapProv( void )
  42. {
  43. dbgRsop.Initialize( L"Software\\Microsoft\\Windows NT\\CurrentVersion\\winlogon",
  44. L"RsopDebugLevel",
  45. L"userenv.log",
  46. L"userenv.bak",
  47. FALSE );
  48. }
  49. extern "C"
  50. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
  51. {
  52. if (rclsid != CLSID_CSnapProv)
  53. {
  54. return CLASS_E_CLASSNOTAVAILABLE;
  55. }
  56. CProvFactory* pFactory = new CProvFactory();
  57. if (pFactory == NULL)
  58. {
  59. return E_OUTOFMEMORY;
  60. }
  61. HRESULT hRes = pFactory->QueryInterface(riid, ppv);
  62. pFactory->Release();
  63. return hRes;
  64. }
  65. extern "C"
  66. STDAPI DllCanUnloadNow()
  67. {
  68. // It is OK to unload if there are no objects or locks on the class factory.
  69. if( g_cObj == 0L && g_cLock == 0L )
  70. {
  71. return S_OK;
  72. }
  73. else
  74. {
  75. return S_FALSE;
  76. }
  77. }
  78. extern "C"
  79. STDAPI DllRegisterServer(void)
  80. {
  81. wchar_t szID[128];
  82. wchar_t szCLSID[128];
  83. wchar_t szModule[MAX_PATH];
  84. wchar_t* pName = L"Rsop Logging Mode Provider";
  85. wchar_t* pModel = L"Both";
  86. HRESULT hr = S_OK;
  87. HKEY hKey1, hKey2;
  88. DWORD dwError = ERROR_SUCCESS;
  89. // Create the path.
  90. GuidToString( &CLSID_CSnapProv, szID );
  91. hr = StringCchCopy(szCLSID, ARRAYSIZE(szCLSID), TEXT("CLSID\\"));
  92. if(FAILED(hr))
  93. return hr;
  94. hr = StringCchCat(szCLSID, ARRAYSIZE(szCLSID), szID);
  95. if(FAILED(hr))
  96. return hr;
  97. // Create entries under CLSID
  98. dwError = RegCreateKey(HKEY_CLASSES_ROOT, szCLSID, &hKey1); // Fixing bug 571328, i.e, checking return values
  99. if (dwError != ERROR_SUCCESS)
  100. {
  101. return HRESULT_FROM_WIN32(dwError);
  102. }
  103. dwError = RegSetValueEx(hKey1, NULL, 0, REG_SZ, (BYTE*)pName, (wcslen(pName) + 1) * sizeof(wchar_t));
  104. if (dwError != ERROR_SUCCESS)
  105. {
  106. RegCloseKey(hKey1);
  107. return HRESULT_FROM_WIN32(dwError);
  108. }
  109. dwError = RegCreateKey(hKey1, L"InprocServer32", &hKey2);
  110. if (dwError != ERROR_SUCCESS)
  111. {
  112. RegCloseKey(hKey1);
  113. return HRESULT_FROM_WIN32(dwError);
  114. }
  115. GetModuleFileName(g_hDllInstance, szModule, MAX_PATH);
  116. dwError = RegSetValueEx(hKey2, NULL, 0, REG_SZ, (BYTE*)szModule, (wcslen(szModule) + 1) * sizeof(wchar_t));
  117. if (dwError != ERROR_SUCCESS)
  118. {
  119. RegCloseKey(hKey2);
  120. RegCloseKey(hKey1);
  121. return HRESULT_FROM_WIN32(dwError);
  122. }
  123. dwError = RegSetValueEx(hKey2, L"ThreadingModel", 0, REG_SZ, (BYTE*)pModel, (wcslen(pModel) + 1) * sizeof(wchar_t));
  124. if (dwError != ERROR_SUCCESS)
  125. {
  126. RegCloseKey(hKey2);
  127. RegCloseKey(hKey1);
  128. return HRESULT_FROM_WIN32(dwError);
  129. }
  130. RegCloseKey(hKey2);
  131. RegCloseKey(hKey1);
  132. return S_OK;
  133. }
  134. extern "C"
  135. STDAPI DllUnregisterServer(void)
  136. {
  137. wchar_t szID[128];
  138. const DWORD dwCLSIDLength = 128;
  139. wchar_t szCLSID[dwCLSIDLength];
  140. HKEY hKey;
  141. HRESULT hr = S_OK;
  142. // Create the path using the CLSID
  143. GuidToString( &CLSID_CSnapProv, szID );
  144. hr = StringCchCopy(szCLSID, dwCLSIDLength, TEXT("CLSID\\"));
  145. if(FAILED(hr))
  146. return hr;
  147. hr = StringCchCat(szCLSID, dwCLSIDLength, szID);
  148. if(FAILED(hr))
  149. return hr;
  150. // First delete the InProcServer subkey.
  151. DWORD dwRet = RegOpenKey(HKEY_CLASSES_ROOT, szCLSID, &hKey);
  152. if(dwRet == ERROR_SUCCESS)
  153. {
  154. RegDeleteKey(hKey, L"InProcServer32");
  155. CloseHandle(hKey);
  156. }
  157. dwRet = RegOpenKey(HKEY_CLASSES_ROOT, L"CLSID", &hKey);
  158. if(dwRet == ERROR_SUCCESS)
  159. {
  160. RegDeleteKey(hKey,szID);
  161. CloseHandle(hKey);
  162. }
  163. return S_OK;
  164. }
  165. BOOL RunningOnWow64()
  166. {
  167. #if defined(_WIN64)
  168. // 64bit builds don't run in Wow64
  169. return false;
  170. #else
  171. // OS version
  172. OSVERSIONINFO osviVersion;
  173. osviVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  174. if (!GetVersionEx(&osviVersion)) {
  175. DebugMsg((DM_WARNING, TEXT("RunningOnWow64: Couldn't detect Version with error %d"), GetLastError()));
  176. return FALSE;
  177. }
  178. // on NT5 or later 32bit build. Check for 64 bit OS
  179. if ((osviVersion.dwPlatformId == VER_PLATFORM_WIN32_NT) &&
  180. (osviVersion.dwMajorVersion >= 5))
  181. {
  182. // QueryInformation for ProcessWow64Information returns a pointer to the Wow Info.
  183. // if running native, it returns NULL.
  184. PVOID pWow64Info = 0;
  185. if (NT_SUCCESS(NtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information, &pWow64Info, sizeof(pWow64Info), NULL))
  186. && pWow64Info != NULL)
  187. {
  188. // running 32bit on Wow64.
  189. return TRUE;
  190. }
  191. }
  192. return FALSE;
  193. #endif
  194. }
  195. HRESULT
  196. CompileMOF( LPCWSTR szMOFFile, LPCWSTR szMFLFile )
  197. {
  198. WCHAR szNamespace[MAX_PATH];
  199. BOOL bUpgrade = FALSE;
  200. HRESULT hr;
  201. XInterface<IWbemLocator> xWbemLocator;
  202. XInterface<IWbemServices> xWbemServicesOld;
  203. DWORD dwCurrentVersion= 0;
  204. DWORD dwNewVersion = RSOP_MOF_SCHEMA_VERSION;
  205. //
  206. // On wow64 do nothing
  207. //
  208. if (RunningOnWow64()) {
  209. DebugMsg((DM_VERBOSE, TEXT("CompileMof: Running on Wow64. returning without doing anything")));
  210. return S_OK;
  211. }
  212. if ( !szMOFFile )
  213. {
  214. return E_POINTER;
  215. }
  216. hr = StringCchCopy(szNamespace, MAX_PATH, RSOP_NS_ROOT);
  217. if(FAILED(hr))
  218. return hr;
  219. //
  220. // Get the wbem services pointer to the machine namespace
  221. //
  222. hr = GetWbemServicesPtr(RSOP_NS_MACHINE,
  223. &xWbemLocator,
  224. &xWbemServicesOld );
  225. if (!xWbemLocator) {
  226. DebugMsg((DM_WARNING, TEXT("CompileMof: Failed to get IWbemLocator pointer.Error 0x%x"), hr));
  227. return hr;
  228. }
  229. if ( (SUCCEEDED(hr)) && (xWbemServicesOld)) {
  230. hr = GetRsopSchemaVersionNumber(xWbemServicesOld, &dwCurrentVersion);
  231. if (FAILED(hr)) {
  232. return hr;
  233. }
  234. }
  235. if (HIWORD(dwCurrentVersion) != HIWORD(dwNewVersion)) {
  236. //
  237. // We should cleanout the schema and recreate below
  238. //
  239. DebugMsg((DM_VERBOSE, TEXT("CompileMof: Major version schema upgrade detected. Deleting rsop namespace and rebuilding")));
  240. xWbemServicesOld = NULL;
  241. hr = DeleteRsopNameSpace(szNamespace, xWbemLocator);
  242. if (FAILED(hr)) {
  243. DebugMsg((DM_WARNING, TEXT("CompileMof: Failed to get delete the rsop namespace. Error 0x%x. Continuing.."), hr));
  244. }
  245. //
  246. // Delete the state info on the machine
  247. //
  248. if (RegDelnode(HKEY_LOCAL_MACHINE, GP_STATE_ROOT_KEY) != ERROR_SUCCESS) {
  249. DebugMsg((DM_WARNING, TEXT("CompileMof: Failed to delete the state key. Continuing..")));
  250. }
  251. bUpgrade = FALSE;
  252. }
  253. else {
  254. bUpgrade = TRUE;
  255. }
  256. XInterface<IMofCompiler> xpMofCompiler;
  257. //
  258. // get a handle to IMofCompiler
  259. //
  260. hr = CoCreateInstance( CLSID_MofCompiler,
  261. 0,
  262. CLSCTX_INPROC_SERVER,
  263. IID_IMofCompiler,
  264. (LPVOID*) &xpMofCompiler );
  265. if ( FAILED(hr) )
  266. {
  267. DebugMsg((DM_WARNING, L"CompileMOF: CoCreateInstance() failed, 0x%X.", hr));
  268. return hr;
  269. }
  270. WBEM_COMPILE_STATUS_INFO Info;
  271. hr = xpMofCompiler->CompileFile((LPWSTR)szMOFFile,
  272. 0, // no server & namespace
  273. 0, // no user
  274. 0, // no authority
  275. 0, // no password
  276. 0, // no options
  277. 0, // no class flags
  278. 0, // no instance flags
  279. &Info );
  280. if ( FAILED( hr ) )
  281. {
  282. DebugMsg((DM_WARNING, L"CompileMOF: IMofCompiler::CompileFile() failed, 0x%X.", hr));
  283. }
  284. else
  285. {
  286. if (hr != S_OK )
  287. {
  288. DebugMsg((DM_WARNING, L"CompileMOF: IMofCompiler::CompileFile() returned with 0x%X.", hr));
  289. DebugMsg((DM_WARNING, L"CompileMOF: Details - lPhaseError - %d, hRes = 0x%x, ObjectNum - %d, firstline - %d, LastLine - %d",
  290. Info.lPhaseError, Info.hRes, Info.ObjectNum, Info.FirstLine, Info.LastLine ));
  291. }
  292. else
  293. {
  294. hr = xpMofCompiler->CompileFile((LPWSTR)szMFLFile,
  295. 0, // no server & namespace
  296. 0, // no user
  297. 0, // no authority
  298. 0, // no password
  299. 0, // no options
  300. 0, // no class flags
  301. 0, // no instance flags
  302. &Info );
  303. if ( FAILED( hr ) )
  304. {
  305. DebugMsg((DM_WARNING, L"CompileMOF: IMofCompiler::CompileFile() failed, 0x%X.", hr));
  306. }
  307. else
  308. {
  309. if (hr != S_OK )
  310. {
  311. DebugMsg((DM_WARNING, L"CompileMOF: IMofCompiler::CompileFile() returned with 0x%X.", hr));
  312. DebugMsg((DM_WARNING, L"CompileMOF: Details - lPhaseError - %d, hRes = 0x%x, ObjectNum - %d, firstline - %d, LastLine - %d",
  313. Info.lPhaseError, Info.hRes, Info.ObjectNum, Info.FirstLine, Info.LastLine ));
  314. }
  315. }
  316. }
  317. }
  318. //
  319. // There are 2 reasons we are doing this always.
  320. // 1. We had put AUthUsers:R permission in XP and we want to
  321. // get rid of those permissions
  322. // 2. Seems like it is better to secure it to OS level permissions
  323. // on each upgrade.
  324. //
  325. XPtrLF<SECURITY_DESCRIPTOR> xsd;
  326. SECURITY_ATTRIBUTES sa;
  327. CSecDesc Csd;
  328. Csd.AddLocalSystem(RSOP_ALL_PERMS, CONTAINER_INHERIT_ACE);
  329. Csd.AddAdministrators(RSOP_ALL_PERMS, CONTAINER_INHERIT_ACE);
  330. Csd.AddNetworkService(RSOP_ALL_PERMS, CONTAINER_INHERIT_ACE);
  331. Csd.AddAdministratorsAsOwner();
  332. Csd.AddAdministratorsAsGroup();
  333. DebugMsg((DM_VERBOSE, L"CompileMOF: Setting permissions on RSoP namespaces"));
  334. xsd = Csd.MakeSelfRelativeSD();
  335. if (!xsd) {
  336. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("CompileMOF::MakeSelfSD failed with %d"), GetLastError());
  337. return HRESULT_FROM_WIN32(GetLastError());
  338. }
  339. if (!SetSecurityDescriptorControl( (SECURITY_DESCRIPTOR *)xsd, SE_DACL_PROTECTED, SE_DACL_PROTECTED )) {
  340. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("CompileMOF::SetSecurityDescriptorControl failed with %d"), GetLastError());
  341. return HRESULT_FROM_WIN32(GetLastError());
  342. }
  343. hr = SetNameSpaceSecurity(RSOP_NS_USER, xsd, xWbemLocator);
  344. if (FAILED(hr)) {
  345. DebugMsg((DM_WARNING, L"CompileMOF: SetNamespaceSecurity() failed, 0x%X.", hr));
  346. return hr;
  347. }
  348. hr = SetNameSpaceSecurity(RSOP_NS_MACHINE, xsd, xWbemLocator);
  349. if (FAILED(hr)) {
  350. DebugMsg((DM_WARNING, L"CompileMOF: SetNamespaceSecurity() failed, 0x%X.", hr));
  351. return hr;
  352. }
  353. //
  354. // AUthenticated users need to make method calls at the root.
  355. // Give them the ability to do that below.
  356. //
  357. Csd.AddAuthUsers(WBEM_ENABLE |
  358. WBEM_METHOD_EXECUTE |
  359. WBEM_REMOTE_ACCESS); // no inheritance
  360. xsd = NULL; // free up the structure already allocated
  361. xsd = Csd.MakeSelfRelativeSD();
  362. if (!xsd) {
  363. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("CompileMOF::MakeSelfSD failed with %d"), GetLastError());
  364. return HRESULT_FROM_WIN32(GetLastError());
  365. }
  366. if (!SetSecurityDescriptorControl( (SECURITY_DESCRIPTOR *)xsd, SE_DACL_PROTECTED, SE_DACL_PROTECTED )) {
  367. dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("CompileMOF::SetSecurityDescriptorControl failed with %d"), GetLastError());
  368. return HRESULT_FROM_WIN32(GetLastError());
  369. }
  370. hr = SetNameSpaceSecurity(RSOP_NS_ROOT, xsd, xWbemLocator);
  371. if (FAILED(hr)) {
  372. DebugMsg((DM_WARNING, L"CompileMOF: SetNamespaceSecurity() failed, 0x%X.", hr));
  373. return hr;
  374. }
  375. return hr;
  376. }
  377. //
  378. // currently this code is intended to be called by regsvr32.
  379. // setup does not call this code.
  380. // "regsvr32 /n /i userenv.dll"
  381. // waiting for WMI gives us a mechanism to install our MOF at setup time.
  382. //
  383. extern "C"
  384. STDAPI DllInstall( BOOL, LPCWSTR )
  385. {
  386. HRESULT hr = S_OK;
  387. WCHAR szMofFile[MAX_PATH];
  388. WCHAR szMflFile[MAX_PATH];
  389. if ( GetSystemDirectory( szMofFile, MAX_PATH ) )
  390. {
  391. hr = StringCchCopy( szMflFile, MAX_PATH, szMofFile );
  392. if(FAILED(hr))
  393. return hr;
  394. LPWSTR szMOF = CheckSlash(szMofFile);
  395. LPWSTR szMFL = CheckSlash(szMflFile);
  396. hr = StringCchCat( szMOF, MAX_PATH - (szMOF - szMofFile), L"Wbem\\RSoP.mof" );
  397. if(FAILED(hr))
  398. return hr;
  399. hr = StringCchCat( szMFL, MAX_PATH - (szMFL - szMflFile), L"Wbem\\RSoP.mfl" );
  400. if(FAILED(hr))
  401. return hr;
  402. hr = CompileMOF( szMofFile, szMflFile );
  403. }
  404. else
  405. {
  406. hr = GetLastError();
  407. }
  408. return hr;
  409. }