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.

1471 lines
33 KiB

  1. /********************************************************************
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. srrpcc.cpp
  5. Abstract:
  6. implements functions exported in srclient.DLL
  7. Exported API:
  8. SRSetRestorePoint / SRRemoveRestorePoint
  9. DisableSR / EnableSR
  10. DisableFIFO / EnableFIFO
  11. Revision History:
  12. Brijesh Krishnaswami (brijeshk) - 04/10/00 - Created
  13. ********************************************************************/
  14. #include "stdafx.h"
  15. #ifdef THIS_FILE
  16. #undef THIS_FILE
  17. #endif
  18. static char __szTraceSourceFile[] = __FILE__;
  19. #define THIS_FILE __szTraceSourceFile
  20. //
  21. // function to check if SR configuration is disabled
  22. // via group policy
  23. //
  24. DWORD
  25. CheckPolicy()
  26. {
  27. DWORD dwPolicyEnabled = 0;
  28. DWORD dwErr = ERROR_SUCCESS;
  29. HKEY hKey = NULL;
  30. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  31. s_cszGroupPolicy,
  32. 0,
  33. KEY_READ,
  34. &hKey))
  35. {
  36. // if this value exists,
  37. // then config policy is either enabled or disabled
  38. // we need to disable access in both cases
  39. if (ERROR_SUCCESS == RegReadDWORD(hKey, s_cszDisableConfig, &dwPolicyEnabled))
  40. dwErr = ERROR_ACCESS_DENIED;
  41. RegCloseKey(hKey);
  42. }
  43. return dwErr;
  44. }
  45. // bind handle to endpoint
  46. DWORD
  47. SRRPCInit(
  48. RPC_IF_HANDLE * pIfHandle,
  49. BOOL fVerifyRights)
  50. {
  51. RPC_STATUS status;
  52. LPWSTR pszStringBinding = NULL;
  53. DWORD dwRc = ERROR_SUCCESS;
  54. InitAsyncTrace();
  55. TENTER("SRRPCInit");
  56. //
  57. // if admin rights are required
  58. //
  59. if (fVerifyRights && ! IsAdminOrSystem())
  60. {
  61. TRACE(0, "Caller does not have admin or localsystem rights");
  62. dwRc = ERROR_ACCESS_DENIED;
  63. goto exit;
  64. }
  65. //
  66. // check if the service is stopping
  67. // if it is, then we don't want to accept any more rpc calls
  68. //
  69. if (IsStopSignalled(NULL))
  70. {
  71. TRACE(0, "Service shut down - not accepting rpc call");
  72. dwRc = ERROR_SERVICE_DISABLED;
  73. goto exit;
  74. }
  75. // compose string to pass to binding api
  76. dwRc = (DWORD) RpcStringBindingCompose(NULL,
  77. s_cszRPCProtocol,
  78. NULL,
  79. s_cszRPCEndPoint,
  80. NULL,
  81. &pszStringBinding);
  82. if (dwRc != ERROR_SUCCESS)
  83. {
  84. TRACE(0, "RPCStringBindingCompose: error=%ld", dwRc);
  85. goto exit;
  86. }
  87. // set the binding handle that will be used to bind to the server.
  88. dwRc = (DWORD) RpcBindingFromStringBinding(pszStringBinding,
  89. pIfHandle);
  90. if (dwRc != ERROR_SUCCESS)
  91. {
  92. TRACE(0, "RPCBindingFromStringBinding: error=%ld", dwRc);
  93. }
  94. // free string
  95. RpcStringFree(&pszStringBinding);
  96. exit:
  97. TLEAVE();
  98. return dwRc;
  99. }
  100. // free binding handle
  101. DWORD
  102. SRRPCTerm(
  103. RPC_IF_HANDLE * pIfHandle)
  104. {
  105. RPC_STATUS status;
  106. TENTER("SRRPCTerm");
  107. // free binding handle
  108. if (pIfHandle && *pIfHandle)
  109. status = RpcBindingFree(pIfHandle);
  110. TLEAVE();
  111. TermAsyncTrace();
  112. return (DWORD) status;
  113. }
  114. // API to disable System Restore
  115. extern "C" DWORD WINAPI
  116. DisableSR(LPCWSTR pszDrive)
  117. {
  118. DWORD dwRc = ERROR_INTERNAL_ERROR;
  119. handle_t srrpc_IfHandle = NULL;
  120. TENTER("DisableSR");
  121. //
  122. // check if sr config is disabled via group policy
  123. //
  124. dwRc = CheckPolicy();
  125. if (dwRc != ERROR_SUCCESS)
  126. {
  127. goto exit;
  128. }
  129. // initialize
  130. dwRc = SRRPCInit(&srrpc_IfHandle, TRUE);
  131. if (dwRc != ERROR_SUCCESS)
  132. {
  133. goto exit;
  134. }
  135. // call remote procedure
  136. RpcTryExcept
  137. {
  138. dwRc = DisableSRS(srrpc_IfHandle, pszDrive);
  139. }
  140. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  141. {
  142. dwRc = RpcExceptionCode();
  143. TRACE(0, "DisableSRS threw exception: error=%ld", dwRc);
  144. }
  145. RpcEndExcept
  146. // terminate
  147. SRRPCTerm(&srrpc_IfHandle);
  148. exit:
  149. TLEAVE();
  150. return dwRc;
  151. }
  152. // private function to start the SR service
  153. // fWait - if TRUE : function is synchronous - waits till service is started completely
  154. // if FALSE : function is asynchronous - does not wait for service to complete starting
  155. DWORD
  156. StartSRService(BOOL fWait)
  157. {
  158. TENTER("StartSRService");
  159. DWORD dwRc = ERROR_INTERNAL_ERROR;
  160. SC_HANDLE hSR=NULL;
  161. SC_HANDLE hSCM = ::OpenSCManager(NULL,
  162. NULL,
  163. SC_MANAGER_ALL_ACCESS);
  164. SERVICE_STATUS Status;
  165. if (NULL==hSCM)
  166. {
  167. dwRc = GetLastError();
  168. ErrorTrace(0,"OpenSCManager failed 0x%x", dwRc);
  169. goto done;
  170. }
  171. hSR = OpenService(hSCM,
  172. s_cszServiceName,
  173. SERVICE_ALL_ACCESS);
  174. if (NULL == hSR)
  175. {
  176. dwRc = GetLastError();
  177. ErrorTrace(0,"OpenService failed 0x%x", dwRc);
  178. goto done;
  179. }
  180. if (FALSE == StartService(hSR, 0, NULL))
  181. {
  182. dwRc = GetLastError();
  183. if (dwRc == ERROR_SERVICE_ALREADY_RUNNING)
  184. {
  185. goto done;
  186. }
  187. if (FALSE == QueryServiceStatus(hSR, &Status))
  188. {
  189. goto done;
  190. }
  191. else
  192. {
  193. dwRc = Status.dwWin32ExitCode;
  194. goto done;
  195. }
  196. }
  197. if (fWait)
  198. {
  199. //
  200. // query the service until it starts or stops
  201. // try thrice
  202. //
  203. for (int i = 0; i < 3; i++)
  204. {
  205. Sleep(2000);
  206. if (FALSE == QueryServiceStatus(hSR, &Status))
  207. {
  208. goto done;
  209. }
  210. if (Status.dwCurrentState == SERVICE_STOPPED)
  211. {
  212. dwRc = Status.dwWin32ExitCode;
  213. if (dwRc == ERROR_SUCCESS)
  214. {
  215. //
  216. // service masks DISABLED error code
  217. // to avoid unnecessary event log messages
  218. //
  219. dwRc = ERROR_SERVICE_DISABLED;
  220. }
  221. goto done;
  222. }
  223. if (Status.dwCurrentState == SERVICE_RUNNING)
  224. {
  225. //
  226. // wait on init event
  227. //
  228. HANDLE hInit = OpenEvent(SYNCHRONIZE, FALSE, s_cszSRInitEvent);
  229. if (hInit)
  230. {
  231. dwRc = WaitForSingleObject(hInit, 120000); // wait for 2 minutes
  232. CloseHandle(hInit);
  233. if (dwRc == WAIT_OBJECT_0)
  234. {
  235. dwRc = ERROR_SUCCESS;
  236. goto done;
  237. }
  238. else
  239. {
  240. dwRc = ERROR_TIMEOUT;
  241. goto done;
  242. }
  243. }
  244. }
  245. }
  246. }
  247. dwRc = ERROR_SUCCESS;
  248. done:
  249. if (NULL != hSR)
  250. {
  251. CloseServiceHandle(hSR);
  252. }
  253. if (NULL != hSCM)
  254. {
  255. CloseServiceHandle(hSCM);
  256. }
  257. TLEAVE();
  258. return dwRc;
  259. }
  260. DWORD
  261. SetDisableFlag(DWORD dwValue)
  262. {
  263. HKEY hKeySR = NULL;
  264. DWORD dwRc = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  265. s_cszSRRegKey,
  266. 0,
  267. KEY_WRITE,
  268. &hKeySR);
  269. if (ERROR_SUCCESS != dwRc)
  270. goto done;
  271. dwRc = RegWriteDWORD(hKeySR, s_cszDisableSR, &dwValue);
  272. if (ERROR_SUCCESS != dwRc)
  273. goto done;
  274. done:
  275. if (hKeySR)
  276. RegCloseKey(hKeySR);
  277. return dwRc;
  278. }
  279. // API to enable System Restore
  280. extern "C" DWORD WINAPI
  281. EnableSR(LPCWSTR pszDrive)
  282. {
  283. DWORD dwRc = ERROR_INTERNAL_ERROR;
  284. handle_t srrpc_IfHandle = NULL;
  285. TENTER("EnableSR");
  286. //
  287. // check if sr config is disabled via group policy
  288. //
  289. dwRc = CheckPolicy();
  290. if (dwRc != ERROR_SUCCESS)
  291. {
  292. goto exit;
  293. }
  294. // if whole of SR is enabled, then
  295. // set the boot mode of service/filter to automatic
  296. // and start the service
  297. if (! pszDrive || IsSystemDrive((LPWSTR) pszDrive))
  298. {
  299. //
  300. // if safe mode, then don't
  301. //
  302. if (0 != GetSystemMetrics(SM_CLEANBOOT))
  303. {
  304. TRACE(0, "This is safemode");
  305. dwRc = ERROR_BAD_ENVIRONMENT;
  306. goto exit;
  307. }
  308. dwRc = SetServiceStartup(s_cszServiceName, SERVICE_AUTO_START);
  309. if (ERROR_SUCCESS != dwRc)
  310. goto exit;
  311. dwRc = SetServiceStartup(s_cszFilterName, SERVICE_BOOT_START);
  312. if (ERROR_SUCCESS != dwRc)
  313. goto exit;
  314. // set the disable flag to false
  315. // BUGBUG - this piece of code is duplicated in the service code as well
  316. // reason is: we need the ability to disable/enable SR from within and outside
  317. // the service
  318. dwRc = SetDisableFlag(FALSE);
  319. if (ERROR_SUCCESS != dwRc)
  320. goto exit;
  321. dwRc = StartSRService(FALSE);
  322. }
  323. else
  324. {
  325. // initialize
  326. dwRc = SRRPCInit(&srrpc_IfHandle, TRUE);
  327. if (dwRc != ERROR_SUCCESS)
  328. {
  329. goto exit;
  330. }
  331. // call remote procedure
  332. RpcTryExcept
  333. {
  334. dwRc = EnableSRS(srrpc_IfHandle, pszDrive);
  335. }
  336. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  337. {
  338. dwRc = RpcExceptionCode();
  339. TRACE(0, "EnableSRS threw exception: error=%ld", dwRc);
  340. }
  341. RpcEndExcept
  342. // terminate
  343. SRRPCTerm(&srrpc_IfHandle);
  344. }
  345. exit:
  346. TLEAVE();
  347. return dwRc;
  348. }
  349. // API to enable System Restore - extended version
  350. extern "C" DWORD WINAPI
  351. EnableSREx(LPCWSTR pszDrive, BOOL fWait)
  352. {
  353. DWORD dwRc = ERROR_INTERNAL_ERROR;
  354. handle_t srrpc_IfHandle = NULL;
  355. TENTER("EnableSREx");
  356. //
  357. // check if sr config is disabled via group policy
  358. //
  359. dwRc = CheckPolicy();
  360. if (dwRc != ERROR_SUCCESS)
  361. {
  362. goto exit;
  363. }
  364. // if whole of SR is enabled, then
  365. // set the boot mode of service/filter to automatic
  366. // and start the service
  367. if (! pszDrive || IsSystemDrive((LPWSTR) pszDrive))
  368. {
  369. //
  370. // if safe mode, then don't
  371. //
  372. if (0 != GetSystemMetrics(SM_CLEANBOOT))
  373. {
  374. TRACE(0, "This is safemode");
  375. dwRc = ERROR_BAD_ENVIRONMENT;
  376. goto exit;
  377. }
  378. dwRc = SetServiceStartup(s_cszServiceName, SERVICE_AUTO_START);
  379. if (ERROR_SUCCESS != dwRc)
  380. goto exit;
  381. dwRc = SetServiceStartup(s_cszFilterName, SERVICE_BOOT_START);
  382. if (ERROR_SUCCESS != dwRc)
  383. goto exit;
  384. // set the disable flag to false
  385. // BUGBUG - this piece of code is duplicated in the service code as well
  386. // reason is: we need the ability to disable/enable SR from within and outside
  387. // the service
  388. dwRc = SetDisableFlag(FALSE);
  389. if (ERROR_SUCCESS != dwRc)
  390. goto exit;
  391. dwRc = StartSRService(fWait);
  392. }
  393. else
  394. {
  395. // initialize
  396. dwRc = SRRPCInit(&srrpc_IfHandle, TRUE);
  397. if (dwRc != ERROR_SUCCESS)
  398. {
  399. goto exit;
  400. }
  401. // call remote procedure
  402. RpcTryExcept
  403. {
  404. dwRc = EnableSRS(srrpc_IfHandle, pszDrive);
  405. }
  406. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  407. {
  408. dwRc = RpcExceptionCode();
  409. TRACE(0, "EnableSRS threw exception: error=%ld", dwRc);
  410. }
  411. RpcEndExcept
  412. // terminate
  413. SRRPCTerm(&srrpc_IfHandle);
  414. }
  415. exit:
  416. TLEAVE();
  417. return dwRc;
  418. }
  419. // API to update the list of protected files - UNICODE version
  420. // pass the fullpath name of the XML file containing the updated list of files
  421. extern "C" DWORD WINAPI
  422. SRUpdateMonitoredListA(
  423. LPCSTR pszXMLFile)
  424. {
  425. DWORD dwRc = ERROR_INTERNAL_ERROR;
  426. LPWSTR pwszXMLFile = NULL;
  427. handle_t srrpc_IfHandle = NULL;
  428. TENTER("SRUpdateMonitoredListA");
  429. pwszXMLFile = ConvertToUnicode((LPSTR) pszXMLFile);
  430. if (! pwszXMLFile)
  431. {
  432. TRACE(0, "ConvertToUnicode");
  433. goto exit;
  434. }
  435. // initialize
  436. dwRc = SRRPCInit(&srrpc_IfHandle, TRUE);
  437. if (dwRc != ERROR_SUCCESS)
  438. {
  439. goto exit;
  440. }
  441. // call remote procedure
  442. RpcTryExcept
  443. {
  444. dwRc = SRUpdateMonitoredListS(srrpc_IfHandle, pwszXMLFile);
  445. }
  446. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  447. {
  448. dwRc = RpcExceptionCode();
  449. TRACE(0, "SRUpdateMonitoredListS threw exception: error=%ld", dwRc);
  450. }
  451. RpcEndExcept
  452. // terminate
  453. SRRPCTerm(&srrpc_IfHandle);
  454. exit:
  455. if (pwszXMLFile)
  456. SRMemFree(pwszXMLFile);
  457. TLEAVE();
  458. return dwRc;
  459. }
  460. // API to update the list of protected files - UNICODE version
  461. // pass the fullpath name of the XML file containing the updated list of files
  462. extern "C" DWORD WINAPI
  463. SRUpdateMonitoredListW(
  464. LPCWSTR pwszXMLFile)
  465. {
  466. DWORD dwRc = ERROR_INTERNAL_ERROR;
  467. handle_t srrpc_IfHandle = NULL;
  468. TENTER("SRUpdateMonitoredListW");
  469. // initialize
  470. dwRc = SRRPCInit(&srrpc_IfHandle, TRUE);
  471. if (dwRc != ERROR_SUCCESS)
  472. {
  473. goto exit;
  474. }
  475. // call remote procedure
  476. RpcTryExcept
  477. {
  478. dwRc = SRUpdateMonitoredListS(srrpc_IfHandle, pwszXMLFile);
  479. }
  480. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  481. {
  482. dwRc = RpcExceptionCode();
  483. TRACE(0, "SRUpdateMonitoredListS threw exception: error=%ld", dwRc);
  484. }
  485. RpcEndExcept
  486. // terminate
  487. SRRPCTerm(&srrpc_IfHandle);
  488. exit:
  489. TLEAVE();
  490. return dwRc;
  491. }
  492. // API to set a restore point - ANSI version
  493. extern "C" BOOL
  494. SRSetRestorePointA(
  495. PRESTOREPOINTINFOA pRPInfoA,
  496. PSTATEMGRSTATUS pSMgrStatus)
  497. {
  498. BOOL fRc = FALSE;
  499. RESTOREPOINTINFOW RPInfoW;
  500. LPWSTR pszDescW = NULL;
  501. handle_t srrpc_IfHandle = NULL;
  502. TENTER("SRSetRestorePointA");
  503. // Initialize return values
  504. if (! pSMgrStatus || ! pRPInfoA)
  505. {
  506. goto exit;
  507. }
  508. pSMgrStatus->llSequenceNumber = 0;
  509. pSMgrStatus->nStatus = ERROR_INTERNAL_ERROR;
  510. // convert struct to unicode
  511. // since the string is the last member of the struct, we can memcpy
  512. // all
  513. memcpy(&RPInfoW, pRPInfoA, sizeof(RESTOREPOINTINFOA));
  514. pszDescW = ConvertToUnicode(pRPInfoA->szDescription);
  515. if (! pszDescW)
  516. {
  517. TRACE(0, "ConvertToUnicode");
  518. goto exit;
  519. }
  520. lstrcpy(RPInfoW.szDescription, pszDescW);
  521. // initialize
  522. // don't need admin rights to call this api
  523. pSMgrStatus->nStatus = SRRPCInit(&srrpc_IfHandle, FALSE);
  524. if (pSMgrStatus->nStatus != ERROR_SUCCESS)
  525. {
  526. goto exit;
  527. }
  528. // call remote procedure
  529. RpcTryExcept
  530. {
  531. fRc = SRSetRestorePointS(srrpc_IfHandle, &RPInfoW, pSMgrStatus);
  532. }
  533. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  534. {
  535. // set right error code if SR is disabled
  536. DWORD dwRc = RpcExceptionCode();
  537. if (RPC_S_SERVER_UNAVAILABLE == dwRc ||
  538. RPC_S_UNKNOWN_IF == dwRc)
  539. {
  540. pSMgrStatus->nStatus = ERROR_SERVICE_DISABLED;
  541. }
  542. else
  543. {
  544. pSMgrStatus->nStatus = dwRc;
  545. }
  546. TRACE(0, "SRSetRestorePointS threw exception: nStatus=%ld", pSMgrStatus->nStatus);
  547. }
  548. RpcEndExcept
  549. // terminate
  550. SRRPCTerm(&srrpc_IfHandle);
  551. exit:
  552. if (pszDescW)
  553. SRMemFree(pszDescW);
  554. TLEAVE();
  555. return fRc;
  556. }
  557. // API to set a restore point - UNICODE version
  558. extern "C" BOOL
  559. SRSetRestorePointW(
  560. PRESTOREPOINTINFOW pRPInfoW,
  561. PSTATEMGRSTATUS pSMgrStatus)
  562. {
  563. BOOL fRc = FALSE;
  564. DWORD dwRc = ERROR_SUCCESS;
  565. handle_t srrpc_IfHandle = NULL;
  566. TENTER("SRSetRestorePointW");
  567. // Initialize return values
  568. if (! pSMgrStatus || ! pRPInfoW)
  569. {
  570. goto exit;
  571. }
  572. pSMgrStatus->llSequenceNumber = 0;
  573. pSMgrStatus->nStatus = ERROR_INTERNAL_ERROR;
  574. // initialize
  575. pSMgrStatus->nStatus = SRRPCInit(&srrpc_IfHandle, FALSE);
  576. if (pSMgrStatus->nStatus != ERROR_SUCCESS)
  577. {
  578. goto exit;
  579. }
  580. // call remote procedure
  581. RpcTryExcept
  582. {
  583. fRc = SRSetRestorePointS(srrpc_IfHandle, pRPInfoW, pSMgrStatus);
  584. }
  585. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  586. {
  587. // set right error code if SR is disabled
  588. DWORD dwRc = RpcExceptionCode();
  589. if (RPC_S_SERVER_UNAVAILABLE == dwRc ||
  590. RPC_S_UNKNOWN_IF == dwRc)
  591. {
  592. pSMgrStatus->nStatus = ERROR_SERVICE_DISABLED;
  593. }
  594. else
  595. {
  596. pSMgrStatus->nStatus = dwRc;
  597. }
  598. TRACE(0, "SRSetRestorePointS threw exception: nStatus=%ld", pSMgrStatus->nStatus);
  599. }
  600. RpcEndExcept
  601. // terminate
  602. SRRPCTerm(&srrpc_IfHandle);
  603. exit:
  604. TLEAVE();
  605. return fRc;
  606. }
  607. // API to remove a restore point
  608. extern "C" DWORD
  609. SRRemoveRestorePoint(
  610. DWORD dwRPNum)
  611. {
  612. DWORD dwRc = ERROR_INTERNAL_ERROR;
  613. handle_t srrpc_IfHandle = NULL;
  614. TENTER("SRRemoveRestorePoint");
  615. // initialize
  616. dwRc = SRRPCInit(&srrpc_IfHandle, FALSE);
  617. if (dwRc != ERROR_SUCCESS)
  618. goto exit;
  619. // call remote procedure
  620. RpcTryExcept
  621. {
  622. dwRc = SRRemoveRestorePointS(srrpc_IfHandle, dwRPNum);
  623. }
  624. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  625. {
  626. dwRc = RpcExceptionCode();
  627. TRACE(0, "SRRemoveRestorePointS threw exception: error=%ld", dwRc);
  628. }
  629. RpcEndExcept
  630. // terminate
  631. SRRPCTerm(&srrpc_IfHandle);
  632. exit:
  633. TLEAVE();
  634. return dwRc;
  635. }
  636. // api to disable FIFO
  637. extern "C" DWORD WINAPI
  638. DisableFIFO(
  639. DWORD dwRPNum)
  640. {
  641. DWORD dwRc = ERROR_INTERNAL_ERROR;
  642. handle_t srrpc_IfHandle = NULL;
  643. TENTER("DisableFIFO");
  644. // initialize
  645. dwRc = SRRPCInit(&srrpc_IfHandle, TRUE);
  646. if (dwRc != ERROR_SUCCESS)
  647. {
  648. goto exit;
  649. }
  650. // call remote procedure
  651. RpcTryExcept
  652. {
  653. dwRc = DisableFIFOS(srrpc_IfHandle, dwRPNum);
  654. }
  655. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  656. {
  657. dwRc = RpcExceptionCode();
  658. TRACE(0, "DisableFIFOS threw exception: error=%ld", dwRc);
  659. }
  660. RpcEndExcept
  661. // terminate
  662. SRRPCTerm(&srrpc_IfHandle);
  663. exit:
  664. TLEAVE();
  665. return dwRc;
  666. }
  667. // api to enable FIFO
  668. extern "C" DWORD WINAPI
  669. EnableFIFO()
  670. {
  671. DWORD dwRc = ERROR_INTERNAL_ERROR;
  672. handle_t srrpc_IfHandle = NULL;
  673. TENTER("EnableFIFO");
  674. // initialize
  675. dwRc = SRRPCInit(&srrpc_IfHandle, TRUE);
  676. if (dwRc != ERROR_SUCCESS)
  677. {
  678. goto exit;
  679. }
  680. // call remote procedure
  681. RpcTryExcept
  682. {
  683. dwRc = EnableFIFOS(srrpc_IfHandle);
  684. }
  685. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  686. {
  687. dwRc = RpcExceptionCode();
  688. TRACE(0, "EnableFIFOS threw exception: error=%ld", dwRc);
  689. }
  690. RpcEndExcept
  691. // terminate
  692. SRRPCTerm(&srrpc_IfHandle);
  693. exit:
  694. TLEAVE();
  695. return dwRc;
  696. }
  697. // api to reset SR
  698. extern "C" DWORD WINAPI
  699. ResetSR(
  700. LPCWSTR pszDrive)
  701. {
  702. DWORD dwRc = ERROR_INTERNAL_ERROR;
  703. handle_t srrpc_IfHandle = NULL;
  704. TENTER("ResetSR");
  705. // initialize
  706. dwRc = SRRPCInit(&srrpc_IfHandle, TRUE);
  707. if (dwRc != ERROR_SUCCESS)
  708. {
  709. goto exit;
  710. }
  711. // call remote procedure
  712. RpcTryExcept
  713. {
  714. dwRc = ResetSRS(srrpc_IfHandle, pszDrive);
  715. }
  716. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  717. {
  718. dwRc = RpcExceptionCode();
  719. TRACE(0, "ResetSRS threw exception: error=%ld", dwRc);
  720. }
  721. RpcEndExcept
  722. // terminate
  723. SRRPCTerm(&srrpc_IfHandle);
  724. exit:
  725. TLEAVE();
  726. return dwRc;
  727. }
  728. // api to refresh the drive table from disk
  729. // restore UI will call this - service will update its drivetable in memory
  730. extern "C" DWORD WINAPI
  731. SRUpdateDSSize(LPCWSTR pszDrive, UINT64 ullSizeLimit)
  732. {
  733. DWORD dwRc = ERROR_INTERNAL_ERROR;
  734. handle_t srrpc_IfHandle = NULL;
  735. TENTER("SRUpdateDSSize");
  736. //
  737. // check if sr config is disabled via group policy
  738. //
  739. dwRc = CheckPolicy();
  740. if (dwRc != ERROR_SUCCESS)
  741. {
  742. goto exit;
  743. }
  744. // initialize
  745. dwRc = SRRPCInit(&srrpc_IfHandle, TRUE);
  746. if (dwRc != ERROR_SUCCESS)
  747. {
  748. goto exit;
  749. }
  750. // call remote procedure
  751. RpcTryExcept
  752. {
  753. dwRc = SRUpdateDSSizeS(srrpc_IfHandle, pszDrive, ullSizeLimit);
  754. }
  755. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  756. {
  757. dwRc = RpcExceptionCode();
  758. TRACE(0, "SRUpdateDSSizeS threw exception: error=%ld", dwRc);
  759. }
  760. RpcEndExcept
  761. // terminate
  762. SRRPCTerm(&srrpc_IfHandle);
  763. exit:
  764. TLEAVE();
  765. return dwRc;
  766. }
  767. extern "C" DWORD WINAPI
  768. SRSwitchLog()
  769. {
  770. DWORD dwRc = ERROR_INTERNAL_ERROR;
  771. handle_t srrpc_IfHandle = NULL;
  772. TENTER("SRSwitchLog");
  773. // initialize
  774. dwRc = SRRPCInit(&srrpc_IfHandle, FALSE);
  775. if (dwRc != ERROR_SUCCESS)
  776. {
  777. goto exit;
  778. }
  779. // call remote procedure
  780. RpcTryExcept
  781. {
  782. dwRc = SRSwitchLogS(srrpc_IfHandle);
  783. }
  784. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  785. {
  786. dwRc = RpcExceptionCode();
  787. TRACE(0, "SRSwitchLogS threw exception: error=%ld", dwRc);
  788. }
  789. RpcEndExcept
  790. // terminate
  791. SRRPCTerm(&srrpc_IfHandle);
  792. exit:
  793. TLEAVE();
  794. return dwRc;
  795. }
  796. extern "C" void WINAPI
  797. SRNotify(LPCWSTR pszDrive, DWORD dwFreeSpaceInMB, BOOL fImproving)
  798. {
  799. DWORD dwRc = ERROR_INTERNAL_ERROR;
  800. handle_t srrpc_IfHandle = NULL;
  801. TENTER("SRNotify");
  802. // initialize
  803. dwRc = SRRPCInit(&srrpc_IfHandle, FALSE);
  804. if (dwRc != ERROR_SUCCESS)
  805. {
  806. goto exit;
  807. }
  808. // call remote procedure
  809. RpcTryExcept
  810. {
  811. SRNotifyS(srrpc_IfHandle, pszDrive, dwFreeSpaceInMB, fImproving);
  812. }
  813. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  814. {
  815. dwRc = RpcExceptionCode();
  816. TRACE(0, "SRNotifyS threw exception: error=%ld", dwRc);
  817. }
  818. RpcEndExcept
  819. // terminate
  820. SRRPCTerm(&srrpc_IfHandle);
  821. exit:
  822. TLEAVE();
  823. return;
  824. }
  825. extern "C" void WINAPI
  826. SRPrintState()
  827. {
  828. DWORD dwRc = ERROR_INTERNAL_ERROR;
  829. handle_t srrpc_IfHandle = NULL;
  830. TENTER("SRPrintState");
  831. // initialize
  832. dwRc = SRRPCInit(&srrpc_IfHandle, FALSE);
  833. if (dwRc != ERROR_SUCCESS)
  834. {
  835. goto exit;
  836. }
  837. // call remote procedure
  838. RpcTryExcept
  839. {
  840. SRPrintStateS(srrpc_IfHandle);
  841. }
  842. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  843. {
  844. dwRc = RpcExceptionCode();
  845. TRACE(0, "SRPrintStateS threw exception: error=%ld", dwRc);
  846. }
  847. RpcEndExcept
  848. // terminate
  849. SRRPCTerm(&srrpc_IfHandle);
  850. exit:
  851. TLEAVE();
  852. return;
  853. }
  854. extern "C" DWORD WINAPI
  855. SRFifo(LPCWSTR pszDrive, DWORD dwTargetRp, int nPercent, BOOL fIncludeCurrentRp, BOOL fFifoAtleastOneRp)
  856. {
  857. DWORD dwRc = ERROR_INTERNAL_ERROR;
  858. handle_t srrpc_IfHandle = NULL;
  859. TENTER("Fifo");
  860. // initialize
  861. dwRc = SRRPCInit(&srrpc_IfHandle, TRUE);
  862. if (dwRc != ERROR_SUCCESS)
  863. {
  864. goto exit;
  865. }
  866. // call remote procedure
  867. RpcTryExcept
  868. {
  869. dwRc = FifoS(srrpc_IfHandle, pszDrive, dwTargetRp, nPercent, fIncludeCurrentRp, fFifoAtleastOneRp);
  870. }
  871. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  872. {
  873. dwRc = RpcExceptionCode();
  874. TRACE(0, "Fifo threw exception: error=%ld", dwRc);
  875. }
  876. RpcEndExcept
  877. // terminate
  878. SRRPCTerm(&srrpc_IfHandle);
  879. exit:
  880. TLEAVE();
  881. return dwRc;
  882. }
  883. extern "C" DWORD WINAPI
  884. SRCompress(LPCWSTR pszDrive)
  885. {
  886. DWORD dwRc = ERROR_INTERNAL_ERROR;
  887. handle_t srrpc_IfHandle = NULL;
  888. TENTER("Compress");
  889. // initialize
  890. dwRc = SRRPCInit(&srrpc_IfHandle, TRUE);
  891. if (dwRc != ERROR_SUCCESS)
  892. {
  893. goto exit;
  894. }
  895. // call remote procedure
  896. RpcTryExcept
  897. {
  898. dwRc = CompressS(srrpc_IfHandle, pszDrive);
  899. }
  900. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  901. {
  902. dwRc = RpcExceptionCode();
  903. TRACE(0, "Compress threw exception: error=%ld", dwRc);
  904. }
  905. RpcEndExcept
  906. // terminate
  907. SRRPCTerm(&srrpc_IfHandle);
  908. exit:
  909. TLEAVE();
  910. return dwRc;
  911. }
  912. extern "C" DWORD WINAPI
  913. SRFreeze(LPCWSTR pszDrive)
  914. {
  915. DWORD dwRc = ERROR_INTERNAL_ERROR;
  916. handle_t srrpc_IfHandle = NULL;
  917. TENTER("Freeze");
  918. // initialize
  919. dwRc = SRRPCInit(&srrpc_IfHandle, TRUE);
  920. if (dwRc != ERROR_SUCCESS)
  921. {
  922. goto exit;
  923. }
  924. // call remote procedure
  925. RpcTryExcept
  926. {
  927. dwRc = FreezeS(srrpc_IfHandle, pszDrive);
  928. }
  929. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  930. {
  931. dwRc = RpcExceptionCode();
  932. TRACE(0, "Freeze threw exception: error=%ld", dwRc);
  933. }
  934. RpcEndExcept
  935. // terminate
  936. SRRPCTerm(&srrpc_IfHandle);
  937. exit:
  938. TLEAVE();
  939. return dwRc;
  940. }
  941. // registration of callback method for third-parties to
  942. // do their own snapshotting and restoration for their components
  943. // clients will call this method with the full path of their dll.
  944. // system restore will call "CreateSnapshot" and "RestoreSnapshot"
  945. // methods in the registered dll when creating a restore point and
  946. // when restoring respectively
  947. extern "C" DWORD WINAPI
  948. SRRegisterSnapshotCallback(
  949. LPCWSTR pszDllPath)
  950. {
  951. DWORD dwErr = ERROR_SUCCESS;
  952. HKEY hKey = NULL;
  953. LPWSTR pszDllName = NULL;
  954. WCHAR szKey[MAX_PATH];
  955. DWORD dwDisposition;
  956. TENTER("RegisterSnapshotCallback");
  957. //
  958. // allow this only if admin or system
  959. //
  960. if (! IsAdminOrSystem())
  961. {
  962. dwErr = ERROR_ACCESS_DENIED;
  963. trace(0, "Not admin or system");
  964. goto Err;
  965. }
  966. if (pszDllPath == NULL)
  967. {
  968. dwErr = ERROR_INVALID_PARAMETER;
  969. trace(0, "pszDllPath = NULL");
  970. goto Err;
  971. }
  972. //
  973. // add the dll to Software\...\SystemRestore\SnapshotCallbacks
  974. // each dll will be a value
  975. // value name : name of dll, value: fullpath of dll
  976. // this way, the registration is idempotent
  977. //
  978. //
  979. // create/open the key
  980. //
  981. lstrcpy(szKey, s_cszSRRegKey);
  982. lstrcat(szKey, L"\\");
  983. lstrcat(szKey, s_cszCallbacksRegKey);
  984. CHECKERR( RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  985. szKey,
  986. 0,
  987. NULL,
  988. 0,
  989. KEY_ALL_ACCESS,
  990. NULL,
  991. &hKey,
  992. &dwDisposition),
  993. L"RegCreateKeyEx" );
  994. //
  995. // get the dll name from the path
  996. // if the path is not specified, this is same as input param
  997. //
  998. pszDllName = wcsrchr(pszDllPath, L'\\');
  999. if (pszDllName == NULL)
  1000. {
  1001. pszDllName = (LPWSTR) pszDllPath;
  1002. }
  1003. else
  1004. {
  1005. pszDllName++; // skip the '\'
  1006. }
  1007. //
  1008. // if the value already exists
  1009. // bail
  1010. //
  1011. if (ERROR_SUCCESS == RegQueryValueEx(hKey,
  1012. pszDllName,
  1013. 0,
  1014. NULL,
  1015. NULL,
  1016. NULL))
  1017. {
  1018. trace(0, "Dll is already registered");
  1019. dwErr = ERROR_ALREADY_EXISTS;
  1020. goto Err;
  1021. }
  1022. //
  1023. // add the value
  1024. //
  1025. CHECKERR(RegSetValueEx(hKey,
  1026. pszDllName,
  1027. 0,
  1028. REG_SZ,
  1029. (BYTE *) pszDllPath,
  1030. (lstrlen(pszDllPath)+1)*sizeof(WCHAR)),
  1031. L"RegSetValueEx");
  1032. trace(0, "Added %S as snapshot callback", pszDllPath);
  1033. Err:
  1034. if (hKey)
  1035. {
  1036. RegCloseKey(hKey);
  1037. }
  1038. TLEAVE();
  1039. return dwErr;
  1040. }
  1041. // corresponding unregistration function to above function
  1042. // clients can call this to unregister any snapshot callbacks
  1043. // they have already registered
  1044. extern "C" DWORD WINAPI
  1045. SRUnregisterSnapshotCallback(
  1046. LPCWSTR pszDllPath)
  1047. {
  1048. DWORD dwErr = ERROR_SUCCESS;
  1049. HKEY hKey = NULL;
  1050. LPWSTR pszDllName = NULL;
  1051. WCHAR szKey[MAX_PATH];
  1052. TENTER("SRUnregisterSnapshotCallback");
  1053. //
  1054. // allow this only if admin or system
  1055. //
  1056. if (! IsAdminOrSystem())
  1057. {
  1058. dwErr = ERROR_ACCESS_DENIED;
  1059. trace(0, "Not admin or system");
  1060. goto Err;
  1061. }
  1062. if (pszDllPath == NULL)
  1063. {
  1064. dwErr = ERROR_INVALID_PARAMETER;
  1065. trace(0, "pszDllPath = NULL");
  1066. goto Err;
  1067. }
  1068. //
  1069. // add the dll to Software\...\SystemRestore\SnapshotCallbacks
  1070. // each dll will be a value
  1071. // value name : name of dll, value: fullpath of dll
  1072. // this way, the registration is idempotent
  1073. //
  1074. //
  1075. // open the key
  1076. //
  1077. lstrcpy(szKey, s_cszSRRegKey);
  1078. lstrcat(szKey, L"\\");
  1079. lstrcat(szKey, s_cszCallbacksRegKey);
  1080. CHECKERR( RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  1081. szKey,
  1082. 0,
  1083. KEY_ALL_ACCESS,
  1084. &hKey),
  1085. L"RegOpenKeyEx" );
  1086. //
  1087. // get the dll name from the path
  1088. // if the path is not specified, this is same as input param
  1089. //
  1090. pszDllName = wcsrchr(pszDllPath, L'\\');
  1091. if (pszDllName == NULL)
  1092. {
  1093. pszDllName = (LPWSTR) pszDllPath;
  1094. }
  1095. else
  1096. {
  1097. pszDllName++; // skip the '\'
  1098. }
  1099. //
  1100. // remove the value
  1101. //
  1102. CHECKERR(RegDeleteValue(hKey,
  1103. pszDllName),
  1104. L"RegDeleteValue");
  1105. trace(0, "Removed %S from snapshot callback", pszDllPath);
  1106. Err:
  1107. if (hKey)
  1108. {
  1109. RegCloseKey(hKey);
  1110. }
  1111. TLEAVE();
  1112. return dwErr;
  1113. }
  1114. //
  1115. // test functions for snapshot callbacks
  1116. //
  1117. extern "C" DWORD WINAPI
  1118. CreateSnapshot(LPCWSTR pszSnapshotDir)
  1119. {
  1120. TENTER("CreateSnapshot");
  1121. WCHAR szFile[MAX_PATH];
  1122. wsprintf(szFile, L"%s\\srclient.txt", pszSnapshotDir);
  1123. DebugTrace(0, "Callback createsnapshot");
  1124. if (FALSE == CopyFile(L"c:\\srclient.txt", szFile, FALSE))
  1125. {
  1126. trace(0, "! CopyFile");
  1127. }
  1128. TLEAVE();
  1129. return ERROR_SUCCESS;
  1130. }
  1131. extern "C" DWORD WINAPI
  1132. RestoreSnapshot(LPCWSTR pszSnapshotDir)
  1133. {
  1134. TENTER("RestoreSnapshot");
  1135. WCHAR szFile[MAX_PATH];
  1136. wsprintf(szFile, L"%s\\srclient.txt", pszSnapshotDir);
  1137. DebugTrace(0, "Callback restoresnapshot");
  1138. if (FALSE == CopyFile(szFile, L"c:\\restored.txt", FALSE))
  1139. {
  1140. trace(0, "! CopyFile");
  1141. }
  1142. TLEAVE();
  1143. return ERROR_SUCCESS;
  1144. }
  1145. // alloc/dealloc functions for midl compiler
  1146. void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
  1147. {
  1148. return(SRMemAlloc((DWORD) len));
  1149. }
  1150. void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
  1151. {
  1152. SRMemFree(ptr);
  1153. }