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.

1255 lines
36 KiB

  1. /********************************************************************
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. rpcstest.cpp
  5. Abstract:
  6. This file is a unit test for the SFP client api
  7. Revision History:
  8. Brijesh Krishnaswami (brijeshk) - 06/29/99 - Created
  9. ********************************************************************/
  10. #include <nt.h>
  11. #include <ntrtl.h>
  12. #include <nturtl.h>
  13. #include <windows.h>
  14. #include <windows.h>
  15. #include <shellapi.h>
  16. #include <dbgtrace.h>
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include "srrestoreptapi.h"
  20. #include "srrpcapi.h"
  21. #include "utils.h"
  22. #include "srapi.h"
  23. #include "wintrust.h"
  24. #include "softpub.h"
  25. #include "mscat.h"
  26. #include "shlwapi.h"
  27. void
  28. PrintUsage()
  29. {
  30. printf("Usage: rpctest <option>");
  31. printf("\n 1 = EnableSR <volumename>");
  32. printf("\n 2 = DisableSR <volumename>");
  33. printf("\n 3 = EnableFIFO");
  34. printf("\n 4 = DisableFIFO <seqnum>");
  35. printf("\n 5 = SRSetRestorePoint [Description] [Rptype] [EvtType] [SeqNum]");
  36. printf("\n 6 = SRRemoveRestorePoint <seqnum>");
  37. printf("\n 7 = SRUpdateMonitoredList <filepath>");
  38. printf("\n 8 = SRFifo <volumename> <targetpercent>");
  39. printf("\n 9 = SRFifo <volumename> <targetpercent> -- fifo atleast one rp");
  40. printf("\n 10 = SRFifo <volumename> <targetRPNum> -- include current rp");
  41. printf("\n 11 = SRFifo <volumename> <targetRPNum> -- exclude current rp");
  42. printf("\n 12 = SRFreeze <volumename>");
  43. printf("\n 13 = SRCompress <volumename>");
  44. printf("\n 14 = SRNotify <volumename> <freespace> <direction=1/0>");
  45. printf("\n 15 = Start/Stop Filter <1/0>");
  46. printf("\n 16 = ResetSR <volumename>");
  47. printf("\n 17 = SRUpdateDSSize <volumename> <newsize>");
  48. printf("\n 18 = SRSwitchLog");
  49. printf("\n 19 = AddCatalogToCryptoDB <catfilename> <fullpath>");
  50. printf("\n 20 = RemoveCatalogFromCryptoDB <catfilename>");
  51. printf("\n 21 = SRPrintState -- dump state to %%windir%%\\temp\\sr.txt and debugger");
  52. printf("\n 22 = TestDriveRestore <oldsystemhivepath>");
  53. printf("\n 25 = SRRegisterSnapshotCallback <dllfullpath>");
  54. printf("\n 26 = SRUnregisterSnapshotCallback <dllfullpath>");
  55. printf("\n 27 = EnableSREx <volumename> <fWait>");
  56. printf("\n<volumename> must be specified as \"C:\\\" etc.");
  57. }
  58. // this calls the Crypto API to add a catalog to the Crypto DB
  59. DWORD
  60. AddCatalogToCryptoDB(LPCWSTR pszCatName, LPCWSTR pszCatPath)
  61. {
  62. DWORD dwErr = ERROR_SUCCESS;
  63. HCATADMIN hCatAdmin = NULL;
  64. HCATINFO hCatInfo = NULL;
  65. GUID DriverVerifyGuid = DRIVER_ACTION_VERIFY;
  66. TraceFunctEnter("AddCatalogToCryptoDB");
  67. if (!CryptCATAdminAcquireContext(&hCatAdmin, &DriverVerifyGuid, 0))
  68. {
  69. dwErr = GetLastError();
  70. ErrorTrace(0, "CryptCATAdminAcquireContext() failed, ec=%d",
  71. dwErr);
  72. goto Err;
  73. }
  74. hCatInfo= CryptCATAdminAddCatalog(hCatAdmin,
  75. (LPWSTR) pszCatPath, // path of the temp cat file
  76. (LPWSTR) pszCatName, // name of the cat file
  77. 0); // No Flags
  78. if (NULL == hCatInfo)
  79. {
  80. dwErr = GetLastError();
  81. DebugTrace(0, "CryptCATAdminAddCatalog() failed, ec=%d",
  82. dwErr);
  83. goto Err;
  84. }
  85. Err:
  86. if (NULL != hCatInfo)
  87. {
  88. CryptCATAdminReleaseCatalogContext(hCatAdmin,
  89. hCatInfo,
  90. 0); // no flags
  91. }
  92. if (NULL != hCatAdmin)
  93. {
  94. CryptCATAdminReleaseContext(hCatAdmin,
  95. 0); // no flags
  96. }
  97. TraceFunctLeave();
  98. return dwErr;
  99. }
  100. // this calls the Crypto API to remove a catalog from the Crypto DB
  101. DWORD
  102. RemoveCatalogFromCryptoDB(LPCWSTR pszCatName)
  103. {
  104. DWORD dwErr = ERROR_SUCCESS;
  105. HCATADMIN hCatAdmin = NULL;
  106. HCATINFO hCatInfo = NULL;
  107. GUID DriverVerifyGuid = DRIVER_ACTION_VERIFY;
  108. TraceFunctEnter("RemoveCatalogFromCryptoDB");
  109. if (!CryptCATAdminAcquireContext(&hCatAdmin, &DriverVerifyGuid, 0))
  110. {
  111. dwErr = GetLastError();
  112. ErrorTrace(0, "CryptCATAdminAcquireContext() failed, ec=%d",
  113. dwErr);
  114. goto Err;
  115. }
  116. if (FALSE == CryptCATAdminRemoveCatalog(hCatAdmin,
  117. (LPWSTR) pszCatName,
  118. 0)) // No Flags
  119. {
  120. dwErr = GetLastError();
  121. DebugTrace(0, "CryptCATAdminRemoveCatalog() failed, ec=%d",
  122. dwErr);
  123. goto Err;
  124. }
  125. Err:
  126. if (NULL != hCatAdmin)
  127. {
  128. CryptCATAdminReleaseContext(hCatAdmin,
  129. 0); // no flags
  130. }
  131. TraceFunctLeave();
  132. return dwErr;
  133. }
  134. #define VALIDATE_DWRET(str) \
  135. if ( dwRet != ERROR_SUCCESS ) \
  136. { \
  137. ErrorTrace(0, "failed - %ld", dwRet); \
  138. goto done; \
  139. } \
  140. DWORD
  141. FindDriveMapping(HKEY hk, LPBYTE pSig, DWORD dwSig, LPWSTR pszDrive)
  142. {
  143. DWORD dwIndex = 0;
  144. DWORD dwRet = ERROR_SUCCESS;
  145. DWORD dwType, dwSize = MAX_PATH;
  146. BYTE rgbSig[1024];
  147. DWORD cbSig = sizeof(rgbSig);
  148. LPCWSTR cszErr;
  149. TENTER("FindDriveMapping");
  150. while (ERROR_SUCCESS ==
  151. (dwRet = RegEnumValue( hk,
  152. dwIndex++,
  153. pszDrive,
  154. &dwSize,
  155. NULL,
  156. &dwType,
  157. rgbSig,
  158. &cbSig )))
  159. {
  160. if (0 == wcsncmp(pszDrive, L"\\DosDevice", 10))
  161. {
  162. if (cbSig == dwSig &&
  163. (0 == memcmp(rgbSig, pSig, cbSig)))
  164. break;
  165. }
  166. dwSize = MAX_PATH;
  167. cbSig = sizeof(rgbSig);
  168. }
  169. TLEAVE();
  170. return dwRet;
  171. }
  172. DWORD
  173. KeepMountedDevices(HKEY hkMount)
  174. {
  175. HKEY hkNew = NULL, hkOld = NULL;
  176. DWORD dwIndex = 0;
  177. WCHAR szValue[MAX_PATH], szDrive[MAX_PATH];
  178. BYTE rgbSig[1024];
  179. DWORD cbSig;
  180. DWORD dwSize, dwType;
  181. DWORD dwRet = ERROR_SUCCESS;
  182. LPCWSTR cszErr;
  183. TENTER("KeepMountedDevices");
  184. //
  185. // open the old and new MountedDevices
  186. //
  187. dwRet = ::RegOpenKey( hkMount, L"MountedDevices", &hkOld );
  188. VALIDATE_DWRET("::RegOpenKey");
  189. dwRet = ::RegOpenKey( HKEY_LOCAL_MACHINE, L"System\\MountedDevices", &hkNew );
  190. VALIDATE_DWRET("::RegOpenKey");
  191. //
  192. // enumerate the old devices
  193. // delete volumes that don't exist in the new (i.e. current)
  194. //
  195. dwSize = MAX_PATH;
  196. cbSig = sizeof(rgbSig);
  197. while (ERROR_SUCCESS ==
  198. (dwRet = RegEnumValue( hkOld,
  199. dwIndex++,
  200. szValue,
  201. &dwSize,
  202. NULL,
  203. &dwType,
  204. rgbSig,
  205. &cbSig )))
  206. {
  207. if (0 == wcsncmp(szValue, L"\\??\\Volume", 10))
  208. {
  209. //
  210. // this is a Volume -> Signature mapping
  211. // check if the volume exists in the new
  212. //
  213. trace(0, "Old Volume = %S", szValue);
  214. dwSize = sizeof(rgbSig);
  215. dwRet = RegQueryValueEx(hkNew,
  216. szValue,
  217. NULL,
  218. &dwType,
  219. rgbSig,
  220. &dwSize);
  221. if (ERROR_SUCCESS != dwRet)
  222. {
  223. //
  224. // nope
  225. // so delete the volume and driveletter mapping from old
  226. //
  227. DWORD dwSave = FindDriveMapping(hkOld, rgbSig, cbSig, szDrive);
  228. dwRet = RegDeleteValue(hkOld, szValue);
  229. VALIDATE_DWRET("RegDeleteValue");
  230. if (dwSave == ERROR_SUCCESS)
  231. {
  232. dwIndex--; // hack to make RegEnumValueEx work
  233. dwRet = RegDeleteValue(hkOld, szDrive);
  234. VALIDATE_DWRET("RegDeleteValue");
  235. }
  236. trace(0, "Deleted old volume");
  237. }
  238. }
  239. else if (szValue[0] == L'#')
  240. {
  241. trace(0, "Old Mountpoint = %S", szValue);
  242. }
  243. else if (0 == wcsncmp(szValue, L"\\DosDevice", 10))
  244. {
  245. trace(0, "Old Drive = %S", szValue);
  246. }
  247. else
  248. {
  249. trace(0, "Old Unknown = %S", szValue);
  250. }
  251. dwSize = MAX_PATH;
  252. cbSig = sizeof(rgbSig);
  253. }
  254. if (dwRet != ERROR_NO_MORE_ITEMS)
  255. VALIDATE_DWRET("::RegEnumValue");
  256. //
  257. // now enumerate the current (new) devices
  258. //
  259. dwIndex = 0;
  260. dwSize = MAX_PATH;
  261. cbSig = sizeof(rgbSig);
  262. while (ERROR_SUCCESS ==
  263. (dwRet = RegEnumValue( hkNew,
  264. dwIndex++,
  265. szValue,
  266. &dwSize,
  267. NULL,
  268. &dwType,
  269. rgbSig,
  270. &cbSig )))
  271. {
  272. if (0 == wcsncmp(szValue, L"\\??\\Volume", 10))
  273. {
  274. //
  275. // this is a Volume -> Signature mapping
  276. // copy the new volume to the old
  277. //
  278. trace(0, "New Volume = %S", szValue);
  279. DWORD dwSave = FindDriveMapping(hkOld, rgbSig, cbSig, szDrive);
  280. dwRet = RegSetValueEx(hkOld,
  281. szValue,
  282. NULL,
  283. REG_BINARY,
  284. rgbSig,
  285. cbSig);
  286. VALIDATE_DWRET("::RegSetValueEx");
  287. if (dwSave == ERROR_NO_MORE_ITEMS)
  288. {
  289. //
  290. // there is no driveletter for this volume in the old registry
  291. // so copy the new one to the old if it exists
  292. //
  293. if (ERROR_SUCCESS ==
  294. FindDriveMapping(hkNew, rgbSig, cbSig, szDrive))
  295. {
  296. dwRet = RegSetValueEx(hkOld,
  297. szDrive,
  298. NULL,
  299. REG_BINARY,
  300. rgbSig,
  301. cbSig);
  302. VALIDATE_DWRET("::RegSetValueEx");
  303. trace(0, "Copied new driveletter %S to old", szDrive);
  304. }
  305. }
  306. else
  307. {
  308. //
  309. // preserve the old driveletter
  310. //
  311. trace(0, "Preserving old driveletter %S", szDrive);
  312. }
  313. }
  314. else if (szValue[0] == L'#')
  315. {
  316. //
  317. // this is a mountpoint specification
  318. // BUGBUG - mount points should be restored
  319. // so don't bother about these ?
  320. //
  321. trace(0, "New Mountpoint = %S", szValue);
  322. }
  323. else if (0 == wcsncmp(szValue, L"\\DosDevice", 10))
  324. {
  325. //
  326. // this is a Driveletter -> Signature mapping
  327. // don't touch these
  328. //
  329. trace(0, "New Drive = %S", szValue);
  330. }
  331. else
  332. {
  333. trace(0, "New Unknown = %S", szValue);
  334. }
  335. dwSize = MAX_PATH;
  336. cbSig = sizeof(rgbSig);
  337. }
  338. if (dwRet == ERROR_NO_MORE_ITEMS)
  339. dwRet = ERROR_SUCCESS;
  340. VALIDATE_DWRET("::RegEnumValue");
  341. done:
  342. if (hkOld)
  343. RegCloseKey(hkOld);
  344. if (hkNew)
  345. RegCloseKey(hkNew);
  346. TLEAVE();
  347. return dwRet;
  348. }
  349. LPCWSTR GetSysErrStr( )
  350. {
  351. TraceFunctEnter("GetSysErrStr(DWORD)");
  352. static WCHAR szErr[1024+1];
  353. DWORD dwErr = GetLastError();
  354. ::FormatMessage(
  355. FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
  356. NULL,
  357. dwErr,
  358. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  359. szErr,
  360. 1024,
  361. NULL );
  362. TraceFunctLeave();
  363. return( szErr );
  364. }
  365. BOOL
  366. CheckPrivilege( LPCWSTR szPriv, BOOL fCheckOnly )
  367. {
  368. TraceFunctEnter("CheckPrivilege");
  369. BOOL fRet = FALSE;
  370. LPCWSTR cszErr;
  371. HANDLE hToken = NULL;
  372. LUID luid;
  373. TOKEN_PRIVILEGES tpNew;
  374. TOKEN_PRIVILEGES tpOld;
  375. DWORD dwRes;
  376. // Prepare Process Token
  377. if ( !::OpenProcessToken( ::GetCurrentProcess(),
  378. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
  379. &hToken ) )
  380. {
  381. cszErr = ::GetSysErrStr();
  382. ErrorTrace(0, "::OpenProcessToken failed - %ls", cszErr);
  383. goto Exit;
  384. }
  385. // Get Luid
  386. if ( !::LookupPrivilegeValue( NULL, szPriv, &luid ) )
  387. {
  388. cszErr = ::GetSysErrStr();
  389. ErrorTrace(0, "::LookupPrivilegeValue failed - %ls", cszErr);
  390. goto Exit;
  391. }
  392. // Try to enable the privilege
  393. tpNew.PrivilegeCount = 1;
  394. tpNew.Privileges[0].Luid = luid;
  395. tpNew.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  396. if ( !::AdjustTokenPrivileges( hToken, FALSE, &tpNew, sizeof(tpNew), &tpOld, &dwRes ) )
  397. {
  398. cszErr = ::GetSysErrStr();
  399. ErrorTrace(0, "::AdjustTokenPrivileges(ENABLE) failed - %ls", cszErr);
  400. goto Exit;
  401. }
  402. if ( ::GetLastError() == ERROR_NOT_ALL_ASSIGNED )
  403. {
  404. // This means process does not even have the privilege so
  405. // AdjustTokenPrivilege simply ignored the request.
  406. ErrorTrace(0, "Privilege '%ls' does not exist, probably user is not an admin.", szPriv);
  407. goto Exit;
  408. }
  409. DebugTrace(0, "old=%d", tpOld.Privileges[0].Attributes);
  410. if ( fCheckOnly )
  411. {
  412. // Restore the privilege if it was not enabled
  413. if ( tpOld.PrivilegeCount > 0 )
  414. {
  415. if ( !::AdjustTokenPrivileges( hToken, FALSE, &tpOld, sizeof(tpOld), NULL, NULL ) )
  416. {
  417. cszErr = ::GetSysErrStr();
  418. ErrorTrace(0, "::AdjustTokenPrivileges(RESTORE) failed - %ls", cszErr);
  419. goto Exit;
  420. }
  421. }
  422. }
  423. fRet = TRUE;
  424. Exit:
  425. if ( hToken != NULL )
  426. ::CloseHandle( hToken );
  427. return( fRet );
  428. }
  429. BOOL DeleteRegKey(HKEY hkOpenKey,
  430. const WCHAR * pszKeyNameToDelete)
  431. {
  432. TraceFunctEnter("DeleteRegKey");
  433. BOOL fRet=FALSE;
  434. DWORD dwRet;
  435. // this recursively deletes the key and all its subkeys
  436. dwRet = SHDeleteKey( hkOpenKey, // handle to open key
  437. pszKeyNameToDelete); // subkey name
  438. if (dwRet != ERROR_SUCCESS)
  439. {
  440. // key does not exist - this is not an error case.
  441. DebugTrace(0, "RegDeleteKey of %S failed ec=%d. Not an error.",
  442. pszKeyNameToDelete, dwRet);
  443. goto cleanup;
  444. }
  445. DebugTrace(0, "RegDeleteKey of %S succeeded", pszKeyNameToDelete);
  446. fRet = TRUE;
  447. cleanup:
  448. TraceFunctLeave();
  449. return fRet;
  450. }
  451. DWORD PersistRegKeys( HKEY hkMountedHive,
  452. const WCHAR * pszKeyNameInHive,
  453. HKEY hkOpenKeyInRegistry,
  454. const WCHAR * pszKeyNameInRegistry,
  455. const WCHAR * pszKeyBackupFile,
  456. WCHAR * pszSnapshotPath)
  457. {
  458. TraceFunctEnter("PersistRegKeys");
  459. HKEY hKey=NULL;
  460. WCHAR szDataFile[MAX_PATH];
  461. LPCWSTR cszErr;
  462. DWORD dwRet=ERROR_INTERNAL_ERROR;
  463. BOOL fKeySaved;
  464. DWORD dwDisposition;
  465. // construct the name of the file that stores the backup we will
  466. // construct the name such that the file will get deleted after
  467. // the restore.
  468. wsprintf(szDataFile, L"%s%s", pszSnapshotPath, pszKeyBackupFile);
  469. DeleteFile(szDataFile); // delete the file if it exists
  470. // first load the DRM key to a file
  471. // open the DRM key
  472. dwRet= RegOpenKeyEx(hkOpenKeyInRegistry, // handle to open key
  473. pszKeyNameInRegistry, // name of subkey to open
  474. 0, // reserved
  475. KEY_READ, // security access mask
  476. &hKey); // handle to open key
  477. if (dwRet != ERROR_SUCCESS)
  478. {
  479. // key does not exist - this is not an error case.
  480. DebugTrace(0, "RegOpenKey of %S failed ec=%d", pszKeyNameInRegistry,
  481. dwRet);
  482. fKeySaved = FALSE;
  483. }
  484. else
  485. {
  486. // key exist
  487. dwRet = RegSaveKey( hKey, // handle to key
  488. szDataFile, // data file
  489. NULL); // SD
  490. if (dwRet != ERROR_SUCCESS)
  491. {
  492. // key does not exist - this is not an error case.
  493. DebugTrace(0, "RegSaveKey of %S failed ec=%d",
  494. pszKeyNameInRegistry, dwRet);
  495. fKeySaved = FALSE;
  496. }
  497. else
  498. {
  499. DebugTrace(0, "Current DRM Key %S saved successfully",
  500. pszKeyNameInRegistry);
  501. fKeySaved = TRUE;
  502. }
  503. }
  504. // close the key
  505. if (hKey)
  506. {
  507. RegCloseKey(hKey);
  508. hKey = NULL;
  509. }
  510. // now replace the snapshotted DRM key with the new key
  511. // first delete the existing key
  512. DeleteRegKey(hkMountedHive, pszKeyNameInHive);
  513. // now check to see if the key existing in the old registry in
  514. // the first place
  515. if (fKeySaved == FALSE)
  516. {
  517. DebugTrace(0, "Current key %S did not exist. Leaving",
  518. pszKeyNameInRegistry);
  519. goto done;
  520. }
  521. // Create the new DRM key
  522. dwRet = RegCreateKeyEx( hkMountedHive, // handle to open key
  523. pszKeyNameInHive, // subkey name
  524. 0, // reserved
  525. NULL, // class string
  526. REG_OPTION_NON_VOLATILE, // special options
  527. KEY_ALL_ACCESS, // desired security access
  528. NULL, // inheritance
  529. &hKey, // key handle
  530. &dwDisposition); // disposition value buffer
  531. VALIDATE_DWRET("::RegCreateKeyEx");
  532. _VERIFY(dwDisposition == REG_CREATED_NEW_KEY);
  533. dwRet= RegRestoreKey( hKey, // handle to key where restore begins
  534. szDataFile, // registry file
  535. REG_FORCE_RESTORE|REG_NO_LAZY_FLUSH); // options
  536. VALIDATE_DWRET("::RegRestoreKey");
  537. DebugTrace(0, "Successfully kept key %S", pszKeyNameInRegistry);
  538. dwRet = ERROR_SUCCESS;
  539. done:
  540. if (hKey)
  541. RegCloseKey(hKey);
  542. DeleteFile(szDataFile); // delete the file if it exists
  543. TraceFunctLeave();
  544. return dwRet;
  545. }
  546. LPWSTR
  547. GetNextMszString(LPWSTR pszBuffer)
  548. {
  549. return pszBuffer + lstrlen(pszBuffer) + 1;
  550. }
  551. DWORD
  552. ValueReplace(HKEY hkOldSystem, HKEY hkNewSystem, LPWSTR pszString)
  553. {
  554. tenter("ValueReplace");
  555. WCHAR szBuffer[MAX_PATH];
  556. BYTE *pData = NULL;
  557. DWORD dwType, dwSize, dwRet = ERROR_SUCCESS;
  558. LPWSTR pszValue = NULL;
  559. LPCWSTR cszErr;
  560. // split up the key and value in pszString
  561. lstrcpy(szBuffer, pszString);
  562. pszValue = wcsrchr(szBuffer, L'\\');
  563. if (! pszValue)
  564. {
  565. trace(0, "No value in %S", pszString);
  566. goto done;
  567. }
  568. *pszValue=L'\0';
  569. pszValue++;
  570. trace(0, "Key=%S, Value=%S", szBuffer, pszValue);
  571. // get the value size
  572. dwRet = SHGetValue(hkNewSystem, szBuffer, pszValue, &dwType, NULL, &dwSize);
  573. VALIDATE_DWRET("SHGetValue");
  574. pData = (BYTE *) SRMemAlloc(dwSize);
  575. if (! pData)
  576. {
  577. trace(0, "! SRMemAlloc");
  578. dwRet = ERROR_OUTOFMEMORY;
  579. goto done;
  580. }
  581. // get the value
  582. dwRet = SHGetValue(hkNewSystem, szBuffer, pszValue, &dwType, pData, &dwSize);
  583. VALIDATE_DWRET("SHGetValue");
  584. // set the value in the old registry
  585. SHSetValue(hkOldSystem, szBuffer, pszValue, dwType, pData, dwSize);
  586. VALIDATE_DWRET("SHGetValue");
  587. done:
  588. if (pData)
  589. {
  590. SRMemFree(pData);
  591. }
  592. tleave();
  593. return dwRet;
  594. }
  595. //
  596. // list of keys in KeysNotToRestore that we should ignore
  597. //
  598. LPWSTR g_rgKeysToRestore[] = {
  599. L"Installed Services",
  600. L"Mount Manager",
  601. L"Pending Rename Operations",
  602. L"Session Manager"
  603. };
  604. int g_nKeysToRestore = 4;
  605. BOOL
  606. IsKeyToBeRestored(LPWSTR pszKey)
  607. {
  608. for (int i=0; i < g_nKeysToRestore; i++)
  609. {
  610. if (lstrcmpi(g_rgKeysToRestore[i], pszKey) == 0)
  611. return TRUE;
  612. }
  613. return FALSE;
  614. }
  615. BOOL SRGetRegDword( HKEY hKey, LPCWSTR cszSubKey, LPCWSTR cszValue, DWORD *pdwData )
  616. {
  617. TraceFunctEnter("SRGetRegDword");
  618. BOOL fRet = FALSE;
  619. DWORD dwType;
  620. DWORD dwRes;
  621. DWORD cbData;
  622. dwType = REG_DWORD;
  623. cbData = sizeof(DWORD);
  624. dwRes = ::SHGetValue( hKey, cszSubKey, cszValue, &dwType, pdwData, &cbData );
  625. if ( dwRes != ERROR_SUCCESS )
  626. {
  627. ErrorTrace(0, "::SHGetValue failed - %ld", GetLastError() );
  628. goto Exit;
  629. }
  630. fRet = TRUE;
  631. Exit:
  632. TraceFunctLeave();
  633. return( fRet );
  634. }
  635. void
  636. ChangeCCS(HKEY hkMount, LPWSTR pszString)
  637. {
  638. tenter("ChangeCCS");
  639. int nCS = lstrlen(L"CurrentControlSet");
  640. if (StrCmpNI(pszString, L"CurrentControlSet", nCS) == 0)
  641. {
  642. LPWSTR pszCS = L"ControlSet001";
  643. DWORD dwCurrent = 0;
  644. if (::SRGetRegDword (hkMount, L"Select", L"Current", &dwCurrent) &&
  645. dwCurrent == 2)
  646. {
  647. pszCS[lstrlenW(L"ControlSet00")] = L'2';
  648. }
  649. WCHAR szTemp[MAX_PATH];
  650. lstrcpy(szTemp, &(pszString[nCS]));
  651. wsprintf(pszString, L"%s%s", pszCS, szTemp);
  652. trace(0, "ChangeCCS: pszString = %S", pszString);
  653. }
  654. tleave();
  655. }
  656. DWORD
  657. PreserveKeysNotToRestore(HKEY hkOldSystem, LPWSTR pszSnapshotPath)
  658. {
  659. HKEY hkNewSystem = NULL;
  660. DWORD dwIndex = 0;
  661. WCHAR szName[MAX_PATH], szKey[MAX_PATH];
  662. BYTE *pMszString = NULL;
  663. DWORD dwSize, dwType, cbValue;
  664. DWORD dwRet = ERROR_SUCCESS;
  665. LPCWSTR cszErr;
  666. HKEY hkKNTR = NULL;
  667. TENTER("PreserveKeysNotToRestore");
  668. //
  669. // open the new system hive
  670. //
  671. dwRet = ::RegOpenKeyEx( HKEY_LOCAL_MACHINE, L"System", 0, KEY_ALL_ACCESS, &hkNewSystem );
  672. VALIDATE_DWRET("::RegOpenKey");
  673. //
  674. // enumerate KeysNotToRestore
  675. //
  676. dwRet = ::RegOpenKeyEx( hkNewSystem,
  677. L"CurrentControlSet\\Control\\BackupRestore\\KeysNotToRestore",
  678. 0, KEY_READ,
  679. &hkKNTR );
  680. VALIDATE_DWRET("::RegOpenKey");
  681. dwSize = MAX_PATH;
  682. cbValue = 0;
  683. while (ERROR_SUCCESS ==
  684. (dwRet = RegEnumValue(hkKNTR,
  685. dwIndex++,
  686. szName,
  687. &dwSize,
  688. NULL,
  689. &dwType,
  690. NULL,
  691. &cbValue )))
  692. {
  693. trace(0, "Name=%S", szName);
  694. if (FALSE == IsKeyToBeRestored(szName))
  695. {
  696. //
  697. // should preserve the keys specified in this multisz value
  698. //
  699. LPWSTR pszString = NULL;
  700. pMszString = (BYTE *) SRMemAlloc(cbValue);
  701. if (NULL == pMszString)
  702. {
  703. trace(0, "! SRMemAlloc");
  704. goto done;
  705. }
  706. // read the multisz string
  707. dwRet = RegQueryValueEx(hkKNTR,
  708. szName,
  709. NULL,
  710. &dwType,
  711. pMszString,
  712. &cbValue);
  713. VALIDATE_DWRET("RegQueryValueEx");
  714. // process each element in the multisz string
  715. pszString = (LPWSTR) pMszString;
  716. do
  717. {
  718. // stop on null or empty string
  719. if (! pszString || ! *pszString)
  720. break;
  721. trace(0, "Key = %S", pszString);
  722. // replace based on the last character of each key
  723. // if '\', then the whole key and subkeys are to be replaced in the old registry
  724. // if '*', it should be merged with the old -- we don't support this and will ignore
  725. // otherwise, it is a value to be replaced
  726. switch (pszString[lstrlen(pszString)-1])
  727. {
  728. case L'*' :
  729. trace(0, "Merge key - ignoring");
  730. break;
  731. case L'\\':
  732. trace(0, "Replacing key");
  733. lstrcpy(szKey, pszString);
  734. szKey[lstrlen(szKey)-1]=L'\0';
  735. ChangeCCS(hkOldSystem, szKey);
  736. PersistRegKeys(hkOldSystem, // mounted hive
  737. szKey, // key name in hive
  738. hkNewSystem, // open key in registry
  739. szKey, // key name in registry
  740. L"srtemp.dat", // name of backup file
  741. pszSnapshotPath); // snapshot path
  742. break;
  743. default:
  744. trace(0, "Replacing value");
  745. lstrcpy(szKey, pszString);
  746. ChangeCCS(hkOldSystem, szKey);
  747. ValueReplace(hkOldSystem, hkNewSystem, szKey);
  748. break;
  749. }
  750. } while (pszString = GetNextMszString(pszString));
  751. SRMemFree(pMszString);
  752. }
  753. dwSize = MAX_PATH;
  754. cbValue = 0;
  755. }
  756. done:
  757. if (hkNewSystem)
  758. RegCloseKey(hkNewSystem);
  759. if (pMszString)
  760. {
  761. SRMemFree(pMszString);
  762. }
  763. if (hkKNTR)
  764. {
  765. RegCloseKey(hkKNTR);
  766. }
  767. TLEAVE();
  768. return dwRet;
  769. }
  770. void _cdecl
  771. main()
  772. {
  773. int nOption;
  774. LPWSTR pwszFileName = NULL;
  775. DWORD dwSize;
  776. RESTOREPOINTINFO rpti;
  777. STATEMGRSTATUS smgrs;
  778. LPWSTR * argv = NULL;
  779. int argc;
  780. HGLOBAL hMem = NULL;
  781. int fStart;
  782. HANDLE hFilter = NULL;
  783. DWORD dwRet;
  784. HKEY hkMount = NULL;
  785. InitAsyncTrace();
  786. TENTER("main");
  787. argv = CommandLineToArgvW(GetCommandLine(), &argc);
  788. if (! argv)
  789. {
  790. printf("Error parsing arguments");
  791. exit(1);
  792. }
  793. if (argc < 2 || argc > 6)
  794. {
  795. PrintUsage();
  796. goto done;
  797. }
  798. nOption = _wtoi(argv[1]);
  799. switch(nOption)
  800. {
  801. case 1:
  802. printf("EnableSR...DWORD %ld", EnableSR(argc == 3 ? argv[2] : NULL));
  803. break;
  804. case 2:
  805. printf("DisableSR...DWORD %ld", DisableSR(argc == 3 ? argv[2] : NULL));
  806. break;
  807. case 3:
  808. printf("EnableFIFO...DWORD %ld", EnableFIFO());
  809. break;
  810. case 4:
  811. if (argc != 3)
  812. {
  813. PrintUsage();
  814. goto done;
  815. }
  816. printf("DisableFIFO...DWORD %ld", DisableFIFO(_wtol(argv[2])));
  817. break;
  818. case 5:
  819. if (argc < 3)
  820. lstrcpyn(rpti.szDescription, L"Rpctest", MAX_DESC_W);
  821. else
  822. lstrcpyn(rpti.szDescription, argv[2], MAX_DESC_W);
  823. if (argc < 4)
  824. rpti.dwRestorePtType = APPLICATION_INSTALL;
  825. else
  826. rpti.dwRestorePtType = _wtol(argv[3]);
  827. if (argc < 5)
  828. rpti.dwEventType = BEGIN_SYSTEM_CHANGE;
  829. else
  830. rpti.dwEventType = _wtol(argv[4]);
  831. if (argc < 6)
  832. rpti.llSequenceNumber = 0;
  833. else
  834. rpti.llSequenceNumber = _wtol(argv[5]);
  835. printf("SRSetRestorePoint...BOOL %d", SRSetRestorePoint(&rpti, &smgrs));
  836. printf("\nStateMgrStatus.nStatus = %d, StateMgrStatus.llSequenceNumber = %I64d",
  837. smgrs.nStatus, smgrs.llSequenceNumber);
  838. break;
  839. case 6:
  840. if (argc != 3)
  841. {
  842. PrintUsage();
  843. goto done;
  844. }
  845. printf("SRRemoveRestorePoint...DWORD %ld", SRRemoveRestorePoint(_wtol(argv[2])));
  846. break;
  847. case 7:
  848. if (argc != 3)
  849. {
  850. PrintUsage();
  851. goto done;
  852. }
  853. printf("SRUpdateMonitoredList...DWORD %ld", SRUpdateMonitoredList(argv[2]));
  854. break;
  855. case 8:
  856. if (argc != 4)
  857. {
  858. PrintUsage();
  859. goto done;
  860. }
  861. printf("SRFifo...DWORD %ld", SRFifo(argv[2], 0, _wtoi(argv[3]), TRUE, FALSE));
  862. break;
  863. case 9:
  864. if (argc != 4)
  865. {
  866. PrintUsage();
  867. goto done;
  868. }
  869. printf("SRFifo...DWORD %ld", SRFifo(argv[2], 0, _wtoi(argv[3]), TRUE, TRUE));
  870. break;
  871. case 10:
  872. if (argc != 4)
  873. {
  874. PrintUsage();
  875. goto done;
  876. }
  877. printf("SRFifo...DWORD %ld", SRFifo(argv[2], _wtoi(argv[3]), 0, TRUE, FALSE));
  878. break;
  879. case 11:
  880. if (argc != 4)
  881. {
  882. PrintUsage();
  883. goto done;
  884. }
  885. printf("SRFifo...DWORD %ld", SRFifo(argv[2], _wtoi(argv[3]), 0, FALSE, FALSE));
  886. break;
  887. case 12:
  888. if (argc != 3)
  889. {
  890. PrintUsage();
  891. goto done;
  892. }
  893. printf("Freeze...DWORD %ld", SRFreeze(argv[2]));
  894. break;
  895. case 13:
  896. if (argc != 3)
  897. {
  898. PrintUsage();
  899. goto done;
  900. }
  901. printf("Compress...DWORD %ld", SRCompress(argv[2]));
  902. break;
  903. case 14:
  904. if (argc != 5)
  905. {
  906. PrintUsage();
  907. goto done;
  908. }
  909. SRNotify(argv[2], _wtol(argv[3]), _wtoi(argv[4]));
  910. printf("SRNotify...no return");
  911. break;
  912. case 15:
  913. if (argc != 3)
  914. {
  915. PrintUsage();
  916. goto done;
  917. }
  918. if (ERROR_SUCCESS != SrCreateControlHandle(SR_OPTION_OVERLAPPED, &hFilter))
  919. {
  920. printf("! SrCreateControlHandle");
  921. goto done;
  922. }
  923. fStart = _wtoi(argv[2]);
  924. printf("Sr%SMonitoring : %ld", fStart ? L"Start" : L"Stop",
  925. fStart ? SrStartMonitoring(hFilter) : SrStopMonitoring(hFilter));
  926. CloseHandle(hFilter);
  927. break;
  928. case 16:
  929. printf("ResetSR...DWORD %ld", ResetSR((argc >= 3) ? argv[2] : NULL));
  930. break;
  931. case 17:
  932. if (argc != 4)
  933. {
  934. PrintUsage();
  935. goto done;
  936. }
  937. printf("SRUpdateDSSize...DWORD %ld", SRUpdateDSSize(argv[2], _wtol(argv[3])));
  938. break;
  939. case 18:
  940. printf("SRSwitchLog...DWORD %ld", SRSwitchLog());
  941. break;
  942. case 19:
  943. if (argc != 4)
  944. {
  945. PrintUsage();
  946. goto done;
  947. }
  948. printf("AddCatalogToCryptoDB...DWORD %ld", AddCatalogToCryptoDB(argv[2], argv[3]));
  949. break;
  950. case 20:
  951. if (argc != 3)
  952. {
  953. PrintUsage();
  954. goto done;
  955. }
  956. printf("RemoveCatalogFromCryptoDB...DWORD %ld", RemoveCatalogFromCryptoDB(argv[2]));
  957. break;
  958. case 21:
  959. SRPrintState();
  960. break;
  961. case 22:
  962. if (argc != 3)
  963. {
  964. PrintUsage();
  965. goto done;
  966. }
  967. if (FALSE == CheckPrivilege(SE_RESTORE_NAME, FALSE))
  968. {
  969. printf("Cannot get RESTORE privilege");
  970. goto done;
  971. }
  972. dwRet = ::RegLoadKey( HKEY_LOCAL_MACHINE, L"SRSys", argv[2] );
  973. VALIDATE_DWRET("::RegLoadKey");
  974. dwRet = ::RegOpenKey( HKEY_LOCAL_MACHINE, L"SRSys", &hkMount );
  975. VALIDATE_DWRET("::RegOpenKey");
  976. dwRet = KeepMountedDevices(hkMount);
  977. printf("KeepMountedDevices = %ld", dwRet);
  978. RegCloseKey(hkMount);
  979. RegUnLoadKey(HKEY_LOCAL_MACHINE, L"SRSys");
  980. break;
  981. case 25:
  982. if (argc != 3)
  983. {
  984. PrintUsage();
  985. goto done;
  986. }
  987. printf("SRRegisterSnapshotCallback...DWORD %ld", SRRegisterSnapshotCallback(argv[2]));
  988. break;
  989. case 26:
  990. if (argc != 3)
  991. {
  992. PrintUsage();
  993. goto done;
  994. }
  995. printf("SRUnregisterSnapshotCallback...DWORD %ld", SRUnregisterSnapshotCallback(argv[2]));
  996. break;
  997. case 27:
  998. if (argc != 4)
  999. {
  1000. PrintUsage();
  1001. goto done;
  1002. }
  1003. printf("EnableSREx...DWORD %ld", EnableSREx(argv[2], _wtoi(argv[3])));
  1004. break;
  1005. case 28:
  1006. if (argc != 3)
  1007. {
  1008. PrintUsage();
  1009. goto done;
  1010. }
  1011. if (FALSE == CheckPrivilege(SE_BACKUP_NAME, FALSE))
  1012. {
  1013. printf("Cannot get RESTORE privilege");
  1014. goto done;
  1015. }
  1016. if (FALSE == CheckPrivilege(SE_RESTORE_NAME, FALSE))
  1017. {
  1018. printf("Cannot get RESTORE privilege");
  1019. goto done;
  1020. }
  1021. dwRet = ::RegLoadKey( HKEY_LOCAL_MACHINE, L"SRSys", argv[2] );
  1022. VALIDATE_DWRET("::RegLoadKey");
  1023. dwRet = ::RegOpenKeyEx( HKEY_LOCAL_MACHINE, L"SRSys", 0, KEY_ALL_ACCESS, &hkMount );
  1024. VALIDATE_DWRET("::RegOpenKey");
  1025. dwRet = PreserveKeysNotToRestore(hkMount, L"c:\\");
  1026. printf("PreserveKeysNotToRestore = %ld", dwRet);
  1027. RegCloseKey(hkMount);
  1028. RegUnLoadKey(HKEY_LOCAL_MACHINE, L"SRSys");
  1029. break;
  1030. default:
  1031. printf("Invalid option\n");
  1032. PrintUsage();
  1033. break;
  1034. }
  1035. done:
  1036. if (argv) hMem = GlobalHandle(argv);
  1037. if (hMem) GlobalFree(hMem);
  1038. TLEAVE();
  1039. TermAsyncTrace();
  1040. }