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.

862 lines
18 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1999
  5. //
  6. // File: row.cpp
  7. //
  8. // Contents: Cert Server Database interface implementation
  9. //
  10. //---------------------------------------------------------------------------
  11. #include <pch.cpp>
  12. #pragma hdrstop
  13. #include "csdisp.h"
  14. #include "csprop.h"
  15. #include "row.h"
  16. #include "enum.h"
  17. #include "db.h"
  18. #include "dbw.h"
  19. #define __dwFILE__ __dwFILE_CERTDB_ROW_CPP__
  20. #if DBG
  21. LONG g_cCertDBRow;
  22. LONG g_cCertDBRowTotal;
  23. #endif
  24. CCertDBRow::CCertDBRow()
  25. {
  26. DBGCODE(InterlockedIncrement(&g_cCertDBRow));
  27. DBGCODE(InterlockedIncrement(&g_cCertDBRowTotal));
  28. m_pdb = NULL;
  29. m_pcs = NULL;
  30. m_cRef = 1;
  31. }
  32. CCertDBRow::~CCertDBRow()
  33. {
  34. DBGCODE(InterlockedDecrement(&g_cCertDBRow));
  35. _Cleanup();
  36. }
  37. VOID
  38. CCertDBRow::_Cleanup()
  39. {
  40. HRESULT hr;
  41. if (NULL != m_pdb)
  42. {
  43. if (NULL != m_pcs)
  44. {
  45. hr = ((CCertDB *) m_pdb)->CloseTables(m_pcs);
  46. _PrintIfError(hr, "CloseTables");
  47. hr = ((CCertDB *) m_pdb)->ReleaseSession(m_pcs);
  48. _PrintIfError(hr, "ReleaseSession");
  49. m_pcs = NULL;
  50. }
  51. m_pdb->Release();
  52. m_pdb = NULL;
  53. }
  54. }
  55. HRESULT
  56. CCertDBRow::Open(
  57. IN CERTSESSION *pcs,
  58. IN ICertDB *pdb,
  59. OPTIONAL IN CERTVIEWRESTRICTION const *pcvr)
  60. {
  61. HRESULT hr;
  62. bool fBeginTransaction = false;
  63. _Cleanup();
  64. if (NULL == pcs || NULL == pdb)
  65. {
  66. hr = E_POINTER;
  67. _JumpError(hr, error, "NULL parm");
  68. }
  69. m_pdb = pdb;
  70. m_pdb->AddRef();
  71. CSASSERT(0 == pcs->cTransact);
  72. if (!(CSF_READONLY & pcs->SesFlags))
  73. {
  74. hr = ((CCertDB *) m_pdb)->BeginTransaction(pcs, FALSE);
  75. _JumpIfError(hr, error, "BeginTransaction");
  76. }
  77. fBeginTransaction = true;
  78. hr = ((CCertDB *) m_pdb)->OpenTables(pcs, pcvr);
  79. _JumpIfError2(hr, error, "OpenTables", CERTSRV_E_PROPERTY_EMPTY);
  80. m_pcs = pcs;
  81. error:
  82. if (S_OK != hr)
  83. {
  84. if(fBeginTransaction && !(CSF_READONLY & pcs->SesFlags))
  85. {
  86. HRESULT hr2;
  87. hr2 = ((CCertDB *) m_pdb)->CommitTransaction(pcs, FALSE, FALSE);
  88. _PrintIfError(hr2, "CommitTransaction");
  89. }
  90. _Cleanup();
  91. }
  92. return(hr);
  93. }
  94. STDMETHODIMP
  95. CCertDBRow::BeginTransaction(VOID)
  96. {
  97. HRESULT hr;
  98. if (NULL == m_pdb)
  99. {
  100. hr = E_UNEXPECTED;
  101. _JumpError(hr, error, "NULL m_pdb");
  102. }
  103. if (CSF_READONLY & m_pcs->SesFlags)
  104. {
  105. hr = E_ACCESSDENIED;
  106. _JumpError(hr, error, "read-only row");
  107. }
  108. hr = ((CCertDB *) m_pdb)->BeginTransaction(m_pcs, TRUE);
  109. _JumpIfError(hr, error, "BeginTransaction");
  110. error:
  111. return(hr);
  112. }
  113. STDMETHODIMP
  114. CCertDBRow::CommitTransaction(
  115. /* [in] */ DWORD dwCommitFlags)
  116. {
  117. HRESULT hr;
  118. BOOL fLazyCommit = ((dwCommitFlags & CDBROW_COMMIT_SOFTCOMMIT)?TRUE:FALSE);
  119. BOOL fCommit = (((dwCommitFlags & CDBROW_COMMIT_COMMIT) || fLazyCommit)?TRUE:FALSE);
  120. if (NULL == m_pdb)
  121. {
  122. hr = E_UNEXPECTED;
  123. _JumpError(hr, error, "NULL m_pdb");
  124. }
  125. if (CSF_READONLY & m_pcs->SesFlags)
  126. {
  127. hr = E_ACCESSDENIED;
  128. _JumpError(hr, error, "read-only row");
  129. }
  130. hr = ((CCertDB *) m_pdb)->CommitTransaction(m_pcs, fCommit, fLazyCommit);
  131. _JumpIfError(hr, error, "CommitTransaction");
  132. error:
  133. return(hr);
  134. }
  135. STDMETHODIMP
  136. CCertDBRow::GetRowId(
  137. /* [out] */ DWORD *pRowId)
  138. {
  139. HRESULT hr;
  140. if (NULL == pRowId)
  141. {
  142. hr = E_POINTER;
  143. _JumpError(hr, error, "NULL parm");
  144. }
  145. if (NULL == m_pcs)
  146. {
  147. hr = E_UNEXPECTED;
  148. _JumpError(hr, error, "m_pcs");
  149. }
  150. *pRowId = m_pcs->RowId;
  151. hr = S_OK;
  152. error:
  153. return(hr);
  154. }
  155. STDMETHODIMP
  156. CCertDBRow::Delete()
  157. {
  158. HRESULT hr;
  159. if (!(CSF_DELETE & m_pcs->SesFlags))
  160. {
  161. hr = E_ACCESSDENIED;
  162. _JumpError(hr, error, "not open for delete");
  163. }
  164. hr = ((CCertDB *) m_pdb)->Delete(m_pcs);
  165. _JumpIfError(hr, error, "Delete");
  166. error:
  167. return(hr);
  168. }
  169. STDMETHODIMP
  170. CCertDBRow::GetProperty(
  171. /* [in] */ WCHAR const *pwszPropName,
  172. /* [in] */ DWORD dwFlags,
  173. /* [in] */ ICertDBComputedColumn *pIComputedColumn,
  174. /* [in, out] */ DWORD *pcbProp,
  175. /* [out] */ BYTE *pbProp) // OPTIONAL
  176. {
  177. HRESULT hr;
  178. DWORD *pcbPropT = pcbProp;
  179. BYTE *pbPropT = pbProp;
  180. DWORD FlagsT = dwFlags;
  181. if (NULL == pwszPropName || NULL == pcbProp)
  182. {
  183. hr = E_POINTER;
  184. _JumpError(hr, error, "NULL parm");
  185. }
  186. if (NULL == pbProp)
  187. {
  188. *pcbProp = 0;
  189. }
  190. hr = _GetPropertyA(
  191. pwszPropName,
  192. FlagsT,
  193. pIComputedColumn,
  194. pcbPropT,
  195. pbPropT);
  196. if (CERTSRV_E_PROPERTY_EMPTY == hr)
  197. {
  198. goto error;
  199. }
  200. _JumpIfErrorStr3(
  201. hr,
  202. error,
  203. "_GetPropertyA",
  204. pwszPropName,
  205. HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW),
  206. E_INVALIDARG);
  207. if (0 == *pcbPropT)
  208. {
  209. hr = CERTSRV_E_PROPERTY_EMPTY;
  210. DBGPRINT((
  211. DBG_SS_CERTDB,
  212. "DB: Empty \"%hs\" property: %ws\n",
  213. PROPTABLE_REQUEST == (PROPTABLE_MASK & dwFlags)?
  214. "Request" :
  215. PROPTABLE_CERTIFICATE == (PROPTABLE_MASK & dwFlags)?
  216. "Certificate" : "CRL",
  217. pwszPropName));
  218. _JumpErrorStr(hr, error, "Empty property", pwszPropName);
  219. }
  220. CSASSERT(_VerifyPropertyLength(FlagsT, *pcbPropT, pbPropT));
  221. CSASSERT(_VerifyPropertyLength(dwFlags, *pcbProp, pbProp));
  222. error:
  223. return(hr);
  224. }
  225. // get a field value
  226. HRESULT
  227. CCertDBRow::_GetPropertyA(
  228. IN WCHAR const *pwszPropName,
  229. IN DWORD dwFlags,
  230. IN ICertDBComputedColumn *pIComputedColumn,
  231. IN OUT DWORD *pcbProp,
  232. OPTIONAL OUT BYTE *pbProp)
  233. {
  234. HRESULT hr;
  235. DBTABLE dt;
  236. if (PROPTABLE_ATTRIBUTE == (PROPTABLE_MASK & dwFlags))
  237. {
  238. hr = _VerifyPropertyValue(
  239. dwFlags,
  240. 0,
  241. JET_coltypLongText,
  242. CB_DBMAXTEXT_ATTRVALUE);
  243. _JumpIfError(hr, error, "Property value type mismatch");
  244. hr = ((CCertDB *) m_pdb)->GetAttribute(
  245. m_pcs,
  246. pwszPropName,
  247. pcbProp,
  248. pbProp);
  249. _JumpIfErrorStr2(
  250. hr,
  251. error,
  252. "GetAttribute",
  253. pwszPropName,
  254. CERTSRV_E_PROPERTY_EMPTY);
  255. }
  256. else
  257. {
  258. hr = ((CCertDB *) m_pdb)->MapPropId(pwszPropName, dwFlags, &dt);
  259. _JumpIfErrorStr(hr, error, "MapPropId", pwszPropName);
  260. hr = _VerifyPropertyValue(dwFlags, 0, dt.dbcoltyp, dt.dwcbMax);
  261. _JumpIfError2(hr, error, "Property value type mismatch", E_INVALIDARG);
  262. hr = ((CCertDB *) m_pdb)->GetProperty(
  263. m_pcs,
  264. &dt,
  265. pIComputedColumn,
  266. pcbProp,
  267. pbProp);
  268. if (hr == HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW))
  269. {
  270. goto error;
  271. }
  272. _JumpIfError2(hr, error, "GetProperty", CERTSRV_E_PROPERTY_EMPTY);
  273. }
  274. error:
  275. return(hr);
  276. }
  277. BOOL
  278. CCertDBRow::_VerifyPropertyLength(
  279. IN DWORD dwFlags,
  280. IN DWORD cbProp,
  281. IN BYTE const *pbProp)
  282. {
  283. BOOL fOk = FALSE;
  284. switch (dwFlags & PROPTYPE_MASK)
  285. {
  286. case PROPTYPE_LONG:
  287. fOk = sizeof(LONG) == cbProp;
  288. break;
  289. case PROPTYPE_DATE:
  290. fOk = sizeof(FILETIME) == cbProp;
  291. break;
  292. case PROPTYPE_BINARY:
  293. fOk = TRUE; // nothing to check
  294. break;
  295. case PROPTYPE_STRING:
  296. if (MAXDWORD == cbProp)
  297. {
  298. cbProp = wcslen((WCHAR const *) pbProp) * sizeof(WCHAR);
  299. }
  300. fOk =
  301. 0 == cbProp ||
  302. NULL == pbProp ||
  303. wcslen((WCHAR const *) pbProp) * sizeof(WCHAR) == cbProp;
  304. break;
  305. default:
  306. CSASSERT(!"_VerifyPropertyLength: Unexpected type");
  307. break;
  308. }
  309. return(fOk);
  310. }
  311. HRESULT
  312. CCertDBRow::_VerifyPropertyValue(
  313. IN DWORD dwFlags,
  314. IN DWORD cbProp,
  315. IN JET_COLTYP coltyp,
  316. IN DWORD cbMax)
  317. {
  318. JET_COLTYP wType;
  319. HRESULT hr = E_INVALIDARG;
  320. switch (dwFlags & PROPTYPE_MASK)
  321. {
  322. case PROPTYPE_LONG:
  323. wType = JET_coltypLong;
  324. break;
  325. case PROPTYPE_DATE:
  326. wType = JET_coltypDateTime;
  327. break;
  328. case PROPTYPE_BINARY:
  329. wType = JET_coltypLongBinary;
  330. break;
  331. case PROPTYPE_STRING:
  332. // LONG or static-sized version?
  333. if (JET_coltypLongText == coltyp)
  334. {
  335. wType = JET_coltypLongText;
  336. if (coltyp == wType)
  337. {
  338. CSASSERT(CB_DBMAXTEXT_MAXINTERNAL < cbMax);
  339. }
  340. }
  341. else
  342. {
  343. wType = JET_coltypText;
  344. if (coltyp == wType)
  345. {
  346. CSASSERT(JET_coltypText == coltyp);
  347. CSASSERT(CB_DBMAXTEXT_MAXINTERNAL >= cbMax);
  348. }
  349. }
  350. break;
  351. default:
  352. _JumpError(hr, error, "Property value type unknown");
  353. }
  354. if (coltyp != wType)
  355. {
  356. _JumpError2(hr, error, "Property value type mismatch", E_INVALIDARG);
  357. }
  358. // Note: cbProp and cbMax do not include the trailing '\0'.
  359. if (ISTEXTCOLTYP(wType) && cbMax < cbProp)
  360. {
  361. hr = HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW);
  362. DBGCODE(wprintf(
  363. L"_VerifyPropertyValue: len = %u, max = %u\n",
  364. cbProp,
  365. cbMax));
  366. _JumpError(hr, error, "Property value string too long");
  367. }
  368. hr = S_OK;
  369. error:
  370. return(hr);
  371. }
  372. STDMETHODIMP
  373. CCertDBRow::SetProperty(
  374. /* [in] */ WCHAR const *pwszPropName,
  375. /* [in] */ DWORD dwFlags,
  376. /* [in] */ DWORD cbProp,
  377. /* [in] */ BYTE const *pbProp) // OPTIONAL
  378. {
  379. HRESULT hr;
  380. char *pszProp = NULL;
  381. if (NULL == pwszPropName)
  382. {
  383. hr = E_POINTER;
  384. _JumpError(hr, error, "NULL parm");
  385. }
  386. if (NULL == pbProp &&
  387. (0 != cbProp || PROPTYPE_STRING != (dwFlags & PROPTYPE_MASK)))
  388. {
  389. hr = E_POINTER;
  390. _JumpError(hr, error, "NULL pbProp");
  391. }
  392. if ((CSF_DELETE | CSF_READONLY) & m_pcs->SesFlags)
  393. {
  394. hr = E_ACCESSDENIED;
  395. _JumpError(hr, error, "SetProperty: delete/read-only row");
  396. }
  397. CSASSERT(_VerifyPropertyLength(dwFlags, cbProp, pbProp));
  398. if (NULL != pbProp && PROPTYPE_STRING == (dwFlags & PROPTYPE_MASK))
  399. {
  400. cbProp = wcslen((WCHAR const *) pbProp) * sizeof(WCHAR);
  401. }
  402. hr = _SetPropertyA(pwszPropName, dwFlags, cbProp, pbProp);
  403. _JumpIfErrorStr(hr, error, "_SetPropertyA", pwszPropName);
  404. error:
  405. if (NULL != pszProp)
  406. {
  407. LocalFree(pszProp);
  408. }
  409. return(hr);
  410. }
  411. HRESULT
  412. CCertDBRow::_SetPropertyA(
  413. IN WCHAR const *pwszPropName,
  414. IN DWORD dwFlags,
  415. IN DWORD cbProp,
  416. IN BYTE const *pbProp) // OPTIONAL
  417. {
  418. HRESULT hr;
  419. DBTABLE dt;
  420. if ((CSF_DELETE | CSF_READONLY) & m_pcs->SesFlags)
  421. {
  422. hr = E_ACCESSDENIED;
  423. _JumpError(hr, error, "_SetPropertyA: delete/read-only row");
  424. }
  425. CSASSERT(NULL != pwszPropName);
  426. if (!_VerifyPropertyLength(dwFlags, cbProp, pbProp))
  427. {
  428. hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
  429. _JumpError(hr, error, "Property value length invalid");
  430. }
  431. if (PROPTABLE_ATTRIBUTE == (PROPTABLE_MASK & dwFlags))
  432. {
  433. if (PROPCALLER_POLICY == (PROPCALLER_MASK & dwFlags))
  434. {
  435. hr = E_ACCESSDENIED;
  436. _JumpError(hr, error, "Property write disallowed");
  437. }
  438. hr = _VerifyPropertyValue(
  439. PROPTYPE_STRING, // lie
  440. wcslen(pwszPropName) * sizeof(WCHAR),
  441. JET_coltypText,
  442. CB_DBMAXTEXT_ATTRNAME);
  443. _JumpIfErrorStr(
  444. hr,
  445. error,
  446. "_VerifyPropertyValue(attribute name)",
  447. pwszPropName);
  448. hr = _VerifyPropertyValue(
  449. dwFlags,
  450. cbProp,
  451. JET_coltypLongText,
  452. CB_DBMAXTEXT_ATTRVALUE);
  453. _JumpIfErrorStr(
  454. hr,
  455. error,
  456. "_VerifyPropertyValue(attribute value)",
  457. pwszPropName);
  458. hr = ((CCertDB *) m_pdb)->SetAttribute(
  459. m_pcs,
  460. pwszPropName,
  461. cbProp,
  462. pbProp);
  463. _JumpIfError(hr, error, "SetProperty");
  464. }
  465. else
  466. {
  467. hr = ((CCertDB *) m_pdb)->MapPropId(pwszPropName, dwFlags, &dt);
  468. _JumpIfErrorStr(hr, error, "MapPropId", pwszPropName);
  469. if (PROPCALLER_POLICY == (PROPCALLER_MASK & dwFlags) &&
  470. 0 == (DBTF_POLICYWRITEABLE & dt.dwFlags))
  471. {
  472. hr = E_ACCESSDENIED;
  473. _JumpError(hr, error, "Property write disallowed");
  474. }
  475. hr = _VerifyPropertyValue(dwFlags, cbProp, dt.dbcoltyp, dt.dwcbMax);
  476. _JumpIfErrorStr(hr, error, "_VerifyPropertyValue", pwszPropName);
  477. hr = ((CCertDB *) m_pdb)->SetProperty(m_pcs, &dt, cbProp, pbProp);
  478. _JumpIfError(hr, error, "SetProperty");
  479. }
  480. error:
  481. return(hr);
  482. }
  483. STDMETHODIMP
  484. CCertDBRow::SetExtension(
  485. /* [in] */ WCHAR const *pwszExtensionName,
  486. /* [in] */ DWORD dwExtFlags,
  487. /* [in] */ DWORD cbValue,
  488. /* [in] */ BYTE const *pbValue) // OPTIONAL
  489. {
  490. HRESULT hr;
  491. if (NULL == pwszExtensionName)
  492. {
  493. hr = E_POINTER;
  494. _JumpError(hr, error, "NULL parm");
  495. }
  496. if (NULL == m_pdb)
  497. {
  498. hr = E_UNEXPECTED;
  499. _JumpError(hr, error, "NULL m_pdb");
  500. }
  501. if (TABLE_REQCERTS != (CSF_TABLEMASK & m_pcs->SesFlags))
  502. {
  503. hr = E_INVALIDARG;
  504. _JumpError(hr, error, "bad Table");
  505. }
  506. if ((CSF_DELETE | CSF_READONLY) & m_pcs->SesFlags)
  507. {
  508. hr = E_ACCESSDENIED;
  509. _JumpError(hr, error, "SetExtension: delete/read-only row");
  510. }
  511. hr = ((CCertDB *) m_pdb)->SetExtension(
  512. m_pcs,
  513. pwszExtensionName,
  514. dwExtFlags,
  515. cbValue,
  516. pbValue);
  517. _JumpIfErrorStr(hr, error, "SetExtension", pwszExtensionName);
  518. error:
  519. return(hr);
  520. }
  521. STDMETHODIMP
  522. CCertDBRow::GetExtension(
  523. /* [in] */ WCHAR const *pwszExtensionName,
  524. /* [out] */ DWORD *pdwExtFlags,
  525. /* [in, out] */ DWORD *pcbValue,
  526. /* [out] */ BYTE *pbValue) // OPTIONAL
  527. {
  528. HRESULT hr;
  529. if (NULL == pwszExtensionName || NULL == pcbValue)
  530. {
  531. hr = E_POINTER;
  532. _JumpError(hr, error, "NULL parm");
  533. }
  534. if (NULL == m_pdb)
  535. {
  536. hr = E_UNEXPECTED;
  537. _JumpError(hr, error, "NULL m_pdb");
  538. }
  539. if (TABLE_REQCERTS != (CSF_TABLEMASK & m_pcs->SesFlags))
  540. {
  541. hr = E_INVALIDARG;
  542. _JumpError(hr, error, "bad Table");
  543. }
  544. hr = ((CCertDB *) m_pdb)->GetExtension(
  545. m_pcs,
  546. pwszExtensionName,
  547. pdwExtFlags,
  548. pcbValue,
  549. pbValue);
  550. _JumpIfErrorStr2(
  551. hr,
  552. error,
  553. "GetExtension",
  554. pwszExtensionName,
  555. CERTSRV_E_PROPERTY_EMPTY);
  556. error:
  557. return(hr);
  558. }
  559. STDMETHODIMP
  560. CCertDBRow::CopyRequestNames()
  561. {
  562. HRESULT hr;
  563. if (NULL == m_pdb)
  564. {
  565. hr = E_UNEXPECTED;
  566. _JumpError(hr, error, "NULL m_pdb");
  567. }
  568. if (TABLE_REQCERTS != (CSF_TABLEMASK & m_pcs->SesFlags))
  569. {
  570. hr = E_INVALIDARG;
  571. _JumpError(hr, error, "bad Table");
  572. }
  573. if ((CSF_DELETE | CSF_READONLY) & m_pcs->SesFlags)
  574. {
  575. hr = E_ACCESSDENIED;
  576. _JumpError(hr, error, "CopyRequestNames: delete/read-only row");
  577. }
  578. hr = ((CCertDB *) m_pdb)->CopyRequestNames(m_pcs);
  579. _JumpIfError(hr, error, "CopyRequestNames");
  580. error:
  581. return(hr);
  582. }
  583. STDMETHODIMP
  584. CCertDBRow::EnumCertDBName(
  585. /* [in] */ DWORD dwFlags,
  586. /* [out] */ IEnumCERTDBNAME **ppenum)
  587. {
  588. HRESULT hr;
  589. IEnumCERTDBNAME *penum = NULL;
  590. JET_TABLEID tableid = 0;
  591. if (NULL == ppenum)
  592. {
  593. hr = E_POINTER;
  594. _JumpError(hr, error, "NULL parm");
  595. }
  596. *ppenum = NULL;
  597. if (NULL == m_pdb)
  598. {
  599. hr = E_UNEXPECTED;
  600. _JumpError(hr, error, "NULL m_pdb");
  601. }
  602. if (TABLE_REQCERTS != (CSF_TABLEMASK & m_pcs->SesFlags))
  603. {
  604. hr = E_INVALIDARG;
  605. _JumpError(hr, error, "bad Table");
  606. }
  607. hr = ((CCertDB *) m_pdb)->EnumerateSetup(m_pcs, &dwFlags, &tableid);
  608. _JumpIfError(hr, error, "EnumerateSetup");
  609. penum = new CEnumCERTDBNAME;
  610. if (NULL == penum)
  611. {
  612. hr = E_OUTOFMEMORY;
  613. _JumpError(hr, error, "new CEnumCERTDBNAME");
  614. }
  615. hr = ((CEnumCERTDBNAME *) penum)->Open(this, tableid, dwFlags);
  616. _JumpIfError(hr, error, "Open");
  617. *ppenum = penum;
  618. error:
  619. if (S_OK != hr)
  620. {
  621. HRESULT hr2;
  622. if (0 != tableid)
  623. {
  624. hr2 = ((CCertDB *) m_pdb)->CloseTable(m_pcs, tableid);
  625. _PrintIfError(hr2, "CloseTable");
  626. }
  627. delete penum;
  628. }
  629. return(hr);
  630. }
  631. HRESULT
  632. CCertDBRow::EnumerateNext(
  633. IN OUT DWORD *pFlags,
  634. IN JET_TABLEID tableid,
  635. IN LONG cskip,
  636. IN ULONG celt,
  637. OUT CERTDBNAME *rgelt,
  638. OUT ULONG *pceltFetched)
  639. {
  640. HRESULT hr;
  641. if (NULL == rgelt || NULL == pceltFetched)
  642. {
  643. hr = E_POINTER;
  644. _JumpError(hr, error, "NULL parm");
  645. }
  646. if (NULL == m_pdb)
  647. {
  648. hr = E_UNEXPECTED;
  649. _JumpError(hr, error, "NULL m_pdb");
  650. }
  651. if (TABLE_REQCERTS != (CSF_TABLEMASK & m_pcs->SesFlags))
  652. {
  653. hr = E_INVALIDARG;
  654. _JumpError(hr, error, "bad Table");
  655. }
  656. hr = ((CCertDB *) m_pdb)->EnumerateNext(
  657. m_pcs,
  658. pFlags,
  659. tableid,
  660. cskip,
  661. celt,
  662. rgelt,
  663. pceltFetched);
  664. _JumpIfError2(hr, error, "EnumerateNext", S_FALSE);
  665. error:
  666. return(hr);
  667. }
  668. HRESULT
  669. CCertDBRow::EnumerateClose(
  670. IN JET_TABLEID tableid)
  671. {
  672. return(((CCertDB *) m_pdb)->EnumerateClose(m_pcs, tableid));
  673. }
  674. // IUnknown implementation
  675. STDMETHODIMP
  676. CCertDBRow::QueryInterface(
  677. const IID& iid,
  678. void **ppv)
  679. {
  680. HRESULT hr;
  681. if (NULL == ppv)
  682. {
  683. hr = E_POINTER;
  684. _JumpError(hr, error, "NULL parm");
  685. }
  686. if (iid == IID_IUnknown)
  687. {
  688. *ppv = static_cast<ICertDBRow *>(this);
  689. }
  690. else if (iid == IID_ICertDBRow)
  691. {
  692. *ppv = static_cast<ICertDBRow *>(this);
  693. }
  694. else
  695. {
  696. *ppv = NULL;
  697. hr = E_NOINTERFACE;
  698. _JumpError(hr, error, "IID");
  699. }
  700. reinterpret_cast<IUnknown *>(*ppv)->AddRef();
  701. hr = S_OK;
  702. error:
  703. return(hr);
  704. }
  705. ULONG STDMETHODCALLTYPE
  706. CCertDBRow::AddRef()
  707. {
  708. return(InterlockedIncrement(&m_cRef));
  709. }
  710. ULONG STDMETHODCALLTYPE
  711. CCertDBRow::Release()
  712. {
  713. ULONG cRef = InterlockedDecrement(&m_cRef);
  714. if (0 == cRef)
  715. {
  716. delete this;
  717. }
  718. return(cRef);
  719. }
  720. #if 0
  721. STDMETHODIMP
  722. CCertDBRow::InterfaceSupportsErrorInfo(
  723. IN REFIID riid)
  724. {
  725. static const IID *arr[] =
  726. {
  727. &IID_ICertDBRow,
  728. };
  729. for (int i = 0; i < sizeof(arr)/sizeof(arr[0]); i++)
  730. {
  731. if (InlineIsEqualGUID(*arr[i], riid))
  732. {
  733. return(S_OK);
  734. }
  735. }
  736. return(S_FALSE);
  737. }
  738. #endif