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.

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