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.

633 lines
18 KiB

  1. //***************************************************************************
  2. //
  3. // MAINDLL.CPP
  4. //
  5. // Module: WMI Framework Instance provider
  6. //
  7. // Purpose: Contains DLL entry points. Also has code that controls
  8. // when the DLL can be unloaded by tracking the number of
  9. // objects and locks as well as routines that support
  10. // self registration.
  11. //
  12. // Copyright (c)1999 Microsoft Corporation, All Rights Reserved
  13. //
  14. //***************************************************************************
  15. //
  16. // need this to access older WMI methods
  17. // BUGBUG - better alternative is to change the params
  18. // to use the new methods
  19. //
  20. #define FRAMEWORK_ALLOW_DEPRECATED 0
  21. #include "stdafx.h"
  22. #include <FWcommon.h>
  23. #include <objbase.h>
  24. #include <initguid.h>
  25. #include <wbemidl.h>
  26. #include <setupbat.h>
  27. #include "diskcleanup.h"
  28. #include "..\rstrcore\resource.h"
  29. #ifdef THIS_FILE
  30. #undef THIS_FILE
  31. #endif
  32. static char __szTraceSourceFile[] = __FILE__;
  33. #define THIS_FILE __szTraceSourceFile
  34. void UnattendedFileParameters ();
  35. HMODULE ghModule;
  36. //============
  37. WCHAR *GUIDSTRING = L"{a47401f6-a8a6-40ea-9c29-b8f6026c98b8}";
  38. CLSID CLSID_SYSTEMRESTORE = {0xa47401f6, 0xa8a6, 0x40ea,
  39. {0x9c, 0x29, 0xb8, 0xf6, 0x02, 0x6c, 0x98, 0xb8}} ;
  40. WCHAR *GUID_SRDiskCleanup = L"{7325c922-bb81-47b0-8b2f-a5f8605e242f}";
  41. CLSID Clsid_SRDiskCleanup = {/*7325c922-bb81-47b0-8b2f-a5f8605e242f*/
  42. 0x7325c922,
  43. 0xbb81,
  44. 0x47b0,
  45. {0x8b, 0x2f, 0xa5, 0xf8, 0x60, 0x5e, 0x24, 0x2f}
  46. };
  47. //Count number of objects and number of locks.
  48. long g_cLock=0;
  49. //***************************************************************************
  50. //
  51. // DllGetClassObject
  52. //
  53. // Purpose: Called by Ole when some client wants a class factory. Return
  54. // one only if it is the sort of class this DLL supports.
  55. //
  56. //***************************************************************************
  57. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, PPVOID ppv)
  58. {
  59. HRESULT hr;
  60. if (CLSID_SYSTEMRESTORE == rclsid)
  61. {
  62. CWbemGlueFactory *pObj;
  63. pObj=new CWbemGlueFactory();
  64. if (NULL==pObj)
  65. return E_OUTOFMEMORY;
  66. hr=pObj->QueryInterface(riid, ppv);
  67. if (FAILED(hr))
  68. delete pObj;
  69. }
  70. else if (rclsid == Clsid_SRDiskCleanup)
  71. {
  72. CSRClassFactory *pcf = new CSRClassFactory ();
  73. if (pcf == NULL)
  74. return E_OUTOFMEMORY;
  75. hr = pcf->QueryInterface (riid, ppv);
  76. pcf->Release(); // release constructor refcount
  77. }
  78. else hr = E_FAIL;
  79. return hr;
  80. }
  81. //***************************************************************************
  82. //
  83. // DllCanUnloadNow
  84. //
  85. // Purpose: Called periodically by Ole in order to determine if the
  86. // DLL can be freed.
  87. //
  88. // Return: S_OK if there are no objects in use and the class factory
  89. // isn't locked.
  90. //
  91. //***************************************************************************
  92. STDAPI DllCanUnloadNow(void)
  93. {
  94. SCODE sc;
  95. // It is OK to unload if there are no objects or locks on the
  96. // class factory and the framework is done with you.
  97. if ((0L==g_cLock) && CWbemProviderGlue::FrameworkLogoffDLL(L"SYSTEMRESTORE"))
  98. {
  99. sc = S_OK;
  100. }
  101. else
  102. {
  103. sc = S_FALSE;
  104. }
  105. return sc;
  106. }
  107. //***************************************************************************
  108. //
  109. // Is4OrMore
  110. //
  111. // Returns true if win95 or any version of NT > 3.51
  112. //
  113. //***************************************************************************
  114. BOOL Is4OrMore(void)
  115. {
  116. OSVERSIONINFO os;
  117. os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  118. if(!GetVersionEx(&os))
  119. return FALSE; // should never happen
  120. return os.dwMajorVersion >= 4;
  121. }
  122. DWORD
  123. CopyMofFile()
  124. {
  125. TENTER("CopyMofFile");
  126. WCHAR szSrc[MAX_PATH];
  127. IMofCompiler *pimof = NULL;
  128. HRESULT hr;
  129. WBEM_COMPILE_STATUS_INFO Info;
  130. BOOL fInitialized = FALSE;
  131. hr = CoInitialize(NULL);
  132. if (FAILED(hr))
  133. {
  134. trace(0, "! CoInitialize : %ld", hr);
  135. goto done;
  136. }
  137. fInitialized = TRUE;
  138. //
  139. // create an IMofCompiler instance
  140. //
  141. hr = CoCreateInstance( CLSID_MofCompiler,
  142. 0,
  143. CLSCTX_INPROC_SERVER,
  144. IID_IMofCompiler,
  145. (LPVOID*) &pimof );
  146. if (FAILED(hr) || NULL == pimof)
  147. {
  148. trace(0, "! CoCreateInstance : %ld", hr);
  149. goto done;
  150. }
  151. //
  152. // get the path of the source mof file
  153. // %windir%\system32\restore\sr.mof
  154. //
  155. if (0 == ExpandEnvironmentStrings(s_cszWinRestDir, szSrc, MAX_PATH))
  156. {
  157. hr = (HRESULT) GetLastError();
  158. trace(0, "! ExpandEnvironmentStrings : %ld", hr);
  159. goto done;
  160. }
  161. lstrcat(szSrc, s_cszMofFile);
  162. //
  163. // compile the mof file
  164. //
  165. hr = pimof->CompileFile(szSrc,
  166. 0, // no server & namespace
  167. 0, // no user
  168. 0, // no authority
  169. 0, // no password
  170. 0, // no options
  171. 0, // no class flags
  172. 0, // no instance flags
  173. &Info );
  174. if (hr != S_OK)
  175. {
  176. trace(0, "! CompileFile : %ld", hr);
  177. goto done;
  178. }
  179. done:
  180. if (pimof)
  181. {
  182. pimof->Release();
  183. }
  184. if (fInitialized)
  185. CoUninitialize();
  186. TLEAVE();
  187. return hr;
  188. }
  189. //***************************************************************************
  190. //
  191. // DllRegisterServer
  192. //
  193. // Purpose: Called during setup or by regsvr32.
  194. //
  195. // Return: NOERROR if registration successful, error otherwise.
  196. //***************************************************************************
  197. STDAPI DllRegisterServer(void)
  198. {
  199. WCHAR wcID[128];
  200. WCHAR wcCLSID[128];
  201. WCHAR wcModule[MAX_PATH];
  202. WCHAR * pName = L"";
  203. WCHAR * pModel = L"Both";
  204. HKEY hKey1 = NULL, hKey2 = NULL, hKeySR = NULL;
  205. DWORD dwRc;
  206. // Create the path.
  207. lstrcpy(wcCLSID, L"SOFTWARE\\CLASSES\\CLSID\\");
  208. lstrcat(wcCLSID, GUIDSTRING);
  209. // Create entries under CLSID
  210. RegCreateKey(HKEY_LOCAL_MACHINE, wcCLSID, &hKey1);
  211. if (hKey1 != NULL)
  212. {
  213. RegSetValueEx(hKey1, NULL, 0, REG_SZ, (BYTE *)pName,
  214. (lstrlen(pName)+1) * sizeof(WCHAR));
  215. RegCreateKey(hKey1, L"InprocServer32",&hKey2);
  216. if (hKey2 != NULL)
  217. {
  218. GetModuleFileName(ghModule, wcModule, MAX_PATH);
  219. RegSetValueEx(hKey2, NULL, 0, REG_SZ, (BYTE *) wcModule,
  220. (lstrlen(wcModule)+1) * sizeof(WCHAR));
  221. RegSetValueEx(hKey2, L"ThreadingModel", 0, REG_SZ,
  222. (BYTE *)pModel, (lstrlen(pModel)+1) * sizeof(WCHAR));
  223. CloseHandle(hKey2);
  224. }
  225. CloseHandle(hKey1);
  226. }
  227. // copy the sr.mof file into the wbem directories
  228. // get the wbem directories from the registry
  229. // dwRc = CopyMofFile();
  230. lstrcpy(wcCLSID, L"SOFTWARE\\CLASSES\\CLSID\\");
  231. lstrcat(wcCLSID, GUID_SRDiskCleanup);
  232. RegCreateKey(HKEY_LOCAL_MACHINE, wcCLSID, &hKey1);
  233. if (hKey1 != NULL)
  234. {
  235. RegSetValueEx(hKey1, NULL, 0, REG_SZ, (BYTE *)pName,
  236. (lstrlen(pName)+1) * sizeof(WCHAR));
  237. RegCreateKey(hKey1, L"InprocServer32", &hKey2);
  238. if (hKey2 != NULL)
  239. {
  240. GetModuleFileName(ghModule, wcModule, MAX_PATH);
  241. RegSetValueEx(hKey2, NULL, 0, REG_SZ, (BYTE *) wcModule,
  242. (lstrlen(wcModule)+1) * sizeof(WCHAR));
  243. RegSetValueEx(hKey2, L"ThreadingModel", 0, REG_SZ,
  244. (BYTE *)pModel, (lstrlen(pModel)+1) * sizeof(WCHAR));
  245. CloseHandle(hKey2);
  246. }
  247. RegCreateKey(hKey1, L"DefaultIcon", &hKey2);
  248. if (hKey2 != NULL)
  249. {
  250. lstrcpy (wcModule, L"%SystemRoot%\\system32\\srclient.dll,0");
  251. RegSetValueEx(hKey2, NULL, 0, REG_EXPAND_SZ, (BYTE *) wcModule,
  252. (lstrlen(wcModule)+1) * sizeof(WCHAR));
  253. CloseHandle(hKey2);
  254. }
  255. CloseHandle(hKey1);
  256. }
  257. RegCreateKey(HKEY_LOCAL_MACHINE,
  258. L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\VolumeCaches"
  259. L"\\System Restore", &hKey1);
  260. if (hKey1 != NULL)
  261. {
  262. RegSetValueEx(hKey1, NULL, 0, REG_SZ, (BYTE *) GUID_SRDiskCleanup,
  263. (lstrlen(GUID_SRDiskCleanup)+1) * sizeof(WCHAR));
  264. }
  265. UnattendedFileParameters();
  266. return NOERROR;
  267. }
  268. //***************************************************************************
  269. //
  270. // DllUnregisterServer
  271. //
  272. // Purpose: Called when it is time to remove the registry entries.
  273. //
  274. // Return: NOERROR if registration successful, error otherwise.
  275. //***************************************************************************
  276. STDAPI DllUnregisterServer(void)
  277. {
  278. WCHAR wcID[128];
  279. WCHAR wcCLSID[128];
  280. HKEY hKey;
  281. // Create the path using the CLSID
  282. lstrcpy(wcCLSID, L"SOFTWARE\\CLASSES\\CLSID\\");
  283. lstrcat(wcCLSID, GUIDSTRING);
  284. // First delete the InProcServer subkey.
  285. DWORD dwRet = RegOpenKey(HKEY_LOCAL_MACHINE, wcCLSID, &hKey);
  286. if(dwRet == NO_ERROR)
  287. {
  288. RegDeleteKey(hKey, L"InProcServer32");
  289. CloseHandle(hKey);
  290. }
  291. lstrcpy(wcCLSID, L"SOFTWARE\\CLASSES\\CLSID\\");
  292. lstrcat(wcCLSID, GUID_SRDiskCleanup);
  293. dwRet = RegOpenKey(HKEY_LOCAL_MACHINE, wcCLSID, &hKey);
  294. if(dwRet == NO_ERROR)
  295. {
  296. RegDeleteKey(hKey, L"InProcServer32");
  297. RegDeleteKey(hKey, L"DefaultIcon");
  298. CloseHandle(hKey);
  299. }
  300. // then delete the clsid keys for both SystemRestoreProv and SRDiskCleanup
  301. dwRet = RegOpenKey(HKEY_LOCAL_MACHINE, L"SOFTWARE\\CLASSES\\CLSID\\", &hKey);
  302. if(dwRet == NO_ERROR)
  303. {
  304. RegDeleteKey(hKey, GUIDSTRING);
  305. RegDeleteKey(hKey, GUID_SRDiskCleanup);
  306. CloseHandle(hKey);
  307. }
  308. RegDeleteKey(HKEY_LOCAL_MACHINE,
  309. L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\VolumeCaches"
  310. L"\\System Restore");
  311. return NOERROR;
  312. }
  313. void UnattendedFileParameters ()
  314. {
  315. HKEY hKey = NULL;
  316. WCHAR * pwNull = L"";
  317. DWORD dwAnswerLength = MAX_PATH;
  318. LONG lAnswer = 0;
  319. WCHAR wcsAnswerFile [MAX_PATH];
  320. WCHAR wcsAnswer [MAX_PATH];
  321. if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, s_cszSRCfgRegKey, 0,
  322. KEY_WRITE, &hKey))
  323. return;
  324. if (0 == GetSystemDirectoryW (wcsAnswerFile,MAX_PATH))
  325. return;
  326. lstrcatW (wcsAnswerFile, L"\\");
  327. lstrcatW (wcsAnswerFile, WINNT_GUI_FILE_W);
  328. /*
  329. if( GetPrivateProfileString( s_cszSRUnattendedSection,
  330. L"MaximumDataStoreSize",
  331. pwNull,
  332. wcsAnswer,
  333. dwAnswerLength,
  334. wcsAnswerFile ) )
  335. {
  336. if( lstrcmpW (pwNull, wcsAnswer ))
  337. {
  338. lAnswer = wcstol (wcsAnswer,NULL,10);
  339. if (lAnswer > 0)
  340. RegWriteDWORD(hKey, s_cszDSMax, (DWORD *) &lAnswer);
  341. }
  342. }
  343. */
  344. if( GetPrivateProfileString( s_cszSRUnattendedSection,
  345. L"RestorePointLife",
  346. pwNull,
  347. wcsAnswer,
  348. dwAnswerLength,
  349. wcsAnswerFile ) )
  350. {
  351. if( lstrcmpW (pwNull, wcsAnswer ))
  352. {
  353. lAnswer = wcstol (wcsAnswer,NULL,10);
  354. lAnswer *= 24 * 3600; // convert days to seconds
  355. if (lAnswer > 0)
  356. RegWriteDWORD(hKey, s_cszRPLifeInterval, (DWORD *) &lAnswer);
  357. }
  358. }
  359. if( GetPrivateProfileString( s_cszSRUnattendedSection,
  360. L"CheckpointCalendarFrequency",
  361. pwNull,
  362. wcsAnswer,
  363. dwAnswerLength,
  364. wcsAnswerFile ) )
  365. {
  366. if( lstrcmpW (pwNull, wcsAnswer ))
  367. {
  368. lAnswer = wcstol (wcsAnswer,NULL,10);
  369. lAnswer *= 24 * 3600; // convert days to seconds
  370. if (lAnswer > 0)
  371. RegWriteDWORD(hKey, s_cszRPGlobalInterval, (DWORD *) &lAnswer);
  372. }
  373. }
  374. if( GetPrivateProfileString( s_cszSRUnattendedSection,
  375. L"CheckPointSessionFrequency",
  376. pwNull,
  377. wcsAnswer,
  378. dwAnswerLength,
  379. wcsAnswerFile ) )
  380. {
  381. if( lstrcmpW (pwNull, wcsAnswer ))
  382. {
  383. lAnswer = wcstol (wcsAnswer,NULL,10);
  384. lAnswer *= 3600; // convert hours to seconds
  385. if (lAnswer > 0)
  386. RegWriteDWORD(hKey, s_cszRPSessionInterval, (DWORD *) &lAnswer);
  387. }
  388. }
  389. if( GetPrivateProfileString( s_cszSRUnattendedSection,
  390. L"MaximumDataStorePercentOfDisk",
  391. pwNull,
  392. wcsAnswer,
  393. dwAnswerLength,
  394. wcsAnswerFile ) )
  395. {
  396. if( lstrcmpW (pwNull, wcsAnswer ))
  397. {
  398. lAnswer = wcstol (wcsAnswer,NULL,10);
  399. if (lAnswer <= 100 && lAnswer > 0)
  400. RegWriteDWORD(hKey, s_cszDiskPercent, (DWORD *) &lAnswer);
  401. }
  402. }
  403. RegCloseKey (hKey);
  404. return;
  405. }
  406. void CALLBACK
  407. CreateFirstRunRp(
  408. HWND hwnd,
  409. HINSTANCE hinst,
  410. LPSTR lpszCmdLine,
  411. int nCmdShow)
  412. {
  413. RESTOREPOINTINFO RPInfo;
  414. STATEMGRSTATUS SmgrStatus;
  415. DWORD dwValue;
  416. HANDLE hInit = NULL;
  417. //
  418. // first remove ourselves from Run key
  419. //
  420. HKEY hKey;
  421. DWORD dwRet = RegOpenKey(HKEY_LOCAL_MACHINE,
  422. L"Software\\Microsoft\\Windows\\CurrentVersion\\Run",
  423. &hKey);
  424. if (dwRet == ERROR_SUCCESS)
  425. {
  426. RegDeleteValue(hKey, L"SRFirstRun");
  427. RegCloseKey(hKey);
  428. }
  429. //
  430. // wait until the service has fully initialized
  431. // query thrice at 10 second intervals
  432. //
  433. dwRet = WAIT_FAILED;
  434. int i = 0;
  435. while (i++ <= 3)
  436. {
  437. hInit = OpenEvent(SYNCHRONIZE, FALSE, s_cszSRInitEvent);
  438. if (hInit == NULL)
  439. {
  440. if (i >= 3)
  441. {
  442. break;
  443. }
  444. Sleep(10000);
  445. }
  446. else
  447. {
  448. dwRet = WaitForSingleObject(hInit, 60*1000); // 1 minute
  449. break;
  450. }
  451. }
  452. //
  453. // reset registry value CreateFirstRunRp
  454. // so that service will create firstrun rp in the future
  455. //
  456. dwValue = 1;
  457. if (ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE,
  458. s_cszSRRegKey,
  459. &hKey))
  460. {
  461. RegWriteDWORD(hKey, s_cszCreateFirstRunRp, &dwValue);
  462. RegCloseKey(hKey);
  463. }
  464. //
  465. // try creating firstrun rp now
  466. //
  467. if (dwRet != WAIT_FAILED)
  468. {
  469. RPInfo.dwEventType = BEGIN_SYSTEM_CHANGE;
  470. RPInfo.dwRestorePtType = FIRSTRUN;
  471. if (ERROR_SUCCESS != SRLoadString(L"srrstr.dll", IDS_SYSTEM_CHECKPOINT_TEXT, RPInfo.szDescription, MAX_DESC_W))
  472. {
  473. lstrcpy(RPInfo.szDescription, s_cszSystemCheckpointName);
  474. }
  475. SRSetRestorePoint(&RPInfo, &SmgrStatus);
  476. }
  477. if (hInit)
  478. {
  479. CloseHandle(hInit);
  480. }
  481. return;
  482. }
  483. //***************************************************************************
  484. //
  485. // DllMain
  486. //
  487. // Purpose: Called by the operating system when processes and threads are
  488. // initialized and terminated, or upon calls to the LoadLibrary
  489. // and FreeLibrary functions
  490. //
  491. // Return: TRUE if load was successful, else FALSE
  492. //***************************************************************************
  493. BOOL APIENTRY DllMain ( HINSTANCE hInstDLL, // handle to dll module
  494. DWORD fdwReason, // reason for calling function
  495. LPVOID lpReserved ) // reserved
  496. {
  497. BOOL bRet = TRUE;
  498. // Perform actions based on the reason for calling.
  499. switch( fdwReason )
  500. {
  501. case DLL_PROCESS_ATTACH:
  502. DisableThreadLibraryCalls(hInstDLL);
  503. // Initialize once for each new process.
  504. // Return FALSE to fail DLL load.
  505. ghModule = hInstDLL;
  506. bRet = CWbemProviderGlue::FrameworkLoginDLL(L"SYSTEMRESTORE");
  507. break;
  508. case DLL_THREAD_ATTACH:
  509. // Do thread-specific initialization.
  510. break;
  511. case DLL_THREAD_DETACH:
  512. // Do thread-specific cleanup.
  513. break;
  514. case DLL_PROCESS_DETACH:
  515. // Perform any necessary cleanup.
  516. break;
  517. }
  518. return bRet; // Sstatus of DLL_PROCESS_ATTACH.
  519. }