Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

956 lines
22 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1999
  5. //
  6. // File: backup.cpp
  7. //
  8. // Contents: Cert Server client database backup APIs
  9. //
  10. //---------------------------------------------------------------------------
  11. #include <pch.cpp>
  12. #pragma hdrstop
  13. #include "certsrvd.h"
  14. #include "csdisp.h"
  15. #include "certadmp.h"
  16. #define __dwFILE__ __dwFILE_CERTADM_BACKUP_CPP__
  17. #if DBG
  18. #define _CERTBCLI_TYPECHECK
  19. #endif
  20. #include <certbcli.h>
  21. WCHAR g_wszBackupAnnotation[] = L"backup";
  22. WCHAR g_wszRestoreAnnotation[] = L"restore";
  23. HRESULT
  24. AllocateContext(
  25. IN WCHAR const *pwszConfig,
  26. OUT CSBACKUPCONTEXT **ppcsbc)
  27. {
  28. HRESULT hr;
  29. WCHAR *pwszT = NULL;
  30. CSASSERT(NULL != pfnCertSrvIsServerOnline);
  31. pwszT = (WCHAR *) LocalAlloc(
  32. LMEM_FIXED,
  33. (wcslen(pwszConfig) + 1) * sizeof(WCHAR));
  34. if (NULL == pwszT)
  35. {
  36. hr = E_OUTOFMEMORY;
  37. _JumpError(hr, error, "LocalAlloc");
  38. }
  39. wcscpy(pwszT, pwszConfig);
  40. *ppcsbc = (CSBACKUPCONTEXT *) LocalAlloc(
  41. LMEM_FIXED | LMEM_ZEROINIT,
  42. sizeof(**ppcsbc));
  43. if (NULL == *ppcsbc)
  44. {
  45. hr = E_OUTOFMEMORY;
  46. _JumpError(hr, error, "LocalAlloc");
  47. }
  48. (*ppcsbc)->pwszConfig = pwszT;
  49. pwszT = NULL;
  50. hr = S_OK;
  51. error:
  52. if (NULL != pwszT)
  53. {
  54. LocalFree(pwszT);
  55. }
  56. return(hr);
  57. }
  58. VOID
  59. ReleaseContext(
  60. IN OUT CSBACKUPCONTEXT *pcsbc)
  61. {
  62. CSASSERT(NULL != pcsbc);
  63. if (NULL != pcsbc->pwszConfig)
  64. {
  65. LocalFree(const_cast<WCHAR *>(pcsbc->pwszConfig));
  66. pcsbc->pwszConfig = NULL;
  67. }
  68. if (NULL != pcsbc->pICertAdminD)
  69. {
  70. CloseAdminServer(&pcsbc->pICertAdminD);
  71. CSASSERT(NULL == pcsbc->pICertAdminD);
  72. }
  73. if (NULL != pcsbc->pbReadBuffer)
  74. {
  75. VirtualFree(pcsbc->pbReadBuffer, 0, MEM_RELEASE);
  76. }
  77. LocalFree(pcsbc);
  78. }
  79. HRESULT
  80. OpenAdminServer(
  81. IN WCHAR const *pwszConfig,
  82. OUT WCHAR const **ppwszAuthority,
  83. OUT DWORD *pdwServerVersion,
  84. OUT ICertAdminD2 **ppICertAdminD)
  85. {
  86. HRESULT hr;
  87. BOOL fCoInitialized = FALSE;
  88. hr = CoInitialize(NULL);
  89. if (RPC_E_CHANGED_MODE == hr)
  90. {
  91. _PrintError(hr, "CoInitialize");
  92. hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
  93. }
  94. if (S_OK != hr && S_FALSE != hr)
  95. {
  96. _JumpError(hr, error, "CoInitialize");
  97. }
  98. fCoInitialized = TRUE;
  99. *pdwServerVersion = 0;
  100. hr = myOpenAdminDComConnection(
  101. pwszConfig,
  102. ppwszAuthority,
  103. NULL,
  104. pdwServerVersion,
  105. ppICertAdminD);
  106. _JumpIfError(hr, error, "myOpenDComConnection");
  107. CSASSERT(0 != *pdwServerVersion);
  108. error:
  109. if (S_OK != hr && fCoInitialized)
  110. {
  111. CoUninitialize();
  112. }
  113. return(hr);
  114. }
  115. VOID
  116. CloseAdminServer(
  117. IN OUT ICertAdminD2 **ppICertAdminD)
  118. {
  119. myCloseDComConnection((IUnknown **) ppICertAdminD, NULL);
  120. CoUninitialize();
  121. }
  122. //+--------------------------------------------------------------------------
  123. // CertSrvIsServerOnline -- check to see if the Cert Server is Online on the
  124. // given server. This call is guaranteed to return quickly.
  125. //
  126. // Parameters:
  127. // [in] pwszConfig - name of the server to check
  128. // [out] pfServerOnline - pointer to receive the bool result
  129. // (TRUE if Cert Server is online; FALSE, otherwise)
  130. // Returns:
  131. // S_OK if the call executed successfully;
  132. // Failure code otherwise.
  133. //+--------------------------------------------------------------------------
  134. HRESULT
  135. CERTBCLI_API
  136. CertSrvIsServerOnlineW(
  137. IN WCHAR const *pwszConfig,
  138. OPTIONAL OUT BOOL *pfServerOnline)
  139. {
  140. HRESULT hr;
  141. ICertAdminD2 *pICertAdminD = NULL;
  142. WCHAR const *pwszAuthority;
  143. DWORD State;
  144. DWORD dwServerVersion;
  145. if (NULL == pwszConfig)
  146. {
  147. hr = E_POINTER;
  148. _JumpError(hr, error, "NULL parm");
  149. }
  150. __try
  151. {
  152. if (NULL != pfServerOnline)
  153. {
  154. *pfServerOnline = FALSE;
  155. }
  156. hr = OpenAdminServer(
  157. pwszConfig,
  158. &pwszAuthority,
  159. &dwServerVersion,
  160. &pICertAdminD);
  161. // OpenAdminServer etc might get E_ACCESSDENIED -- meaning server down
  162. if (S_OK != hr)
  163. {
  164. _PrintError(hr, "OpenAdminServer");
  165. if (E_ACCESSDENIED == hr || (HRESULT) ERROR_ACCESS_DENIED == hr)
  166. {
  167. hr = S_OK;
  168. }
  169. __leave;
  170. }
  171. hr = pICertAdminD->GetServerState(pwszAuthority, &State);
  172. _LeaveIfError(hr, "GetServerState");
  173. if (NULL != pfServerOnline && 0 != State)
  174. {
  175. *pfServerOnline = TRUE;
  176. }
  177. }
  178. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  179. {
  180. }
  181. error:
  182. if (NULL != pICertAdminD)
  183. {
  184. CloseAdminServer(&pICertAdminD);
  185. }
  186. return(hr);
  187. }
  188. //+--------------------------------------------------------------------------
  189. // CertSrvBackupPrepare -- prepare the DS for the online backup and return a
  190. // Backup Context Handle to be used for subsequent calls to backup
  191. // functions.
  192. //
  193. // Parameters:
  194. // [in] pwszConfig - server name to prepare for online backup
  195. // [in] grbitJet - flag to be passed to jet while backing up dbs
  196. // [in] dwBackupFlags - CSBACKUP_TYPE_FULL or CSBACKUP_TYPE_LOGS_ONLY
  197. // [out] phbc - pointer that will receive the backup context handle
  198. //
  199. // Returns:
  200. // S_OK if the call executed successfully;
  201. // Failure code otherwise.
  202. //---------------------------------------------------------------------------
  203. HRESULT
  204. CERTBCLI_API
  205. CertSrvBackupPrepareW(
  206. IN WCHAR const *pwszConfig,
  207. IN ULONG grbitJet,
  208. IN ULONG dwBackupFlags,
  209. OUT HCSBC *phbc)
  210. {
  211. HRESULT hr;
  212. CSBACKUPCONTEXT *pcsbc = NULL;
  213. if (NULL == pwszConfig || NULL == phbc)
  214. {
  215. hr = E_POINTER;
  216. _JumpError(hr, error, "NULL parm");
  217. }
  218. *phbc = NULL;
  219. if (CSBACKUP_TYPE_LOGS_ONLY == dwBackupFlags)
  220. {
  221. grbitJet |= JET_bitBackupIncremental;
  222. }
  223. else if (CSBACKUP_TYPE_FULL != dwBackupFlags)
  224. {
  225. hr = E_INVALIDARG;
  226. _JumpError(hr, error, "dwBackupFlags");
  227. }
  228. __try
  229. {
  230. hr = AllocateContext(pwszConfig, &pcsbc);
  231. _LeaveIfError(hr, "AllocateContext");
  232. hr = OpenAdminServer(
  233. pcsbc->pwszConfig,
  234. &pcsbc->pwszAuthority,
  235. &pcsbc->dwServerVersion,
  236. &pcsbc->pICertAdminD);
  237. _LeaveIfError(hr, "OpenAdminServer");
  238. hr = pcsbc->pICertAdminD->BackupPrepare(
  239. pcsbc->pwszAuthority,
  240. grbitJet,
  241. dwBackupFlags,
  242. g_wszBackupAnnotation,
  243. 0); // dwClientIdentifier
  244. _LeaveIfError(hr, "BackupPrepare");
  245. *phbc = (HCSBC) pcsbc;
  246. pcsbc = NULL;
  247. }
  248. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  249. {
  250. }
  251. error:
  252. if (NULL != pcsbc)
  253. {
  254. ReleaseContext(pcsbc);
  255. }
  256. return(hr);
  257. }
  258. // Return the length of a double '\0' terminated string -- includes the
  259. // trailing '\0's.
  260. DWORD
  261. mySzzLen(
  262. CHAR const *pszz)
  263. {
  264. CHAR const *psz;
  265. DWORD cb;
  266. psz = pszz;
  267. do
  268. {
  269. cb = strlen(psz);
  270. psz += cb + 1;
  271. } while (0 != cb);
  272. return SAFE_SUBTRACT_POINTERS(psz, pszz); // includes double trailing '\0's
  273. }
  274. HRESULT
  275. myLocalAllocCopy(
  276. IN VOID *pbIn,
  277. IN DWORD cbIn,
  278. OUT VOID **pbOut)
  279. {
  280. HRESULT hr;
  281. *pbOut = LocalAlloc(LMEM_FIXED, cbIn);
  282. if (NULL == *pbOut)
  283. {
  284. hr = E_OUTOFMEMORY;
  285. _JumpError(hr, error, "LocalAlloc");
  286. }
  287. CopyMemory(*pbOut, pbIn, cbIn);
  288. hr = S_OK;
  289. error:
  290. return(hr);
  291. }
  292. HRESULT
  293. BackupRestoreGetFileList(
  294. IN DWORD FileListType,
  295. IN HCSBC hbc,
  296. OUT WCHAR **ppwszzFileList,
  297. OUT DWORD *pcbList)
  298. {
  299. HRESULT hr;
  300. CSBACKUPCONTEXT *pcsbc;
  301. WCHAR *pwszzFileList = NULL;
  302. LONG cwcList;
  303. DWORD cbList;
  304. if (NULL == hbc)
  305. {
  306. hr = E_HANDLE;
  307. _JumpError(hr, error, "NULL handle");
  308. }
  309. if (NULL != ppwszzFileList)
  310. {
  311. *ppwszzFileList = NULL;
  312. }
  313. if (NULL != pcbList)
  314. {
  315. *pcbList = 0;
  316. }
  317. if (NULL == ppwszzFileList || NULL == pcbList)
  318. {
  319. hr = E_POINTER;
  320. _JumpError(hr, error, "NULL parm");
  321. }
  322. pcsbc = (CSBACKUPCONTEXT *) hbc;
  323. __try
  324. {
  325. if (NULL == pcsbc->pICertAdminD)
  326. {
  327. hr = OpenAdminServer(
  328. pcsbc->pwszConfig,
  329. &pcsbc->pwszAuthority,
  330. &pcsbc->dwServerVersion,
  331. &pcsbc->pICertAdminD);
  332. _LeaveIfError(hr, "OpenAdminServer");
  333. }
  334. CSASSERT(NULL != pcsbc->pICertAdminD);
  335. if (FLT_DBFILES == FileListType)
  336. {
  337. hr = pcsbc->pICertAdminD->BackupGetAttachmentInformation(
  338. &pwszzFileList,
  339. &cwcList);
  340. _LeaveIfError(hr, "BackupGetAttachmentInformation");
  341. }
  342. else if (FLT_LOGFILES == FileListType)
  343. {
  344. hr = pcsbc->pICertAdminD->BackupGetBackupLogs(
  345. &pwszzFileList,
  346. &cwcList);
  347. _LeaveIfError(hr, "BackupGetBackupLogs");
  348. }
  349. else if (FLT_DYNAMICFILES == FileListType)
  350. {
  351. hr = pcsbc->pICertAdminD->BackupGetDynamicFiles(
  352. &pwszzFileList,
  353. &cwcList);
  354. _LeaveIfError(hr, "BackupGetDynamicFileList");
  355. }
  356. else
  357. {
  358. CSASSERT(FLT_RESTOREDBLOCATIONS == FileListType);
  359. hr = pcsbc->pICertAdminD->RestoreGetDatabaseLocations(
  360. &pwszzFileList,
  361. &cwcList);
  362. _LeaveIfError(hr, "RestoreGetDatabaseLocations");
  363. }
  364. cbList = cwcList * sizeof(WCHAR);
  365. myRegisterMemAlloc(pwszzFileList, cbList, CSM_COTASKALLOC);
  366. hr = myLocalAllocCopy(pwszzFileList, cbList, (VOID **) ppwszzFileList);
  367. _JumpIfError(hr, error, "myLocalAllocCopy");
  368. *pcbList = cbList;
  369. }
  370. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  371. {
  372. }
  373. error:
  374. if (NULL != pwszzFileList)
  375. {
  376. CoTaskMemFree(pwszzFileList);
  377. }
  378. return(hr);
  379. }
  380. //+--------------------------------------------------------------------------
  381. // CertSrvBackupGetDatabaseNames -- return the list of data bases that need to
  382. // be backed up for the given backup context The information returned in
  383. // ppwszzFileList should not be interpreted, as it only has meaning on
  384. // the server being backed up.
  385. //
  386. // This API will allocate a buffer of sufficient size to hold the entire
  387. // attachment list, which must be later freed with CertSrvBackupFree.
  388. //
  389. // Parameters:
  390. // [in] hbc - backup context handle
  391. // [out] ppwszzFileList - pointer that will receive the pointer to the
  392. // attachment info; allocated memory should be freed using
  393. // CertSrvBackupFree() API by the caller when it is no longer
  394. // needed; ppwszzFileList info is an array of null-terminated
  395. // filenames and the list is terminated by two L'\0's.
  396. // [out] pcbList - will receive the number of bytes returned
  397. //
  398. // Returns:
  399. // S_OK if the call executed successfully;
  400. // Failure code otherwise.
  401. //---------------------------------------------------------------------------
  402. HRESULT
  403. CERTBCLI_API
  404. CertSrvBackupGetDatabaseNamesW(
  405. IN HCSBC hbc,
  406. OUT WCHAR **ppwszzFileList,
  407. OUT DWORD *pcbList)
  408. {
  409. HRESULT hr;
  410. hr = BackupRestoreGetFileList(FLT_DBFILES, hbc, ppwszzFileList, pcbList);
  411. _JumpIfError(hr, error, "BackupRestoreGetFileList");
  412. error:
  413. return(hr);
  414. }
  415. //+--------------------------------------------------------------------------
  416. // CertSrvBackupGetDynamicFileList -- return the list of dynamic files that
  417. // need to be backed up for the given backup context The information
  418. // returned in ppwszzFileList should not be interpreted, as it only has
  419. // meaning on the server being backed up.
  420. //
  421. // This API will allocate a buffer of sufficient size to hold the entire
  422. // attachment list, which must be later freed with CertSrvBackupFree.
  423. //
  424. // Parameters:
  425. // [in] hbc - backup context handle
  426. // [out] ppwszzFileList - pointer that will receive the pointer to the
  427. // attachment info; allocated memory should be freed using
  428. // CertSrvBackupFree() API by the caller when it is no longer
  429. // needed; ppwszzFileList info is an array of null-terminated
  430. // filenames and the list is terminated by two L'\0's.
  431. // [out] pcbList - will receive the number of bytes returned
  432. //
  433. // Returns:
  434. // S_OK if the call executed successfully;
  435. // Failure code otherwise.
  436. //---------------------------------------------------------------------------
  437. HRESULT
  438. CERTBCLI_API
  439. CertSrvBackupGetDynamicFileListW(
  440. IN HCSBC hbc,
  441. OUT WCHAR **ppwszzFileList,
  442. OUT DWORD *pcbList)
  443. {
  444. HRESULT hr;
  445. hr = BackupRestoreGetFileList(
  446. FLT_DYNAMICFILES,
  447. hbc,
  448. ppwszzFileList,
  449. pcbList);
  450. _JumpIfError(hr, error, "BackupRestoreGetFileList");
  451. error:
  452. return(hr);
  453. }
  454. #define CBREADMIN (64 * 1024) // 64k minimum buffer
  455. #define CBREADDEFAULT (512 * 1024) // 512k recommended
  456. #define CBREADMAX (4 * 1024 * 1024) // 4mb maximum buffer
  457. HRESULT
  458. BufferAllocate(
  459. IN DWORD cbHintSize,
  460. OUT BYTE **ppbBuffer,
  461. OUT DWORD *pcbBuffer)
  462. {
  463. HRESULT hr;
  464. DWORD cb;
  465. *ppbBuffer = NULL;
  466. if (0 == cbHintSize)
  467. {
  468. // at 512k the server begins doing efficient backups
  469. cbHintSize = CBREADDEFAULT;
  470. }
  471. else if (CBREADMIN > cbHintSize)
  472. {
  473. cbHintSize = CBREADMIN;
  474. }
  475. for (cb = CBREADMAX; (cb >> 1) >= cbHintSize; cb >>= 1)
  476. ;
  477. while (TRUE)
  478. {
  479. *ppbBuffer = (BYTE *) VirtualAlloc(
  480. NULL,
  481. cb,
  482. MEM_COMMIT,
  483. PAGE_READWRITE);
  484. if (NULL != *ppbBuffer)
  485. {
  486. break;
  487. }
  488. hr = myHLastError();
  489. CSASSERT(S_OK == hr);
  490. _PrintError(hr, "VirtualAlloc");
  491. cb >>= 1;
  492. if (CBREADMIN > cb)
  493. {
  494. goto error;
  495. }
  496. }
  497. *pcbBuffer = cb;
  498. hr = S_OK;
  499. error:
  500. return(hr);
  501. }
  502. //+--------------------------------------------------------------------------
  503. // CertSrvBackupOpenFile -- open a remote file for backup, and perform whatever
  504. // client and server side operations to prepare for the backup.
  505. // It takes in a hint of the size of the buffer that will later be passed
  506. // into the CertSrvBackupRead API that can be used to optimize the network
  507. // traffic for the API.
  508. //
  509. // Parameters:
  510. // [in] hbc - backup context handle
  511. // [in] pwszPath - name of the attachment to be opened for read
  512. // [in] cbReadHintSize - suggested size in bytes that might be used
  513. // during the subsequent reads on this attachment
  514. // [out] pliFileSize - pointer to a large integer that would receive the
  515. // size in bytes of the given attachment
  516. // Returns:
  517. // S_OK if the call executed successfully;
  518. // Failure code otherwise.
  519. //---------------------------------------------------------------------------
  520. HRESULT
  521. CERTBCLI_API
  522. CertSrvBackupOpenFileW(
  523. IN HCSBC hbc,
  524. IN WCHAR const *pwszPath,
  525. IN DWORD cbReadHintSize,
  526. OUT LARGE_INTEGER *pliFileSize)
  527. {
  528. HRESULT hr;
  529. CSBACKUPCONTEXT *pcsbc;
  530. if (NULL == hbc)
  531. {
  532. hr = E_HANDLE;
  533. _JumpError(hr, error, "NULL handle");
  534. }
  535. if (NULL == pwszPath || NULL == pliFileSize)
  536. {
  537. hr = E_POINTER;
  538. _JumpError(hr, error, "NULL parm");
  539. }
  540. pcsbc = (CSBACKUPCONTEXT *) hbc;
  541. if (pcsbc->fFileOpen)
  542. {
  543. hr = HRESULT_FROM_WIN32(ERROR_BUSY);
  544. _JumpError(hr, error, "File already open");
  545. }
  546. __try
  547. {
  548. hr = pcsbc->pICertAdminD->BackupOpenFile(
  549. pwszPath,
  550. (ULONGLONG *) pliFileSize);
  551. _LeaveIfErrorStr(hr, "BackupOpenFile", pwszPath);
  552. if (NULL == pcsbc->pbReadBuffer)
  553. {
  554. hr = BufferAllocate(
  555. cbReadHintSize,
  556. &pcsbc->pbReadBuffer,
  557. &pcsbc->cbReadBuffer);
  558. _LeaveIfError(hr, "BufferAllocate");
  559. }
  560. pcsbc->fFileOpen = TRUE;
  561. pcsbc->cbCache = 0;
  562. }
  563. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  564. {
  565. }
  566. error:
  567. return(hr);
  568. }
  569. //+--------------------------------------------------------------------------
  570. // CertSrvBackupRead -- read the currently open attachment bytes into the given
  571. // buffer. The client application is expected to call this function
  572. // repeatedly until it gets the entire file (the application would have
  573. // received the file size through the CertSrvBackupOpenFile call before.
  574. //
  575. // Parameters:
  576. // [in] hbc - backup context handle
  577. // [in] pvBuffer - pointer to the buffer that would receive the read data.
  578. // [in] cbBuffer - specifies the size of the above buffer
  579. // [out] pcbRead - pointer to receive the actual number of bytes read.
  580. //
  581. // Returns:
  582. // HRESULT - The status of the operation.
  583. // S_OK if successful.
  584. // ERROR_END_OF_FILE if the end of file was reached while being backed up
  585. // Other Win32 and RPC error code.
  586. //
  587. // Note:
  588. // It is important to realize that pcbRead may be less than cbBuffer.
  589. // This does not indicate an error, some transports may choose to fragment
  590. // the buffer being transmitted instead of returning the entire buffers
  591. // worth of data.
  592. //---------------------------------------------------------------------------
  593. HRESULT
  594. CERTBCLI_API
  595. CertSrvBackupRead(
  596. IN HCSBC hbc,
  597. IN VOID *pvBuffer,
  598. IN DWORD cbBuffer,
  599. OUT DWORD *pcbRead)
  600. {
  601. HRESULT hr;
  602. CSBACKUPCONTEXT *pcsbc;
  603. BYTE *pbBuffer = (BYTE *) pvBuffer;
  604. DWORD cbRead;
  605. DWORD cb;
  606. hr = E_HANDLE;
  607. if (NULL == hbc)
  608. {
  609. _JumpError(hr, error, "NULL handle");
  610. }
  611. if (NULL == pvBuffer || NULL == pcbRead)
  612. {
  613. hr = E_POINTER;
  614. _JumpError(hr, error, "NULL parm");
  615. }
  616. *pcbRead = 0;
  617. pcsbc = (CSBACKUPCONTEXT *) hbc;
  618. if (NULL == pcsbc->pbReadBuffer)
  619. {
  620. _JumpError(hr, error, "NULL buffer");
  621. }
  622. if (!pcsbc->fFileOpen)
  623. {
  624. _JumpError(hr, error, "File not open");
  625. }
  626. while (TRUE)
  627. {
  628. if (0 != pcsbc->cbCache)
  629. {
  630. cb = min(pcsbc->cbCache, cbBuffer);
  631. CopyMemory(pbBuffer, pcsbc->pbCache, cb);
  632. pbBuffer += cb;
  633. cbBuffer -= cb;
  634. pcsbc->pbCache += cb;
  635. pcsbc->cbCache -= cb;
  636. *pcbRead += cb;
  637. }
  638. if (0 == cbBuffer)
  639. {
  640. hr = S_OK;
  641. break; // request satisfied
  642. }
  643. pcsbc->cbCache = 0;
  644. __try
  645. {
  646. hr = pcsbc->pICertAdminD->BackupReadFile(
  647. pcsbc->pbReadBuffer,
  648. pcsbc->cbReadBuffer,
  649. (LONG *) &cbRead);
  650. _LeaveIfError(hr, "BackupReadFile");
  651. }
  652. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  653. {
  654. }
  655. if (S_OK != hr || 0 == cbRead)
  656. {
  657. break; // EOF
  658. }
  659. pcsbc->cbCache = cbRead;
  660. pcsbc->pbCache = pcsbc->pbReadBuffer;
  661. }
  662. error:
  663. return(hr);
  664. }
  665. //+--------------------------------------------------------------------------
  666. // CertSrvBackupClose -- called by the application after it completes reading
  667. // all the data in the currently opened attachement.
  668. //
  669. // Parameters:
  670. // [in] hbc - backup context handle
  671. //
  672. // Returns:
  673. // S_OK if the call executed successfully;
  674. // Failure code otherwise.
  675. //---------------------------------------------------------------------------
  676. HRESULT
  677. CERTBCLI_API
  678. CertSrvBackupClose(
  679. IN HCSBC hbc)
  680. {
  681. HRESULT hr;
  682. CSBACKUPCONTEXT *pcsbc;
  683. hr = E_HANDLE;
  684. if (NULL == hbc)
  685. {
  686. _JumpError(hr, error, "NULL handle");
  687. }
  688. pcsbc = (CSBACKUPCONTEXT *) hbc;
  689. if (!pcsbc->fFileOpen)
  690. {
  691. _JumpError(hr, error, "File not open");
  692. }
  693. __try
  694. {
  695. hr = pcsbc->pICertAdminD->BackupCloseFile();
  696. _LeaveIfError(hr, "BackupCloseFile");
  697. }
  698. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  699. {
  700. }
  701. // Clear flag even on failure...
  702. pcsbc->fFileOpen = FALSE;
  703. error:
  704. return(hr);
  705. }
  706. //+--------------------------------------------------------------------------
  707. // CertSrvBackupGetBackupLogs -- return the list of log files that need to be
  708. // backed up for the given backup context
  709. //
  710. // This API will allocate a buffer of sufficient size to hold the entire
  711. // backup log list, which must be later freed with CertSrvBackupFree.
  712. //
  713. // Parameters:
  714. // [in] hbc - backup context handle
  715. // [out] pszBackupLogFiles - pointer that will receive the pointer to the
  716. // list of log files; allocated memory should be freed using
  717. // CertSrvBackupFree() API by the caller when it is no longer
  718. // needed; Log files are returned in an array of null-terminated
  719. // filenames and the list is terminated by two L'\0's.
  720. // [out] pcbList - will receive the number of bytes returned
  721. //
  722. // Returns:
  723. // S_OK if the call executed successfully;
  724. // Failure code otherwise.
  725. //---------------------------------------------------------------------------
  726. HRESULT
  727. CERTBCLI_API
  728. CertSrvBackupGetBackupLogsW(
  729. IN HCSBC hbc,
  730. OUT WCHAR **ppwszzFileList,
  731. OUT DWORD *pcbList)
  732. {
  733. HRESULT hr;
  734. hr = BackupRestoreGetFileList(
  735. FLT_LOGFILES,
  736. hbc,
  737. ppwszzFileList,
  738. pcbList);
  739. _JumpIfError(hr, error, "BackupRestoreGetFileList");
  740. error:
  741. return(hr);
  742. }
  743. //+--------------------------------------------------------------------------
  744. // CertSrvBackupTruncateLogs -- terminate the backup operation. Called when
  745. // the backup has completed successfully.
  746. //
  747. // Parameters:
  748. // [in] hbc - backup context handle
  749. //
  750. // Returns:
  751. // S_OK if the call executed successfully;
  752. // Failure code otherwise.
  753. //
  754. // Note:
  755. // Again, this API may have to take a grbit parameter to be passed to the
  756. // server to indicate the backup type.
  757. //---------------------------------------------------------------------------
  758. HRESULT
  759. CERTBCLI_API
  760. CertSrvBackupTruncateLogs(
  761. IN HCSBC hbc)
  762. {
  763. HRESULT hr;
  764. CSBACKUPCONTEXT *pcsbc;
  765. if (NULL == hbc)
  766. {
  767. hr = E_HANDLE;
  768. _JumpError(hr, error, "NULL handle");
  769. }
  770. pcsbc = (CSBACKUPCONTEXT *) hbc;
  771. __try
  772. {
  773. hr = pcsbc->pICertAdminD->BackupTruncateLogs();
  774. _LeaveIfError(hr, "BackupTruncateLogs");
  775. }
  776. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  777. {
  778. }
  779. error:
  780. return(hr);
  781. }
  782. //+--------------------------------------------------------------------------
  783. // CertSrvBackupEnd -- clean up after a backup operation has been performed.
  784. // This API will close outstanding binding handles, and do whatever is
  785. // necessary to clean up after successful/unsuccesful backup attempts.
  786. //
  787. // Parameters:
  788. // [in] hbc - backup context handle of the backup session
  789. //
  790. // Returns:
  791. // S_OK if the call executed successfully;
  792. // Failure code otherwise.
  793. //---------------------------------------------------------------------------
  794. HRESULT
  795. CERTBCLI_API
  796. CertSrvBackupEnd(
  797. IN HCSBC hbc)
  798. {
  799. HRESULT hr;
  800. CSBACKUPCONTEXT *pcsbc;
  801. if (NULL == hbc)
  802. {
  803. hr = E_HANDLE;
  804. _JumpError(hr, error, "NULL handle");
  805. }
  806. pcsbc = (CSBACKUPCONTEXT *) hbc;
  807. __try
  808. {
  809. hr = pcsbc->pICertAdminD->BackupEnd();
  810. _LeaveIfError(hr, "BackupEnd");
  811. ReleaseContext((CSBACKUPCONTEXT *) hbc);
  812. hr = S_OK;
  813. }
  814. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  815. {
  816. }
  817. error:
  818. return(hr);
  819. }
  820. //+--------------------------------------------------------------------------
  821. // CertSrvBackupFree -- free any buffer allocated by certbcli.dll APIs.
  822. //
  823. // Parameters:
  824. // [in] pv - pointer to the buffer that is to be freed.
  825. //
  826. // Returns:
  827. // None.
  828. //---------------------------------------------------------------------------
  829. VOID
  830. CERTBCLI_API
  831. CertSrvBackupFree(
  832. IN VOID *pv)
  833. {
  834. LocalFree(pv);
  835. }