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.

1448 lines
30 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1999
  5. //
  6. // File: view.cpp
  7. //
  8. // Contents: CertView implementation
  9. //
  10. //---------------------------------------------------------------------------
  11. #include "pch.cpp"
  12. #pragma hdrstop
  13. #include "csprop.h"
  14. #include "csdisp.h"
  15. #include "column.h"
  16. #include "row.h"
  17. #include "view.h"
  18. #define __dwFILE__ __dwFILE_CERTVIEW_VIEW_CPP__
  19. WCHAR const g_wszRequestDot[] = wszPROPREQUESTDOT;
  20. #if DBG_CERTSRV
  21. LONG g_cCertView;
  22. LONG g_cCertViewTotal;
  23. #endif
  24. #define CV_COLUMN_CHUNK 66
  25. //+--------------------------------------------------------------------------
  26. // _cbcolNominal -- Return nominal size for DB column data, based on type.
  27. //
  28. // Assume string binary columns are less than full:
  29. //+--------------------------------------------------------------------------
  30. __inline LONG
  31. _cbcolNominal(
  32. IN LONG Type,
  33. IN LONG cbMax)
  34. {
  35. LONG divisor = 1;
  36. switch (PROPTYPE_MASK & Type)
  37. {
  38. case PROPTYPE_STRING: divisor = 2; break; // one-half full?
  39. case PROPTYPE_BINARY: divisor = 4; break; // one-quarter full?
  40. }
  41. return(cbMax / divisor);
  42. }
  43. //+--------------------------------------------------------------------------
  44. // CCertView::CCertView -- constructor
  45. //+--------------------------------------------------------------------------
  46. CCertView::CCertView()
  47. {
  48. DBGCODE(InterlockedIncrement(&g_cCertView));
  49. DBGCODE(InterlockedIncrement(&g_cCertViewTotal));
  50. ZeroMemory(&m_aaaColumn, sizeof(m_aaaColumn));
  51. m_fOpenConnection = FALSE;
  52. m_dwServerVersion = 0;
  53. m_pICertAdminD = NULL;
  54. m_aColumnResult = NULL;
  55. m_aDBColumnResult = NULL;
  56. m_pwszAuthority = NULL;
  57. m_fAddOk = FALSE;
  58. m_fOpenView = FALSE;
  59. m_fServerOpenView = FALSE;
  60. m_aRestriction = NULL;
  61. m_fTableSet = FALSE;
  62. m_icvTable = ICVTABLE_REQCERT;
  63. m_cvrcTable = CVRC_TABLE_REQCERT;
  64. m_pwszServerName = NULL;
  65. ZeroMemory(&m_aapwszColumnDisplayName, sizeof(m_aapwszColumnDisplayName));
  66. }
  67. //+--------------------------------------------------------------------------
  68. // CCertView::~CCertView -- destructor
  69. //
  70. // free memory associated with this instance
  71. //+--------------------------------------------------------------------------
  72. CCertView::~CCertView()
  73. {
  74. DBGCODE(InterlockedDecrement(&g_cCertView));
  75. #if DBG_CERTSRV
  76. if (m_dwRef > 1)
  77. {
  78. DBGPRINT((
  79. DBG_SS_CERTVIEWI,
  80. "%hs has %d instances left over\n",
  81. "CCertView",
  82. m_dwRef));
  83. }
  84. #endif
  85. _Cleanup();
  86. }
  87. //+--------------------------------------------------------------------------
  88. // CCertView::_Cleanup
  89. //
  90. // free memory associated with this instance
  91. //+--------------------------------------------------------------------------
  92. VOID
  93. CCertView::_Cleanup()
  94. {
  95. LONG i;
  96. myCloseDComConnection((IUnknown **) &m_pICertAdminD, &m_pwszServerName);
  97. m_dwServerVersion = 0;
  98. m_fOpenConnection = FALSE;
  99. if (NULL != m_aColumnResult)
  100. {
  101. LocalFree(m_aColumnResult);
  102. m_aColumnResult = NULL;
  103. }
  104. if (NULL != m_aDBColumnResult)
  105. {
  106. LocalFree(m_aDBColumnResult);
  107. m_aDBColumnResult = NULL;
  108. }
  109. for (i = 0; i < ICVTABLE_MAX; i++)
  110. {
  111. if (NULL != m_aaaColumn[i])
  112. {
  113. CERTDBCOLUMN **ppcol;
  114. for (
  115. ppcol = m_aaaColumn[i];
  116. ppcol < &m_aaaColumn[i][m_acaColumn[i]];
  117. ppcol++)
  118. {
  119. if (NULL != *ppcol)
  120. {
  121. LocalFree(*ppcol);
  122. }
  123. }
  124. LocalFree(m_aaaColumn[i]);
  125. m_aaaColumn[i] = NULL;
  126. }
  127. }
  128. if (NULL != m_aRestriction)
  129. {
  130. for (i = 0; i < m_cRestriction; i++)
  131. {
  132. if (NULL != m_aRestriction[i].pbValue)
  133. {
  134. LocalFree(m_aRestriction[i].pbValue);
  135. }
  136. }
  137. LocalFree(m_aRestriction);
  138. m_aRestriction = NULL;
  139. }
  140. if (NULL != m_pwszAuthority)
  141. {
  142. LocalFree(m_pwszAuthority);
  143. m_pwszAuthority = NULL;
  144. }
  145. for (i = 0; i < ICVTABLE_MAX; i++)
  146. {
  147. if (NULL != m_aapwszColumnDisplayName[i])
  148. {
  149. LocalFree(m_aapwszColumnDisplayName[i]);
  150. m_aapwszColumnDisplayName[i] = NULL;
  151. }
  152. }
  153. }
  154. HRESULT
  155. CCertView::_ValidateFlags(
  156. IN BOOL fSchemaOnly,
  157. IN DWORD Flags)
  158. {
  159. HRESULT hr = E_INVALIDARG;
  160. if (~CVRC_COLUMN_MASK & Flags)
  161. {
  162. _JumpError(hr, error, "invalid bits");
  163. }
  164. switch (CVRC_COLUMN_MASK & Flags)
  165. {
  166. case CVRC_COLUMN_RESULT:
  167. case CVRC_COLUMN_VALUE:
  168. if (fSchemaOnly)
  169. {
  170. _JumpError(hr, error, "RESULT/VALUE");
  171. }
  172. break;
  173. case CVRC_COLUMN_SCHEMA:
  174. break;
  175. default:
  176. _JumpError(hr, error, "bad column");
  177. }
  178. if (!m_fOpenConnection ||
  179. (CVRC_COLUMN_SCHEMA != (CVRC_COLUMN_MASK & Flags) &&
  180. !m_fOpenView))
  181. {
  182. hr = E_UNEXPECTED;
  183. _JumpError(hr, error, "Unexpected");
  184. }
  185. hr = S_OK;
  186. error:
  187. return(hr);
  188. }
  189. HRESULT
  190. CCertView::_SetTable(
  191. IN LONG ColumnIndex) // CVRC_TABLE_* or CV_COLUMN_*_DEFAULT
  192. {
  193. HRESULT hr;
  194. LONG cvrcTable;
  195. LONG icvTable;
  196. if (0 > ColumnIndex)
  197. {
  198. switch (ColumnIndex)
  199. {
  200. case CV_COLUMN_LOG_DEFAULT:
  201. case CV_COLUMN_LOG_FAILED_DEFAULT:
  202. case CV_COLUMN_LOG_REVOKED_DEFAULT:
  203. case CV_COLUMN_QUEUE_DEFAULT:
  204. icvTable = ICVTABLE_REQCERT;
  205. cvrcTable = CVRC_TABLE_REQCERT;
  206. break;
  207. case CV_COLUMN_EXTENSION_DEFAULT:
  208. icvTable = ICVTABLE_EXTENSION;
  209. cvrcTable = CVRC_TABLE_EXTENSIONS;
  210. break;
  211. case CV_COLUMN_ATTRIBUTE_DEFAULT:
  212. icvTable = ICVTABLE_ATTRIBUTE;
  213. cvrcTable = CVRC_TABLE_ATTRIBUTES;
  214. break;
  215. case CV_COLUMN_CRL_DEFAULT:
  216. icvTable = ICVTABLE_CRL;
  217. cvrcTable = CVRC_TABLE_CRL;
  218. break;
  219. default:
  220. hr = E_INVALIDARG;
  221. _JumpError(hr, error, "bad negative ColumnIndex");
  222. }
  223. }
  224. else
  225. {
  226. if (~CVRC_TABLE_MASK & ColumnIndex)
  227. {
  228. hr = E_INVALIDARG;
  229. _JumpError(hr, error, "invalid bits");
  230. }
  231. switch (ColumnIndex)
  232. {
  233. case CVRC_TABLE_REQCERT:
  234. icvTable = ICVTABLE_REQCERT;
  235. break;
  236. case CVRC_TABLE_EXTENSIONS:
  237. icvTable = ICVTABLE_EXTENSION;
  238. break;
  239. case CVRC_TABLE_ATTRIBUTES:
  240. icvTable = ICVTABLE_ATTRIBUTE;
  241. break;
  242. case CVRC_TABLE_CRL:
  243. icvTable = ICVTABLE_CRL;
  244. break;
  245. default:
  246. hr = E_INVALIDARG;
  247. _JumpError(hr, error, "bad table");
  248. }
  249. cvrcTable = CVRC_TABLE_MASK & ColumnIndex;
  250. }
  251. if (m_fTableSet)
  252. {
  253. if (icvTable != m_icvTable || cvrcTable != m_cvrcTable)
  254. {
  255. DBGPRINT((
  256. DBG_SS_CERTVIEW,
  257. "_SetTable: cvrcTable=%x <- %x\n",
  258. m_cvrcTable,
  259. cvrcTable));
  260. hr = E_INVALIDARG;
  261. _JumpError(hr, error, "mixed tables");
  262. }
  263. }
  264. else
  265. {
  266. m_icvTable = icvTable;
  267. m_cvrcTable = cvrcTable;
  268. m_fTableSet = TRUE;
  269. DBGPRINT((DBG_SS_CERTVIEWI, "_SetTable(cvrcTable=%x)\n", m_cvrcTable));
  270. }
  271. hr = S_OK;
  272. error:
  273. return(hr);
  274. }
  275. STDMETHODIMP
  276. CCertView::SetTable(
  277. /* [in] */ LONG Table) // CVRC_TABLE_*
  278. {
  279. HRESULT hr;
  280. hr = _VerifyServerVersion(2);
  281. _JumpIfError(hr, error, "_VerifyServerVersion");
  282. if (0 > Table)
  283. {
  284. hr = E_INVALIDARG;
  285. _JumpError(hr, error, "Table");
  286. }
  287. if (m_fTableSet)
  288. {
  289. hr = E_UNEXPECTED;
  290. _JumpError(hr, error, "Already set");
  291. }
  292. hr = _SetTable(Table);
  293. _JumpIfError(hr, error, "_SetTable");
  294. error:
  295. return(hr);
  296. }
  297. HRESULT
  298. CCertView::GetTable(
  299. OUT LONG *pcvrcTable)
  300. {
  301. HRESULT hr;
  302. if (NULL == pcvrcTable)
  303. {
  304. hr = E_POINTER;
  305. _JumpError(hr, error, "NULL parm");
  306. }
  307. *pcvrcTable = m_cvrcTable;
  308. hr = S_OK;
  309. error:
  310. return(hr);
  311. }
  312. HRESULT
  313. CCertView::FindColumn(
  314. IN LONG Flags, // CVRC_COLUMN_*
  315. IN LONG ColumnIndex,
  316. OUT CERTDBCOLUMN const **ppColumn, // localized for server
  317. OPTIONAL OUT WCHAR const **ppwszDisplayName) // localized for client
  318. {
  319. HRESULT hr;
  320. DWORD i;
  321. DBGCODE(LONG ColumnIndexArg = ColumnIndex);
  322. if (NULL == ppColumn)
  323. {
  324. hr = E_POINTER;
  325. _JumpError(hr, error, "NULL parm");
  326. }
  327. *ppColumn = NULL;
  328. hr = _ValidateFlags(FALSE, Flags);
  329. _JumpIfError(hr, error, "_ValidateFlags");
  330. hr = E_INVALIDARG;
  331. if (CVRC_COLUMN_SCHEMA != (CVRC_COLUMN_MASK & Flags))
  332. {
  333. if (m_cColumnResult <= ColumnIndex)
  334. {
  335. DBGPRINT((
  336. DBG_SS_CERTVIEW,
  337. "FindColumn(Flags=%x, ColumnIndex=%x, m_cColumnResult=%x)\n",
  338. Flags,
  339. ColumnIndex,
  340. m_cColumnResult));
  341. _JumpError(hr, error, "Result ColumnIndex");
  342. }
  343. ColumnIndex = m_aColumnResult[ColumnIndex];
  344. }
  345. if (ColumnIndex >= m_acColumn[m_icvTable])
  346. {
  347. _JumpError(hr, error, "ColumnIndex");
  348. }
  349. i = ColumnIndex / CV_COLUMN_CHUNK;
  350. if (i >= m_acaColumn[m_icvTable])
  351. {
  352. _JumpError(hr, error, "ColumnIndex2");
  353. }
  354. *ppColumn = &m_aaaColumn[m_icvTable][i][ColumnIndex % CV_COLUMN_CHUNK];
  355. CSASSERT(NULL != m_aapwszColumnDisplayName[m_icvTable]);
  356. CSASSERT(NULL != m_aapwszColumnDisplayName[m_icvTable][ColumnIndex]);
  357. if (NULL != ppwszDisplayName)
  358. {
  359. *ppwszDisplayName = m_aapwszColumnDisplayName[m_icvTable][ColumnIndex];
  360. }
  361. DBGPRINT((
  362. DBG_SS_CERTVIEWI,
  363. "FindColumn(Flags=%x, ColumnIndex=%x->%x) --> Type=%x Index=%x %ws/%ws\n",
  364. Flags,
  365. ColumnIndexArg,
  366. ColumnIndex,
  367. (*ppColumn)->Type,
  368. (*ppColumn)->Index,
  369. (*ppColumn)->pwszName,
  370. m_aapwszColumnDisplayName[m_icvTable][ColumnIndex]));
  371. hr = S_OK;
  372. error:
  373. return(hr);
  374. }
  375. HRESULT
  376. CCertView::_SaveColumnInfo(
  377. IN LONG icvTable,
  378. IN DWORD celt,
  379. IN CERTTRANSBLOB const *pctbColumn)
  380. {
  381. HRESULT hr;
  382. DWORD cbNew;
  383. CERTDBCOLUMN *peltNew = NULL;
  384. CERTDBCOLUMN *pelt;
  385. CERTTRANSDBCOLUMN *ptelt;
  386. CERTTRANSDBCOLUMN *pteltEnd;
  387. BYTE *pbNext;
  388. BYTE *pbEnd;
  389. CERTDBCOLUMN **ppColumn;
  390. if (NULL == pctbColumn)
  391. {
  392. hr = E_POINTER;
  393. _JumpError(hr, error, "NULL parm");
  394. }
  395. cbNew = pctbColumn->cb + celt * (sizeof(*pelt) - sizeof(*ptelt));
  396. peltNew = (CERTDBCOLUMN *) LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, cbNew);
  397. if (NULL == peltNew)
  398. {
  399. hr = E_OUTOFMEMORY;
  400. _JumpError(hr, error, "LocalAlloc");
  401. }
  402. pteltEnd = &((CERTTRANSDBCOLUMN *) pctbColumn->pb)[celt];
  403. if ((BYTE *) pteltEnd > &pctbColumn->pb[pctbColumn->cb])
  404. {
  405. hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
  406. _JumpError(hr, error, "bad marshalled data");
  407. }
  408. pelt = peltNew;
  409. pbNext = (BYTE *) &peltNew[celt];
  410. pbEnd = (BYTE *) Add2Ptr(peltNew, cbNew);
  411. for (ptelt = (CERTTRANSDBCOLUMN *) pctbColumn->pb;
  412. ptelt < pteltEnd;
  413. ptelt++, pelt++)
  414. {
  415. pelt->Type = ptelt->Type;
  416. pelt->Index = ptelt->Index;
  417. pelt->cbMax = ptelt->cbMax;
  418. hr = CopyMarshalledString(
  419. pctbColumn,
  420. ptelt->obwszName,
  421. pbEnd,
  422. &pbNext,
  423. &pelt->pwszName);
  424. _JumpIfError(hr, error, "CopyMarshalledString");
  425. hr = CopyMarshalledString(
  426. pctbColumn,
  427. ptelt->obwszDisplayName,
  428. pbEnd,
  429. &pbNext,
  430. &pelt->pwszDisplayName);
  431. _JumpIfError(hr, error, "CopyMarshalledString");
  432. }
  433. CSASSERT(pbNext == pbEnd);
  434. ppColumn = (CERTDBCOLUMN **) LocalAlloc(
  435. LMEM_FIXED,
  436. (m_acaColumn[icvTable] + 1) * sizeof(m_aaaColumn[0]));
  437. if (NULL == ppColumn)
  438. {
  439. hr = E_OUTOFMEMORY;
  440. _JumpError(hr, error, "LocalAlloc ppColumn");
  441. }
  442. if (NULL != m_aaaColumn[icvTable])
  443. {
  444. CopyMemory(
  445. ppColumn,
  446. m_aaaColumn[icvTable],
  447. m_acaColumn[icvTable] * sizeof(m_aaaColumn[0]));
  448. LocalFree(m_aaaColumn[icvTable]);
  449. }
  450. m_aaaColumn[icvTable] = ppColumn;
  451. m_aaaColumn[icvTable][m_acaColumn[icvTable]] = peltNew;
  452. peltNew = NULL;
  453. m_acaColumn[icvTable]++;
  454. m_acColumn[icvTable] += celt;
  455. hr = S_OK;
  456. error:
  457. if (NULL != peltNew)
  458. {
  459. LocalFree(peltNew);
  460. }
  461. return(hr);
  462. }
  463. HRESULT
  464. CCertView::_LoadSchema(
  465. IN LONG icvTable,
  466. IN LONG cvrcTable)
  467. {
  468. HRESULT hr;
  469. DWORD icol;
  470. DWORD ccol;
  471. CERTTRANSBLOB ctbColumn;
  472. ctbColumn.pb = NULL;
  473. icol = 0;
  474. CSASSERT(icvTable < ICVTABLE_MAX);
  475. do
  476. {
  477. ccol = CV_COLUMN_CHUNK;
  478. __try
  479. {
  480. if (CVRC_TABLE_REQCERT == cvrcTable)
  481. {
  482. hr = m_pICertAdminD->EnumViewColumn(
  483. m_pwszAuthority,
  484. icol,
  485. ccol,
  486. &ccol,
  487. &ctbColumn);
  488. }
  489. else
  490. {
  491. CSASSERT(S_OK == _VerifyServerVersion(2));
  492. hr = m_pICertAdminD->EnumViewColumnTable(
  493. m_pwszAuthority,
  494. cvrcTable,
  495. icol,
  496. ccol,
  497. &ccol,
  498. &ctbColumn);
  499. }
  500. }
  501. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  502. {
  503. }
  504. if (S_FALSE != hr)
  505. {
  506. _JumpIfError(
  507. hr,
  508. error,
  509. CVRC_TABLE_REQCERT == cvrcTable?
  510. "EnumViewColumn" : "EnumViewColumnTable");
  511. }
  512. myRegisterMemAlloc(ctbColumn.pb, ctbColumn.cb, CSM_MIDLUSERALLOC);
  513. hr = _SaveColumnInfo(icvTable, ccol, &ctbColumn);
  514. _JumpIfError(hr, error, "_SaveColumnInfo");
  515. CoTaskMemFree(ctbColumn.pb);
  516. ctbColumn.pb = NULL;
  517. icol += ccol;
  518. } while (CV_COLUMN_CHUNK == ccol);
  519. m_aapwszColumnDisplayName[icvTable] = (WCHAR const **) LocalAlloc(
  520. LMEM_FIXED | LMEM_ZEROINIT,
  521. m_acColumn[icvTable] * sizeof(m_aapwszColumnDisplayName[icvTable][0]));
  522. if (NULL == m_aapwszColumnDisplayName[icvTable])
  523. {
  524. hr = E_OUTOFMEMORY;
  525. _JumpError(hr, error, "LocalAlloc");
  526. }
  527. for (icol = 0; icol < (DWORD) m_acColumn[icvTable]; icol++)
  528. {
  529. CERTDBCOLUMN const *pColumn;
  530. CSASSERT(icol / CV_COLUMN_CHUNK < m_acaColumn[icvTable]);
  531. pColumn = &m_aaaColumn[icvTable][icol / CV_COLUMN_CHUNK][icol % CV_COLUMN_CHUNK];
  532. hr = myGetColumnDisplayName(
  533. pColumn->pwszName,
  534. &m_aapwszColumnDisplayName[icvTable][icol]);
  535. if (E_INVALIDARG == hr)
  536. {
  537. _PrintErrorStr(hr, "myGetColumnDisplayName", pColumn->pwszName);
  538. m_aapwszColumnDisplayName[icvTable][icol] = pColumn->pwszName;
  539. hr = S_OK;
  540. }
  541. _JumpIfError(hr, error, "myGetColumnDisplayName");
  542. }
  543. hr = S_OK;
  544. error:
  545. if (NULL != ctbColumn.pb)
  546. {
  547. CoTaskMemFree(ctbColumn.pb);
  548. }
  549. return(hr);
  550. }
  551. STDMETHODIMP
  552. CCertView::OpenConnection(
  553. /* [in] */ BSTR const strConfig)
  554. {
  555. HRESULT hr;
  556. DWORD i;
  557. WCHAR const *pwszAuthority;
  558. BOOL fTeardownOnError = FALSE;
  559. static LONG s_aTable[ICVTABLE_MAX] =
  560. {
  561. CVRC_TABLE_REQCERT, // ICVTABLE_REQCERT
  562. CVRC_TABLE_EXTENSIONS, // ICVTABLE_EXTENSION
  563. CVRC_TABLE_ATTRIBUTES, // ICVTABLE_ATTRIBUTE
  564. CVRC_TABLE_CRL, // ICVTABLE_CRL
  565. };
  566. if (NULL == strConfig)
  567. {
  568. hr = E_POINTER;
  569. _JumpError(hr, error, "NULL parm");
  570. }
  571. if (m_fOpenConnection)
  572. {
  573. hr = E_UNEXPECTED;
  574. _JumpError(hr, error, "Connected");
  575. }
  576. fTeardownOnError = TRUE;
  577. m_dwServerVersion = 0;
  578. hr = myOpenAdminDComConnection(
  579. strConfig,
  580. &pwszAuthority,
  581. &m_pwszServerName,
  582. &m_dwServerVersion,
  583. &m_pICertAdminD);
  584. _JumpIfError(hr, error, "myOpenAdminDComConnection");
  585. CSASSERT (0 != m_dwServerVersion);
  586. hr = myDupString(pwszAuthority, &m_pwszAuthority);
  587. _JumpIfError(hr, error, "myDupString");
  588. ZeroMemory(&m_acaColumn, sizeof(m_acaColumn));
  589. ZeroMemory(&m_acColumn, sizeof(m_acColumn));
  590. m_cRestriction = 0;
  591. m_aRestriction = (CERTVIEWRESTRICTION *) LocalAlloc(LMEM_FIXED, 0);
  592. if (NULL == m_aRestriction)
  593. {
  594. hr = E_OUTOFMEMORY;
  595. _JumpError(hr, error, "LocalAlloc");
  596. }
  597. m_fOpenConnection = TRUE;
  598. for (i = 0; i < ICVTABLE_MAX; i++)
  599. {
  600. if (m_dwServerVersion >= 2 || ICVTABLE_REQCERT == i)
  601. {
  602. hr = _LoadSchema(i, s_aTable[i]);
  603. _JumpIfError(hr, error, "_LoadSchema");
  604. }
  605. }
  606. hr = S_OK;
  607. error:
  608. if (S_OK != hr && fTeardownOnError)
  609. {
  610. _Cleanup();
  611. }
  612. return(_SetErrorInfo(hr, L"CCertView::OpenConnection"));
  613. }
  614. //+--------------------------------------------------------------------------
  615. // CCertView::_VerifyServerVersion -- verify server version
  616. //
  617. //+--------------------------------------------------------------------------
  618. HRESULT
  619. CCertView::_VerifyServerVersion(
  620. IN DWORD RequiredVersion)
  621. {
  622. HRESULT hr;
  623. if (!m_fOpenConnection)
  624. {
  625. hr = HRESULT_FROM_WIN32(ERROR_ONLY_IF_CONNECTED);
  626. _JumpError(hr, error, "Not connected");
  627. }
  628. if (m_dwServerVersion < RequiredVersion)
  629. {
  630. hr = RPC_E_VERSION_MISMATCH;
  631. _JumpError(hr, error, "old server");
  632. }
  633. hr = S_OK;
  634. error:
  635. return(hr);
  636. }
  637. STDMETHODIMP
  638. CCertView::EnumCertViewColumn(
  639. /* [in] */ LONG fResultColumn, // CVRC_COLUMN_*
  640. /* [out, retval] */ IEnumCERTVIEWCOLUMN **ppenum)
  641. {
  642. HRESULT hr;
  643. IEnumCERTVIEWCOLUMN *penum = NULL;
  644. if (NULL == ppenum)
  645. {
  646. hr = E_POINTER;
  647. _JumpError(hr, error, "NULL parm");
  648. }
  649. *ppenum = NULL;
  650. penum = new CEnumCERTVIEWCOLUMN;
  651. if (NULL == penum)
  652. {
  653. hr = E_OUTOFMEMORY;
  654. _JumpError(hr, error, "new CEnumCERTVIEWCOLUMN");
  655. }
  656. hr = ((CEnumCERTVIEWCOLUMN *) penum)->Open(fResultColumn, -1, this, NULL);
  657. _JumpIfError(hr, error, "Open");
  658. *ppenum = penum;
  659. penum = NULL;
  660. hr = S_OK;
  661. error:
  662. if (NULL != penum)
  663. {
  664. penum->Release();
  665. }
  666. return(_SetErrorInfo(hr, L"CCertView::EnumCertViewColumn"));
  667. }
  668. STDMETHODIMP
  669. CCertView::GetColumnCount(
  670. /* [in] */ LONG fResultColumn, // CVRC_COLUMN_*
  671. /* [out, retval] */ LONG __RPC_FAR *pcColumn)
  672. {
  673. HRESULT hr;
  674. if (NULL == pcColumn)
  675. {
  676. hr = E_POINTER;
  677. _JumpError(hr, error, "NULL parm");
  678. }
  679. hr = _ValidateFlags(FALSE, fResultColumn);
  680. _JumpIfError(hr, error, "_ValidateFlags");
  681. *pcColumn = CVRC_COLUMN_SCHEMA != (CVRC_COLUMN_MASK & fResultColumn)?
  682. m_cColumnResult : m_acColumn[m_icvTable];
  683. error:
  684. return(_SetErrorInfo(hr, L"CCertView::GetColumnCount"));
  685. }
  686. STDMETHODIMP
  687. CCertView::GetColumnIndex(
  688. /* [in] */ LONG fResultColumn, // CVRC_COLUMN_*
  689. /* [in] */ BSTR const strColumnName,
  690. /* [out, retval] */ LONG *pColumnIndex)
  691. {
  692. HRESULT hr;
  693. CERTDBCOLUMN const *pColumn;
  694. WCHAR const *pwsz;
  695. WCHAR *pwszAlloc = NULL;
  696. WCHAR const *pwszDisplayName;
  697. LONG icol;
  698. LONG i;
  699. if (NULL == strColumnName || NULL == pColumnIndex)
  700. {
  701. hr = E_POINTER;
  702. _JumpError(hr, error, "NULL parm");
  703. }
  704. pwsz = strColumnName;
  705. hr = _ValidateFlags(FALSE, fResultColumn);
  706. _JumpIfError(hr, error, "_ValidateFlags");
  707. // First pass: i == 0 -- compare against unlocalized column name
  708. // Second pass: i == 1 -- compare against localized column name
  709. // Third pass: i == 2 -- compare Request.pwsz against unlocalized colname
  710. for (i = 0; ; i++)
  711. {
  712. if (1 < i)
  713. {
  714. if (ICVTABLE_REQCERT != m_icvTable || NULL != wcschr(pwsz, L'.'))
  715. {
  716. hr = E_INVALIDARG;
  717. _JumpErrorStr(hr, error, "Bad Column Name", strColumnName);
  718. }
  719. pwszAlloc = (WCHAR *) LocalAlloc(
  720. LMEM_FIXED,
  721. wcslen(pwsz) * sizeof(WCHAR) +
  722. sizeof(g_wszRequestDot));
  723. if (NULL == pwszAlloc)
  724. {
  725. hr = E_OUTOFMEMORY;
  726. _JumpError(hr, error, "LocalAlloc");
  727. }
  728. wcscpy(pwszAlloc, g_wszRequestDot);
  729. wcscat(pwszAlloc, pwsz);
  730. pwsz = pwszAlloc;
  731. }
  732. for (icol = 0; icol < m_acColumn[m_icvTable]; icol++)
  733. {
  734. hr = FindColumn(fResultColumn, icol, &pColumn, &pwszDisplayName);
  735. _JumpIfErrorStr(hr, error, "FindColumn", strColumnName);
  736. CSASSERT(NULL != pColumn);
  737. CSASSERT(NULL != pColumn->pwszName);
  738. CSASSERT(NULL != pColumn->pwszDisplayName); // localized for server
  739. CSASSERT(NULL != pwszDisplayName); // localized for client
  740. if (0 == lstrcmpi(
  741. pwsz,
  742. 1 == i? pwszDisplayName : pColumn->pwszName))
  743. {
  744. break;
  745. }
  746. }
  747. if (icol < m_acColumn[m_icvTable])
  748. {
  749. break;
  750. }
  751. }
  752. *pColumnIndex = icol;
  753. hr = S_OK;
  754. error:
  755. if (NULL != pwszAlloc)
  756. {
  757. LocalFree(pwszAlloc);
  758. }
  759. return(_SetErrorInfo(hr, L"CCertView::GetColumnIndex"));
  760. }
  761. STDMETHODIMP
  762. CCertView::SetResultColumnCount(
  763. /* [in] */ LONG cResultColumn)
  764. {
  765. HRESULT hr;
  766. DWORD cColumnDefault;
  767. CERTTRANSBLOB ctbColumnDefault;
  768. ctbColumnDefault.pb = NULL;
  769. hr = E_UNEXPECTED;
  770. if (!m_fOpenConnection)
  771. {
  772. _JumpError(hr, error, "No Connection");
  773. }
  774. if (NULL != m_aColumnResult)
  775. {
  776. _JumpError(hr, error, "2nd call");
  777. }
  778. if (!m_fTableSet)
  779. {
  780. hr = _SetTable(CVRC_TABLE_REQCERT);
  781. _JumpIfError(hr, error, "_SetTable");
  782. }
  783. m_cbcolResultNominalTotal = 0;
  784. m_fAddOk = TRUE;
  785. if (0 > cResultColumn)
  786. {
  787. m_fAddOk = FALSE;
  788. __try
  789. {
  790. hr = m_pICertAdminD->GetViewDefaultColumnSet(
  791. m_pwszAuthority,
  792. cResultColumn,
  793. &cColumnDefault,
  794. &ctbColumnDefault);
  795. }
  796. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  797. {
  798. }
  799. _JumpIfError(hr, error, "GetViewDefaultColumnSet");
  800. myRegisterMemAlloc(
  801. ctbColumnDefault.pb,
  802. ctbColumnDefault.cb,
  803. CSM_MIDLUSERALLOC);
  804. cResultColumn = cColumnDefault;
  805. CSASSERT(NULL != ctbColumnDefault.pb);
  806. CSASSERT(cResultColumn * sizeof(DWORD) == ctbColumnDefault.cb);
  807. }
  808. else
  809. {
  810. cResultColumn &= CVRC_COLUMN_MASK;
  811. }
  812. m_aColumnResult = (LONG *) LocalAlloc(
  813. LMEM_FIXED,
  814. cResultColumn * sizeof(m_aColumnResult[0]));
  815. if (NULL == m_aColumnResult)
  816. {
  817. hr = E_OUTOFMEMORY;
  818. _JumpError(hr, error, "Result Column array");
  819. }
  820. m_aDBColumnResult = (DWORD *) LocalAlloc(
  821. LMEM_FIXED,
  822. cResultColumn * sizeof(m_aDBColumnResult[0]));
  823. if (NULL == m_aDBColumnResult)
  824. {
  825. hr = E_OUTOFMEMORY;
  826. _JumpError(hr, error, "Result DB Column array");
  827. }
  828. m_cColumnResultMax = cResultColumn;
  829. m_cColumnResult = 0;
  830. if (!m_fAddOk)
  831. {
  832. LONG i;
  833. DWORD const *pIndex;
  834. pIndex = (DWORD const *) ctbColumnDefault.pb;
  835. for (i = 0; i < cResultColumn; pIndex++, i++)
  836. {
  837. LONG icol;
  838. CERTDBCOLUMN const *pColumn;
  839. for (icol = 0; icol < m_acColumn[m_icvTable]; icol++)
  840. {
  841. hr = FindColumn(
  842. CVRC_COLUMN_SCHEMA,
  843. icol,
  844. &pColumn,
  845. NULL);
  846. _JumpIfError(hr, error, "FindColumn");
  847. if (*pIndex == pColumn->Index)
  848. {
  849. m_aDBColumnResult[i] = *pIndex;
  850. m_aColumnResult[i] = icol;
  851. m_cbcolResultNominalTotal += _cbcolNominal(pColumn->Type, pColumn->cbMax);
  852. break;
  853. }
  854. }
  855. if (icol >= m_acColumn[m_icvTable])
  856. {
  857. hr = E_INVALIDARG;
  858. _JumpError(hr, error, "ColumnIndex");
  859. }
  860. }
  861. m_cColumnResult = cResultColumn;
  862. }
  863. hr = S_OK;
  864. error:
  865. if (NULL != ctbColumnDefault.pb)
  866. {
  867. CoTaskMemFree(ctbColumnDefault.pb);
  868. }
  869. return(_SetErrorInfo(hr, L"CCertView::SetResultColumnCount"));
  870. }
  871. STDMETHODIMP
  872. CCertView::SetResultColumn(
  873. /* [in] */ LONG ColumnIndex)
  874. {
  875. HRESULT hr;
  876. CERTDBCOLUMN const *pColumn;
  877. if (m_fOpenView || !m_fAddOk || m_cColumnResultMax <= m_cColumnResult)
  878. {
  879. hr = E_UNEXPECTED;
  880. _JumpError(hr, error, "Unexpected");
  881. }
  882. if (!m_fTableSet)
  883. {
  884. hr = _SetTable(CVRC_TABLE_REQCERT);
  885. _JumpIfError(hr, error, "_SetTable");
  886. }
  887. if (m_acColumn[m_icvTable] <= ColumnIndex)
  888. {
  889. hr = E_INVALIDARG;
  890. _JumpError(hr, error, "ColumnIndex");
  891. }
  892. m_aColumnResult[m_cColumnResult] = ColumnIndex;
  893. hr = FindColumn(
  894. CVRC_COLUMN_SCHEMA,
  895. ColumnIndex,
  896. &pColumn,
  897. NULL);
  898. _JumpIfError(hr, error, "FindColumn");
  899. m_aDBColumnResult[m_cColumnResult] = pColumn->Index;
  900. m_cbcolResultNominalTotal += _cbcolNominal(pColumn->Type, pColumn->cbMax);
  901. m_cColumnResult++;
  902. error:
  903. return(_SetErrorInfo(hr, L"CCertView::SetResultColumn"));
  904. }
  905. STDMETHODIMP
  906. CCertView::SetRestriction(
  907. /* [in] */ LONG ColumnIndex,
  908. /* [in] */ LONG SeekOperator,
  909. /* [in] */ LONG SortOrder,
  910. /* [in] */ VARIANT __RPC_FAR const *pvarValue)
  911. {
  912. HRESULT hr;
  913. CERTDBCOLUMN const *pColumn;
  914. CERTVIEWRESTRICTION cvr;
  915. CERTVIEWRESTRICTION *pcvr;
  916. ZeroMemory(&cvr, sizeof(cvr));
  917. hr = E_UNEXPECTED;
  918. if (!m_fOpenConnection)
  919. {
  920. _JumpError(hr, error, "No Connection");
  921. }
  922. if (!m_fTableSet)
  923. {
  924. hr = _SetTable(CVRC_TABLE_REQCERT);
  925. _JumpIfError(hr, error, "_SetTable");
  926. }
  927. if (0 > ColumnIndex)
  928. {
  929. cvr.ColumnIndex = ColumnIndex;
  930. CSASSERT(CVR_SEEK_NONE == cvr.SeekOperator);
  931. CSASSERT(CVR_SORT_NONE == cvr.SortOrder);
  932. CSASSERT(NULL == cvr.pbValue);
  933. CSASSERT(0 == cvr.cbValue);
  934. hr = S_OK;
  935. }
  936. else
  937. {
  938. if (NULL == pvarValue)
  939. {
  940. hr = E_POINTER;
  941. _JumpError(hr, error, "NULL parm");
  942. }
  943. hr = FindColumn(
  944. CVRC_COLUMN_SCHEMA,
  945. CVRC_COLUMN_MASK & ColumnIndex,
  946. &pColumn,
  947. NULL);
  948. _JumpIfError(hr, error, "FindColumn");
  949. switch (SeekOperator)
  950. {
  951. case CVR_SEEK_EQ:
  952. case CVR_SEEK_LT:
  953. case CVR_SEEK_LE:
  954. case CVR_SEEK_GE:
  955. case CVR_SEEK_GT:
  956. case CVR_SEEK_NONE:
  957. //case CVR_SEEK_SET:
  958. break;
  959. default:
  960. hr = E_INVALIDARG;
  961. _JumpError(hr, error, "Seek Operator");
  962. }
  963. switch (SortOrder)
  964. {
  965. case CVR_SORT_NONE:
  966. case CVR_SORT_ASCEND:
  967. case CVR_SORT_DESCEND:
  968. break;
  969. default:
  970. hr = E_INVALIDARG;
  971. _JumpError(hr, error, "Sort Order");
  972. }
  973. hr = myMarshalVariant(
  974. pvarValue,
  975. pColumn->Type,
  976. &cvr.cbValue,
  977. &cvr.pbValue);
  978. _JumpIfError(hr, error, "myMarshalVariant");
  979. cvr.ColumnIndex = pColumn->Index;
  980. cvr.SeekOperator = SeekOperator;
  981. cvr.SortOrder = SortOrder;
  982. }
  983. pcvr = (CERTVIEWRESTRICTION *) LocalAlloc(
  984. LMEM_FIXED,
  985. (m_cRestriction + 1) * sizeof(*pcvr));
  986. if (NULL == pcvr)
  987. {
  988. hr = E_OUTOFMEMORY;
  989. _JumpError(hr, error, "LocalAlloc");
  990. }
  991. if (NULL != m_aRestriction)
  992. {
  993. CopyMemory(pcvr, m_aRestriction, m_cRestriction * sizeof(*pcvr));
  994. LocalFree(m_aRestriction);
  995. }
  996. CopyMemory(&pcvr[m_cRestriction], &cvr, sizeof(cvr));
  997. cvr.pbValue = NULL;
  998. m_aRestriction = pcvr;
  999. m_cRestriction++;
  1000. error:
  1001. if (NULL != cvr.pbValue)
  1002. {
  1003. LocalFree(cvr.pbValue);
  1004. }
  1005. return(_SetErrorInfo(hr, L"CCertView::SetRestriction"));
  1006. }
  1007. STDMETHODIMP
  1008. CCertView::OpenView(
  1009. /* [out] */ IEnumCERTVIEWROW **ppenum)
  1010. {
  1011. HRESULT hr;
  1012. IEnumCERTVIEWROW *penum = NULL;
  1013. if (NULL == ppenum)
  1014. {
  1015. hr = E_POINTER;
  1016. _JumpError(hr, error, "NULL parm");
  1017. }
  1018. *ppenum = NULL;
  1019. hr = E_UNEXPECTED;
  1020. if (!m_fOpenConnection)
  1021. {
  1022. _JumpError(hr, error, "No Connection");
  1023. }
  1024. if (m_fOpenView)
  1025. {
  1026. _JumpError(hr, error, "2nd call");
  1027. }
  1028. penum = new CEnumCERTVIEWROW;
  1029. if (NULL == penum)
  1030. {
  1031. hr = E_OUTOFMEMORY;
  1032. _JumpError(hr, error, "new CEnumCERTVIEWROW");
  1033. }
  1034. hr = ((CEnumCERTVIEWROW *) penum)->Open(this);
  1035. _JumpIfError(hr, error, "Open");
  1036. *ppenum = penum;
  1037. m_fAddOk = FALSE;
  1038. m_fOpenView = TRUE;
  1039. hr = S_OK;
  1040. error:
  1041. if (S_OK != hr && NULL != penum)
  1042. {
  1043. penum->Release();
  1044. }
  1045. return(_SetErrorInfo(hr, L"CCertView::OpenView"));
  1046. }
  1047. HRESULT
  1048. CCertView::SetViewColumns(
  1049. OUT LONG *pcbrowResultNominal)
  1050. {
  1051. HRESULT hr;
  1052. LONG icol;
  1053. if (NULL == pcbrowResultNominal)
  1054. {
  1055. hr = E_POINTER;
  1056. _JumpError(hr, error, "NULL parm");
  1057. }
  1058. if (m_fServerOpenView)
  1059. {
  1060. hr = E_UNEXPECTED;
  1061. _JumpError(hr, error, "View Already Open");
  1062. }
  1063. if (!m_fTableSet)
  1064. {
  1065. hr = _SetTable(CVRC_TABLE_REQCERT);
  1066. _JumpIfError(hr, error, "_SetTable");
  1067. }
  1068. if (NULL == m_aDBColumnResult)
  1069. {
  1070. hr = SetResultColumnCount(m_acColumn[m_icvTable]);
  1071. _JumpIfError(hr, error, "SetResultColumnCount");
  1072. for (icol = 0; icol < m_acColumn[m_icvTable]; icol++)
  1073. {
  1074. hr = SetResultColumn(icol);
  1075. _JumpIfError(hr, error, "SetResultColumn");
  1076. }
  1077. }
  1078. *pcbrowResultNominal =
  1079. sizeof(CERTDBRESULTROW) +
  1080. sizeof(CERTDBRESULTCOLUMN) * m_cColumnResultMax +
  1081. m_cbcolResultNominalTotal;
  1082. hr = S_OK;
  1083. error:
  1084. return(hr);
  1085. }
  1086. HRESULT
  1087. CCertView::EnumView(
  1088. IN LONG cskip,
  1089. IN ULONG celt,
  1090. OUT ULONG *pceltFetched,
  1091. OUT LONG *pieltNext,
  1092. OUT LONG *pcbResultRows,
  1093. OUT CERTTRANSDBRESULTROW const **ppResultRows)
  1094. {
  1095. HRESULT hr;
  1096. CERTTRANSBLOB ctbResultRows;
  1097. if (NULL == ppResultRows ||
  1098. NULL == pceltFetched ||
  1099. NULL == pieltNext ||
  1100. NULL == pcbResultRows)
  1101. {
  1102. hr = E_POINTER;
  1103. _JumpError(hr, error, "NULL parm");
  1104. }
  1105. *ppResultRows = NULL;
  1106. if (!m_fOpenConnection)
  1107. {
  1108. hr = E_UNEXPECTED;
  1109. _JumpError(hr, error, "No Connection");
  1110. }
  1111. DBGPRINT((
  1112. DBG_SS_CERTVIEWI,
  1113. "%hs: ielt=%d cskip=%d celt=%d\n",
  1114. m_fServerOpenView? "EnumView" : "OpenView",
  1115. m_fServerOpenView? m_ielt : 1,
  1116. cskip,
  1117. celt));
  1118. if (!m_fServerOpenView)
  1119. {
  1120. if (m_cColumnResultMax != m_cColumnResult)
  1121. {
  1122. hr = E_UNEXPECTED;
  1123. _JumpError(hr, error, "Missing Result Columns");
  1124. }
  1125. m_ielt = 1;
  1126. __try
  1127. {
  1128. hr = m_pICertAdminD->OpenView(
  1129. m_pwszAuthority,
  1130. m_cRestriction,
  1131. m_aRestriction,
  1132. m_cColumnResultMax,
  1133. m_aDBColumnResult,
  1134. m_ielt + cskip,
  1135. celt,
  1136. pceltFetched,
  1137. &ctbResultRows);
  1138. m_fServerOpenView = TRUE;
  1139. }
  1140. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  1141. {
  1142. }
  1143. if (S_FALSE != hr)
  1144. {
  1145. _JumpIfError(hr, error, "OpenView");
  1146. }
  1147. }
  1148. else
  1149. {
  1150. __try
  1151. {
  1152. hr = m_pICertAdminD->EnumView(
  1153. m_pwszAuthority,
  1154. m_ielt + cskip,
  1155. celt,
  1156. pceltFetched,
  1157. &ctbResultRows);
  1158. }
  1159. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  1160. {
  1161. }
  1162. if (S_FALSE != hr)
  1163. {
  1164. _JumpIfError(hr, error, "EnumView");
  1165. }
  1166. }
  1167. myRegisterMemAlloc(ctbResultRows.pb, ctbResultRows.cb, CSM_MIDLUSERALLOC);
  1168. DBGPRINT((
  1169. DBG_SS_CERTVIEWI,
  1170. "%hs: *pceltFetched=%d -> %d @ielt=%d -> %d\n",
  1171. m_fServerOpenView? "EnumView" : "OpenView",
  1172. celt,
  1173. *pceltFetched,
  1174. m_ielt + cskip,
  1175. m_ielt + cskip + *pceltFetched));
  1176. m_ielt += cskip + *pceltFetched;
  1177. *pieltNext = m_ielt;
  1178. DBGPRINT((
  1179. DBG_SS_CERTVIEWI,
  1180. "EnumView: celtFetched=%d ieltNext=%d cb=%d hr=%x\n",
  1181. *pceltFetched,
  1182. *pieltNext,
  1183. ctbResultRows.cb,
  1184. hr));
  1185. *pcbResultRows = ctbResultRows.cb;
  1186. *ppResultRows = (CERTTRANSDBRESULTROW const *) ctbResultRows.pb;
  1187. error:
  1188. return(hr);
  1189. }
  1190. HRESULT
  1191. CCertView::EnumAttributesOrExtensions(
  1192. IN DWORD RowId,
  1193. IN DWORD Flags,
  1194. OPTIONAL IN WCHAR const *pwszLast,
  1195. IN DWORD celt,
  1196. OUT DWORD *pceltFetched,
  1197. CERTTRANSBLOB *pctbOut)
  1198. {
  1199. HRESULT hr;
  1200. if (NULL == pceltFetched || NULL == pctbOut)
  1201. {
  1202. hr = E_POINTER;
  1203. _JumpError(hr, error, "NULL parm");
  1204. }
  1205. if (!m_fOpenConnection)
  1206. {
  1207. hr = E_UNEXPECTED;
  1208. _JumpError(hr, error, "No Connection");
  1209. }
  1210. __try
  1211. {
  1212. hr = m_pICertAdminD->EnumAttributesOrExtensions(
  1213. m_pwszAuthority,
  1214. RowId,
  1215. Flags,
  1216. pwszLast,
  1217. celt,
  1218. pceltFetched,
  1219. pctbOut);
  1220. }
  1221. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  1222. {
  1223. }
  1224. if (S_FALSE != hr)
  1225. {
  1226. _JumpIfError(hr, error, "EnumAttributesOrExtensions");
  1227. }
  1228. myRegisterMemAlloc(pctbOut->pb, pctbOut->cb, CSM_MIDLUSERALLOC);
  1229. error:
  1230. return(hr);
  1231. }
  1232. HRESULT
  1233. CCertView::_SetErrorInfo(
  1234. IN HRESULT hrError,
  1235. IN WCHAR const *pwszDescription)
  1236. {
  1237. CSASSERT(FAILED(hrError) || S_OK == hrError || S_FALSE == hrError);
  1238. if (FAILED(hrError))
  1239. {
  1240. HRESULT hr;
  1241. hr = DispatchSetErrorInfo(
  1242. hrError,
  1243. pwszDescription,
  1244. wszCLASS_CERTVIEW,
  1245. &IID_ICertView);
  1246. CSASSERT(hr == hrError);
  1247. }
  1248. return(hrError);
  1249. }