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.

959 lines
23 KiB

  1. // This is a part of the Microsoft Management Console.
  2. // Copyright (C) Microsoft Corporation, 1995 - 1999
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Management Console and related
  7. // electronic documentation provided with the interfaces.
  8. #include "stdafx.h"
  9. #include "csdisp.h"
  10. #define __dwFILE__ __dwFILE_CERTMMC_FOLDERS_CPP__
  11. #ifdef _DEBUG
  12. #undef THIS_FILE
  13. static char THIS_FILE[] = __FILE__;
  14. #endif
  15. void CFolder::SetProperties(LPCWSTR szName, SCOPE_TYPES itemType,
  16. FOLDER_TYPES type, int iChildren)
  17. {
  18. // Set folder type
  19. m_type = type;
  20. // Set scope
  21. m_itemType = itemType;
  22. // Add node name
  23. if (szName != NULL)
  24. {
  25. m_ScopeItem.mask |= SDI_STR;
  26. m_ScopeItem.displayname = MMC_CALLBACK;
  27. UINT uiByteLen = (wcslen(szName) + 1) * sizeof(OLECHAR);
  28. LPOLESTR psz = (LPOLESTR)::CoTaskMemAlloc(uiByteLen);
  29. if (psz != NULL)
  30. {
  31. wcscpy(psz, szName);
  32. m_pszName = psz;
  33. }
  34. }
  35. // Always tell view if we have children or not
  36. m_ScopeItem.mask |= SDI_CHILDREN;
  37. m_ScopeItem.cChildren = iChildren;
  38. }
  39. void CFolder::SetScopeItemInformation(int nImage, int nOpenImage)
  40. {
  41. // Add close image
  42. m_ScopeItem.mask |= SDI_IMAGE;
  43. m_ScopeItem.nImage = nImage;
  44. // Add open image
  45. m_ScopeItem.mask |= SDI_OPENIMAGE;
  46. m_ScopeItem.nOpenImage = nOpenImage;
  47. }
  48. // IPersistStream interface members
  49. HRESULT
  50. CFolder::Load(IStream *pStm)
  51. {
  52. HRESULT hr;
  53. ASSERT(pStm);
  54. DWORD dwVer;
  55. CString cstr;
  56. int nImage;
  57. int nOpenImage;
  58. SCOPE_TYPES itemScopeType;
  59. FOLDER_TYPES itemFolderType;
  60. int iChildren;
  61. // load important properties
  62. hr = ReadOfSize(pStm, &dwVer, sizeof(DWORD));
  63. _JumpIfError(hr, Ret, "Load dwVer");
  64. // check to see if correct version
  65. ASSERT(dwVer == VER_FOLDER_SAVE_STREAM_2 || dwVer == VER_FOLDER_SAVE_STREAM_1);
  66. if ((VER_FOLDER_SAVE_STREAM_2 != dwVer) && (dwVer != VER_FOLDER_SAVE_STREAM_1))
  67. {
  68. hr = STG_E_OLDFORMAT;
  69. _JumpError(hr, Ret, "Unsupported Version");
  70. }
  71. // LPCWSTR szName
  72. hr = CStringLoad(cstr, pStm);
  73. _JumpIfError(hr, Ret, "CStringLoad");
  74. hr = ReadOfSize(pStm, &nImage, sizeof(int));
  75. _JumpIfError(hr, Ret, "ReadOfSize nImage");
  76. hr = ReadOfSize(pStm, &nOpenImage, sizeof(int));
  77. _JumpIfError(hr, Ret, "ReadOfSize nOpenImage");
  78. hr = ReadOfSize(pStm, &itemScopeType, sizeof(SCOPE_TYPES));
  79. _JumpIfError(hr, Ret, "ReadOfSize itemScopeType");
  80. hr = ReadOfSize(pStm, &itemFolderType, sizeof(FOLDER_TYPES));
  81. _JumpIfError(hr, Ret, "ReadOfSize itemFolderType");
  82. hr = ReadOfSize(pStm, &iChildren, sizeof(int));
  83. _JumpIfError(hr, Ret, "ReadOfSize iChildren");
  84. // call create with this data
  85. SetProperties(cstr, itemScopeType, itemFolderType, iChildren);
  86. SetScopeItemInformation(nImage, nOpenImage);
  87. // old ver: pull out dead enumerator
  88. if (dwVer == VER_FOLDER_SAVE_STREAM_1)
  89. {
  90. CertViewRowEnum cRowEnum;
  91. hr = cRowEnum.Load(pStm);
  92. _JumpIfError(hr, Ret, "Load cRowEnum");
  93. }
  94. Ret:
  95. return hr;
  96. }
  97. HRESULT
  98. CFolder::Save(IStream *pStm, BOOL fClearDirty)
  99. {
  100. HRESULT hr;
  101. ASSERT(pStm);
  102. DWORD dwVer;
  103. CString cstr;
  104. // save important properties
  105. // Write the version
  106. dwVer = VER_FOLDER_SAVE_STREAM_2;
  107. hr = WriteOfSize(pStm, &dwVer, sizeof(DWORD));
  108. _JumpIfError(hr, Ret, "WriteOfSize dwVer");
  109. // LPCWSTR szName
  110. cstr = (LPCWSTR)m_pszName;
  111. hr = CStringSave(cstr, pStm, fClearDirty);
  112. _JumpIfError(hr, Ret, "CStringSave");
  113. // int nImage
  114. hr = WriteOfSize(pStm, &m_ScopeItem.nImage, sizeof(int));
  115. _JumpIfError(hr, Ret, "WriteOfSize nImage");
  116. // int nOpenImage
  117. hr = WriteOfSize(pStm, &m_ScopeItem.nOpenImage, sizeof(int));
  118. _JumpIfError(hr, Ret, "WriteOfSize nOpenImage");
  119. // SCOPE_TYPES itemType
  120. hr = WriteOfSize(pStm, &m_itemType, sizeof(SCOPE_TYPES));
  121. _JumpIfError(hr, Ret, "WriteOfSize m_itemType");
  122. // FOLDER_TYPES type
  123. hr = WriteOfSize(pStm, &m_type, sizeof(FOLDER_TYPES));
  124. _JumpIfError(hr, Ret, "WriteOfSize m_type");
  125. // int iChildren
  126. hr = WriteOfSize(pStm, &m_ScopeItem.cChildren, sizeof(int));
  127. _JumpIfError(hr, Ret, "WriteOfSize cChildren");
  128. // hr = m_RowEnum.Save(pStm, fClearDirty);
  129. // _JumpIfError(hr, Ret, "Save m_RowEnum");
  130. Ret:
  131. return hr;
  132. }
  133. HRESULT
  134. CFolder::GetSizeMax(int *pcbSize)
  135. {
  136. ASSERT(pcbSize);
  137. int iSize;
  138. // version
  139. iSize = sizeof(DWORD);
  140. // LPCWSTR szName
  141. CString cstr = m_pszName;
  142. CStringGetSizeMax(cstr, &iSize);
  143. // int nImage
  144. iSize += sizeof(int);
  145. // int nOpenImage
  146. iSize += sizeof(int);
  147. // SCOPE_TYPES
  148. iSize += sizeof(SCOPE_TYPES);
  149. // FOLDER_TYPES
  150. iSize += sizeof(FOLDER_TYPES);
  151. // BOOL bHasChildren (actually saved as int)
  152. iSize += sizeof(int);
  153. // int iAdditionalSize = 0;
  154. // m_RowEnum.GetSizeMax(&iAdditionalSize);
  155. // iSize += iAdditionalSize;
  156. *pcbSize = iSize;
  157. return S_OK;
  158. }
  159. BOOL IsAllowedStartStop(CFolder* pFolder, CertSvrMachine* pMachine)
  160. {
  161. BOOL fRightPlace = (pFolder == NULL) || (SERVER_INSTANCE == pFolder->GetType());
  162. ASSERT(NULL != pMachine);
  163. // must be at right node and there must be CAs here
  164. return ( fRightPlace && (0 != pMachine->GetCaCount()) );
  165. }
  166. HRESULT GetCurrentColumnSchema(
  167. IN LPCWSTR szConfig,
  168. IN BOOL fCertView,
  169. OUT CString** pprgcstrColumns,
  170. OUT OPTIONAL LONG** pprglTypes,
  171. OUT OPTIONAL BOOL** pprgfIndexed,
  172. OUT LONG* plEntries)
  173. {
  174. HRESULT hr;
  175. BOOL fGetTypes = pprglTypes != NULL;
  176. LONG* prglTypes = NULL;
  177. BOOL fGetIsIndexed = pprgfIndexed != NULL;
  178. BOOL* prgfIndexed = NULL;
  179. ICertView* pICertView = NULL;
  180. IEnumCERTVIEWCOLUMN* pColEnum = NULL;
  181. IEnumCERTVIEWROW *pRowEnum = NULL;
  182. BSTR bstrColumn = NULL;
  183. int colIdx=0;
  184. //LPWSTR* prgszCols = NULL;
  185. CString* prgcstrColumns = NULL;
  186. LONG lCols;
  187. int i;
  188. hr = CoCreateInstance(
  189. CLSID_CCertView,
  190. NULL, // pUnkOuter
  191. CLSCTX_INPROC_SERVER,
  192. fCertView? IID_ICertView : IID_ICertView2,
  193. (VOID **) &pICertView);
  194. _JumpIfError(hr, Ret, "CoCreateInstance");
  195. ASSERT(NULL != szConfig);
  196. hr = pICertView->OpenConnection(_bstr_t(szConfig));
  197. _JumpIfError(hr, Ret, "OpenConnection");
  198. if (!fCertView)
  199. {
  200. hr = ((ICertView2 *) pICertView)->SetTable(CVRC_TABLE_CRL);
  201. _JumpIfError(hr, Ret, "SetTable");
  202. }
  203. hr = pICertView->OpenView(&pRowEnum);
  204. _JumpIfError(hr, Ret, "OpenView");
  205. hr = pICertView->GetColumnCount(FALSE, &lCols);
  206. _JumpIfError(hr, Ret, "GetColumnCount");
  207. // we need a place to store each LPWSTR
  208. prgcstrColumns = new CString[lCols];
  209. _JumpIfOutOfMemory(hr, Ret, prgcstrColumns);
  210. if (fGetTypes)
  211. {
  212. prglTypes = new LONG[lCols];
  213. _JumpIfOutOfMemory(hr, Ret, prglTypes);
  214. }
  215. if (fGetIsIndexed)
  216. {
  217. prgfIndexed = new BOOL[lCols];
  218. _JumpIfOutOfMemory(hr, Ret, prgfIndexed);
  219. }
  220. // get column enumerator
  221. hr = pICertView->EnumCertViewColumn(FALSE, &pColEnum);
  222. _JumpIfError(hr, Ret, "EnumCertViewColumn");
  223. for (i=0; i<lCols; i++)
  224. {
  225. hr = pColEnum->Next((LONG*)&colIdx);
  226. _JumpIfError(hr, Ret, "Next");
  227. hr = pColEnum->GetName(&bstrColumn);
  228. if (NULL == bstrColumn)
  229. hr = E_UNEXPECTED;
  230. _JumpIfError(hr, Ret, "GetName");
  231. prgcstrColumns[i] = bstrColumn; // wcscpy
  232. if (fGetTypes)
  233. {
  234. hr = pColEnum->GetType(&prglTypes[i]);
  235. _JumpIfError(hr, Ret, "GetType");
  236. }
  237. if (fGetIsIndexed)
  238. {
  239. hr = pColEnum->IsIndexed((LONG*)&prgfIndexed[i]);
  240. _JumpIfError(hr, Ret, "IsIndexed");
  241. }
  242. // next GetName call will free bstrColumn
  243. // SysFreeString(bstrColumn);
  244. // bstrColumn = NULL;
  245. }
  246. // assign to out param
  247. if (fGetTypes)
  248. {
  249. *pprglTypes = prglTypes;
  250. prglTypes = NULL;
  251. }
  252. if (fGetIsIndexed)
  253. {
  254. *pprgfIndexed = prgfIndexed;
  255. prgfIndexed = NULL;
  256. }
  257. *pprgcstrColumns = prgcstrColumns;
  258. prgcstrColumns = NULL;
  259. *plEntries = lCols;
  260. hr = S_OK;
  261. Ret:
  262. if (pICertView)
  263. pICertView->Release();
  264. if (pColEnum)
  265. pColEnum->Release();
  266. if (pRowEnum)
  267. pRowEnum->Release();
  268. if (bstrColumn)
  269. SysFreeString(bstrColumn);
  270. if (prglTypes)
  271. delete [] prglTypes;
  272. if (prgfIndexed)
  273. delete [] prgfIndexed;
  274. if (prgcstrColumns)
  275. delete [] prgcstrColumns;
  276. return hr;
  277. }
  278. // row operations
  279. CertViewRowEnum::CertViewRowEnum()
  280. {
  281. m_pICertView = NULL;
  282. m_fCertViewOpenAttempted = FALSE;
  283. m_pRowEnum = NULL;
  284. m_pRestrictions[0] = NULL;
  285. m_pRestrictions[1] = NULL;
  286. m_fRestrictionsActive[0] = FALSE;
  287. m_fRestrictionsActive[1] = FALSE;
  288. m_dwColumnCount = 0;
  289. m_prgColPropCache = NULL;
  290. m_dwErr = 0;
  291. m_fCertView = TRUE;
  292. InvalidateCachedRowEnum();
  293. }
  294. CertViewRowEnum::~CertViewRowEnum()
  295. {
  296. InvalidateCachedRowEnum();
  297. FreeColumnCacheInfo();
  298. if (m_pICertView)
  299. {
  300. VERIFY(0 == m_pICertView->Release());
  301. m_pICertView = NULL;
  302. }
  303. for (int i = 0; i < ARRAYSIZE(m_pRestrictions); i++)
  304. {
  305. if (m_pRestrictions[i])
  306. {
  307. FreeQueryRestrictionList(m_pRestrictions[i]);
  308. m_pRestrictions[i] = NULL;
  309. }
  310. m_fRestrictionsActive[i] = FALSE;
  311. }
  312. }
  313. HRESULT IsColumnShown(MMC_COLUMN_SET_DATA* pCols, ULONG idxCol, BOOL* pfShown)
  314. {
  315. if (idxCol > (ULONG)pCols->nNumCols)
  316. return ERROR_INVALID_INDEX;
  317. *pfShown = (pCols->pColData[idxCol].dwFlags != HDI_HIDDEN);
  318. return S_OK;
  319. }
  320. HRESULT CountShownColumns(MMC_COLUMN_SET_DATA* pCols, ULONG* plCols)
  321. {
  322. HRESULT hr = S_OK;
  323. *plCols = 0;
  324. // set col cache correctly
  325. for (int i=0; i<pCols->nNumCols; i++)
  326. {
  327. BOOL fShown;
  328. hr = IsColumnShown(pCols, i, &fShown);
  329. _JumpIfError(hr, Ret, "IsColumnShown");
  330. // update
  331. if (fShown)
  332. (*plCols)++;
  333. }
  334. Ret:
  335. return hr;
  336. }
  337. HRESULT CertViewRowEnum::Load(IStream *pStm)
  338. {
  339. HRESULT hr;
  340. ASSERT(pStm);
  341. DWORD dwVer;
  342. DWORD iRestrictions;
  343. PQUERY_RESTRICTION pCurRestriction = NULL;
  344. DWORD iRestrictionNum;
  345. // load important properties
  346. hr = ReadOfSize(pStm, &dwVer, sizeof(DWORD));
  347. _JumpIfError(hr, Ret, "Load dwVer");
  348. // check to see if this is a supported version
  349. ASSERT((dwVer == VER_CERTVIEWROWENUM_SAVE_STREAM_3) ||
  350. (dwVer == VER_CERTVIEWROWENUM_SAVE_STREAM_4));
  351. if ((VER_CERTVIEWROWENUM_SAVE_STREAM_4 != dwVer) &&
  352. (VER_CERTVIEWROWENUM_SAVE_STREAM_3 != dwVer))
  353. {
  354. hr = STG_E_OLDFORMAT;
  355. _JumpError(hr, Ret, "dwVer");
  356. }
  357. // version-dependent: throw away sort order
  358. if (VER_CERTVIEWROWENUM_SAVE_STREAM_3 == dwVer)
  359. {
  360. LONG lSortOrder;
  361. CString cstrSortCol;
  362. ReadOfSize(pStm, &lSortOrder, sizeof(LONG));
  363. _JumpIfError(hr, Ret, "ReadOfSize lSortOrder");
  364. CStringLoad(cstrSortCol, pStm);
  365. }
  366. // fRestrictionsActive;
  367. hr = ReadOfSize(pStm, &m_fRestrictionsActive, sizeof(BOOL));
  368. _JumpIfError(hr, Ret, "ReadOfSize m_fRestrictionsActive");
  369. hr = ReadOfSize(pStm, &iRestrictions, sizeof(DWORD));
  370. _JumpIfError(hr, Ret, "ReadOfSize iRestrictions");
  371. for(iRestrictionNum=0; iRestrictionNum<iRestrictions; iRestrictionNum++)
  372. {
  373. // LPCWSTR szField
  374. CString cstr;
  375. UINT iOperation;
  376. VARIANT varValue;
  377. hr = CStringLoad(cstr, pStm);
  378. _JumpIfError(hr, Ret, "CStringLoad");
  379. // UINT iOperation
  380. hr = ReadOfSize(pStm, &iOperation, sizeof(int));
  381. _JumpIfError(hr, Ret, "ReadOfSize");
  382. // VARIANT varValue
  383. hr = VariantLoad(varValue, pStm);
  384. _JumpIfError(hr, Ret, "VariantLoad");
  385. // insert at end of list
  386. if (NULL == pCurRestriction)
  387. {
  388. // 1st restriction
  389. m_pRestrictions[1] = NewQueryRestriction((LPCWSTR)cstr, iOperation, &varValue);
  390. _JumpIfOutOfMemory(hr, Ret, m_pRestrictions[1]);
  391. pCurRestriction = m_pRestrictions[1];
  392. }
  393. else
  394. {
  395. pCurRestriction->pNext = NewQueryRestriction((LPCWSTR)cstr, iOperation, &varValue);
  396. _JumpIfOutOfMemory(hr, Ret, pCurRestriction->pNext);
  397. pCurRestriction = pCurRestriction->pNext;
  398. }
  399. }
  400. // version-dependent data: column sizes
  401. if (dwVer == VER_CERTVIEWROWENUM_SAVE_STREAM_3)
  402. {
  403. // now load column sizes (NOW DEFUNCT -- mmc saves for us)
  404. // number of cols DWORD dwColSize
  405. DWORD dwColSize;
  406. DWORD dwCol;
  407. LONG lViewType;
  408. hr = ReadOfSize(pStm, &dwColSize, sizeof(DWORD));
  409. _JumpIfError(hr, Ret, "ReadOfSize dwColSize");
  410. for(dwCol=0; dwCol<dwColSize; dwCol++)
  411. {
  412. // BOOL fValid
  413. BOOL fValid;
  414. int iSize;
  415. BOOL fUnLocColHead;
  416. hr = ReadOfSize(pStm, &fValid, sizeof(BOOL));
  417. _JumpIfError(hr, Ret, "ReadOfSize fValid");
  418. // int iSize
  419. hr = ReadOfSize(pStm, &iSize, sizeof(int));
  420. _JumpIfError(hr, Ret, "ReadOfSize iSize");
  421. // BOOL fUnLocColHead
  422. hr = ReadOfSize(pStm, &fUnLocColHead, sizeof(BOOL));
  423. _JumpIfError(hr, Ret, "ReadOfSize fUnLocColHead");
  424. // load only if exists
  425. if (fUnLocColHead)
  426. {
  427. CString cstrUnLocColHead;
  428. hr = CStringLoad(cstrUnLocColHead, pStm);
  429. _JumpIfError(hr, Ret, "CStringLoad");
  430. }
  431. }
  432. // view type
  433. hr = ReadOfSize(pStm, &lViewType, sizeof(LONG));
  434. _JumpIfError(hr, Ret, "ReadOfSize lViewType");
  435. } // version 3 data
  436. Ret:
  437. return hr;
  438. }
  439. HRESULT CertViewRowEnum::Save(IStream *pStm, BOOL fClearDirty)
  440. {
  441. ASSERT(pStm);
  442. HRESULT hr;
  443. DWORD dwVer;
  444. int iRestrictions = 0;
  445. PQUERY_RESTRICTION pRestrict;
  446. // save important properties
  447. // Write the version
  448. dwVer = VER_CERTVIEWROWENUM_SAVE_STREAM_4;
  449. hr = WriteOfSize(pStm, &dwVer, sizeof(DWORD));
  450. _JumpIfError(hr, Ret, "WriteOfSize dwVer");
  451. // BOOL fRestrictionsActive
  452. hr = WriteOfSize(pStm, &m_fRestrictionsActive, sizeof(BOOL));
  453. _JumpIfError(hr, Ret, "WriteOfSize m_fRestrictionsActive");
  454. // count restrictions
  455. pRestrict = m_pRestrictions[1];
  456. while(pRestrict)
  457. {
  458. iRestrictions++;
  459. pRestrict = pRestrict->pNext;
  460. }
  461. // int iRestrictions
  462. hr = WriteOfSize(pStm, &iRestrictions, sizeof(int));
  463. _JumpIfError(hr, Ret, "WriteOfSize iRestrictions");
  464. // write each restriction in turn
  465. pRestrict = m_pRestrictions[1];
  466. while(pRestrict)
  467. {
  468. // LPCWSTR szField
  469. CString cstr = pRestrict->szField;
  470. hr = CStringSave(cstr, pStm, fClearDirty);
  471. _JumpIfError(hr, Ret, "CStringSave");
  472. // UINT iOperation
  473. hr = WriteOfSize(pStm, &pRestrict->iOperation, sizeof(UINT));
  474. _JumpIfError(hr, Ret, "WriteOfSize iOperation");
  475. // VARIANT varValue
  476. hr = VariantSave(pRestrict->varValue, pStm, fClearDirty);
  477. _JumpIfError(hr, Ret, "VariantSave varValue");
  478. pRestrict = pRestrict->pNext;
  479. }
  480. Ret:
  481. return hr;
  482. }
  483. HRESULT CertViewRowEnum::GetSizeMax(int *pcbSize)
  484. {
  485. ASSERT(pcbSize);
  486. // version
  487. *pcbSize = sizeof(DWORD);
  488. // fRestrictionsActive
  489. *pcbSize += sizeof(BOOL);
  490. // iRestrictions
  491. *pcbSize += sizeof(int);
  492. // size each restriction
  493. PQUERY_RESTRICTION pRestrict = m_pRestrictions[1];
  494. while(pRestrict)
  495. {
  496. // LPCWSTR szField
  497. int iSize;
  498. CString cstr = pRestrict->szField;
  499. CStringGetSizeMax(cstr, &iSize);
  500. *pcbSize += iSize;
  501. // UINT iOperation
  502. *pcbSize += sizeof(UINT);
  503. // VARIANT
  504. VariantGetSizeMax(pRestrict->varValue, &iSize);
  505. *pcbSize += iSize;
  506. }
  507. return S_OK;
  508. }
  509. HRESULT CertViewRowEnum::GetView(CertSvrCA* pCA, ICertView** ppView)
  510. {
  511. HRESULT hr = S_OK;
  512. // if tried to get result
  513. if (m_fCertViewOpenAttempted)
  514. {
  515. *ppView = m_pICertView;
  516. ASSERT(m_pICertView || m_dwErr);
  517. return (m_pICertView==NULL) ? m_dwErr : S_OK;
  518. }
  519. if (m_pICertView)
  520. {
  521. m_pICertView->Release();
  522. m_pICertView = NULL;
  523. }
  524. if (!pCA->m_pParentMachine->IsCertSvrServiceRunning())
  525. {
  526. *ppView = NULL;
  527. hr = RPC_S_NOT_LISTENING;
  528. _JumpError(hr, Ret, "IsCertSvrServiceRunning");
  529. }
  530. m_fCertViewOpenAttempted = TRUE;
  531. hr = CoCreateInstance(
  532. CLSID_CCertView,
  533. NULL, // pUnkOuter
  534. CLSCTX_INPROC_SERVER,
  535. g_fCertViewOnly? IID_ICertView : IID_ICertView2,
  536. (VOID **) &m_pICertView);
  537. _JumpIfError(hr, Ret, "CoCreateInstance");
  538. ASSERT(NULL != pCA->m_bstrConfig);
  539. hr = m_pICertView->OpenConnection(pCA->m_bstrConfig);
  540. _JumpIfError(hr, Ret, "OpenConnection");
  541. Ret:
  542. if (hr != S_OK)
  543. {
  544. if (m_pICertView)
  545. {
  546. m_pICertView->Release();
  547. m_pICertView = NULL;
  548. }
  549. }
  550. m_dwErr = hr;
  551. *ppView = m_pICertView;
  552. return hr;
  553. }
  554. HRESULT CertViewRowEnum::GetRowEnum(CertSvrCA* pCA, IEnumCERTVIEWROW** ppRowEnum)
  555. {
  556. if (m_fRowEnumOpenAttempted)
  557. {
  558. *ppRowEnum = m_pRowEnum;
  559. ASSERT(m_pRowEnum || m_dwErr);
  560. return (m_pRowEnum == NULL) ? m_dwErr : S_OK;
  561. }
  562. ASSERT(m_pRowEnum == NULL);
  563. ASSERT(m_idxRowEnum == -1);
  564. m_fRowEnumOpenAttempted = TRUE;
  565. HRESULT hr;
  566. ICertView* pView;
  567. hr = GetView(pCA, &pView);
  568. _JumpIfError(hr, Ret, "GetView");
  569. hr = pView->OpenView(&m_pRowEnum);
  570. _JumpIfError(hr, Ret, "OpenView");
  571. Ret:
  572. *ppRowEnum = m_pRowEnum;
  573. m_dwErr = hr;
  574. return hr;
  575. };
  576. void CertViewRowEnum::InvalidateCachedRowEnum()
  577. {
  578. if (m_pRowEnum)
  579. {
  580. m_pRowEnum->Release();
  581. m_pRowEnum = NULL;
  582. }
  583. m_idxRowEnum = -1;
  584. m_fRowEnumOpenAttempted = FALSE;
  585. // results
  586. m_fKnowNumResultRows = FALSE;
  587. m_dwResultRows = 0;
  588. }
  589. HRESULT CertViewRowEnum::ResetCachedRowEnum()
  590. {
  591. HRESULT hr = S_OK;
  592. if (m_pRowEnum)
  593. {
  594. hr = m_pRowEnum->Reset();
  595. m_idxRowEnum = -1;
  596. }
  597. return hr;
  598. };
  599. HRESULT CertViewRowEnum::GetRowMaxIndex(CertSvrCA* pCA, LONG* pidxMax)
  600. {
  601. HRESULT hr;
  602. IEnumCERTVIEWROW* pRowEnum; // don't have to free, just a ref to class member
  603. ASSERT(pidxMax);
  604. hr = GetRowEnum(pCA, &pRowEnum);
  605. _JumpIfError(hr, Ret, "GetRowEnum");
  606. hr = pRowEnum->GetMaxIndex(pidxMax);
  607. _JumpIfError(hr, Ret, "GetMaxIndex");
  608. // update max
  609. if (!m_fKnowNumResultRows)
  610. {
  611. m_dwResultRows = *pidxMax;
  612. m_fKnowNumResultRows = TRUE;
  613. }
  614. Ret:
  615. return hr;
  616. }
  617. #if 0// DBG
  618. void ReportMove(LONG idxCur, LONG idxDest, LONG skip)
  619. {
  620. if ((idxDest == 0) && (skip == 0))
  621. {
  622. DBGPRINT((DBG_SS_CERTMMC, "Cur %i Dest 0 <RESET><NEXT>\n", idxCur));
  623. return;
  624. }
  625. DBGPRINT((DBG_SS_CERTMMC, "Cur %i Dest %i <SKIP %i><NEXT>\n", idxCur, idxDest, skip));
  626. }
  627. #else
  628. #define ReportMove(_x_, _y_, _z_)
  629. #endif
  630. HRESULT CertViewRowEnum::SetRowEnumPos(LONG idxRow)
  631. {
  632. // make input ones-based
  633. // seek there smartly
  634. HRESULT hr;
  635. // already positioned correctly
  636. if (idxRow == m_idxRowEnum)
  637. return S_OK;
  638. // Next() could take awhile
  639. CWaitCursor cwait;
  640. ResetCachedRowEnum();
  641. hr = m_pRowEnum->Skip(idxRow);
  642. _JumpIfError(hr, Ret, "Skip");
  643. LONG lTmp;
  644. hr = m_pRowEnum->Next(&lTmp);
  645. if (hr != S_OK)
  646. {
  647. // ignore reentrance error in ICertView (bug 339811)
  648. if(hr != E_UNEXPECTED)
  649. {
  650. ResetCachedRowEnum();
  651. }
  652. _JumpError2(hr, Ret, "Next", S_FALSE);
  653. }
  654. // we should be successfully seeked to result row (ones-based)
  655. ASSERT(lTmp == idxRow+1);
  656. // else okay, we seeked correctly
  657. m_idxRowEnum = idxRow;
  658. // update max if necessary
  659. if (m_idxRowEnum+1 > (int)m_dwResultRows)
  660. m_dwResultRows = m_idxRowEnum+1;
  661. Ret:
  662. // ignore reentrance error in ICertView (bug 339811)
  663. if(hr==E_UNEXPECTED)
  664. {
  665. hr = S_OK;
  666. }
  667. return hr;
  668. };
  669. // DB Column Property Caches
  670. void CertViewRowEnum::FreeColumnCacheInfo()
  671. {
  672. if (m_prgColPropCache)
  673. {
  674. LocalFree(m_prgColPropCache);
  675. m_prgColPropCache = NULL;
  676. }
  677. m_dwColumnCount = 0;
  678. }
  679. HRESULT CertViewRowEnum::SetColumnCacheInfo(
  680. IN int iIndex, // db col
  681. IN int idxViewCol) // 0...X
  682. {
  683. if (m_dwColumnCount <= (DWORD)iIndex)
  684. return HRESULT_FROM_WIN32(ERROR_INVALID_INDEX);
  685. m_prgColPropCache[iIndex].iViewCol = idxViewCol;
  686. return S_OK;
  687. }
  688. HRESULT CertViewRowEnum::GetColumnCacheInfo(
  689. int iIndex, // 0..x
  690. int* piViewIndex) // db col
  691. {
  692. if (m_dwColumnCount <= (DWORD)iIndex)
  693. return HRESULT_FROM_WIN32(ERROR_INVALID_INDEX);
  694. // don't let uninitialized elements get through
  695. if (m_prgColPropCache[iIndex].iViewCol == -1)
  696. {
  697. // Handle mmc bug:
  698. // This is commonly caused by race condition between time
  699. // we get an MMCN_COLUMNS_CHANGED for a col removal and the
  700. // listview asking to update the removed column. AnandhaG knows about
  701. // this bug.
  702. // so that we don't fail the whole view, just go on about your business
  703. DBGPRINT((DBG_SS_CERTMMC, "GetColumnCacheInfo error: unknown dbcol = %i\n", iIndex));
  704. return HRESULT_FROM_WIN32(ERROR_CONTINUE);
  705. }
  706. if (piViewIndex)
  707. *piViewIndex = m_prgColPropCache[iIndex].iViewCol;
  708. return S_OK;
  709. }
  710. // This is a destructive operation, and resets EVERYTHING about the column cache
  711. HRESULT CertViewRowEnum::ResetColumnCount(LONG lCols)
  712. {
  713. HRESULT hr = S_OK;
  714. if ((DWORD)lCols != m_dwColumnCount)
  715. {
  716. void* pvNewAlloc;
  717. // for view properties
  718. if (m_prgColPropCache)
  719. pvNewAlloc = LocalReAlloc(m_prgColPropCache, sizeof(COLUMN_TYPE_CACHE)*lCols, LMEM_MOVEABLE);
  720. else
  721. pvNewAlloc = LocalAlloc(LMEM_FIXED, sizeof(COLUMN_TYPE_CACHE)*lCols);
  722. if (NULL == pvNewAlloc)
  723. {
  724. hr = E_OUTOFMEMORY;
  725. _JumpError(hr, Ret, "Local(Re)Alloc");
  726. }
  727. m_prgColPropCache = (COLUMN_TYPE_CACHE*)pvNewAlloc;
  728. m_dwColumnCount = lCols;
  729. }
  730. // initialize with -1s -- invalidate cache
  731. FillMemory(m_prgColPropCache, m_dwColumnCount * sizeof(COLUMN_TYPE_CACHE), 0xff);
  732. Ret:
  733. return hr;
  734. }