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.

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