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.

518 lines
9.8 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1999
  5. //
  6. // File: attrib.cpp
  7. //
  8. // Contents: Cert Server Database interface implementation
  9. //
  10. //---------------------------------------------------------------------------
  11. #include <pch.cpp>
  12. #pragma hdrstop
  13. #include <certdb.h>
  14. #include "csdisp.h"
  15. #include "column.h"
  16. #include "attrib.h"
  17. #include "ext.h"
  18. #include "row.h"
  19. #include "view.h"
  20. #if DBG_CERTSRV
  21. LONG g_cCertViewAttribute;
  22. LONG g_cCertViewAttributeTotal;
  23. #endif
  24. CEnumCERTVIEWATTRIBUTE::CEnumCERTVIEWATTRIBUTE()
  25. {
  26. DBGCODE(InterlockedIncrement(&g_cCertViewAttribute));
  27. DBGCODE(InterlockedIncrement(&g_cCertViewAttributeTotal));
  28. m_pvw = NULL;
  29. m_aelt = NULL;
  30. m_cRef = 1;
  31. }
  32. CEnumCERTVIEWATTRIBUTE::~CEnumCERTVIEWATTRIBUTE()
  33. {
  34. DBGCODE(InterlockedDecrement(&g_cCertViewAttribute));
  35. #if DBG_CERTSRV
  36. if (m_cRef > 1)
  37. {
  38. DBGPRINT((
  39. DBG_SS_CERTVIEWI,
  40. "%hs has %d instances left over\n",
  41. "CEnumCERTVIEWATTRIBUTE",
  42. m_cRef));
  43. }
  44. #endif
  45. if (NULL != m_aelt)
  46. {
  47. LocalFree(m_aelt);
  48. m_aelt = NULL;
  49. }
  50. if (NULL != m_pvw)
  51. {
  52. m_pvw->Release();
  53. m_pvw = NULL;
  54. }
  55. }
  56. HRESULT
  57. CEnumCERTVIEWATTRIBUTE::Open(
  58. IN LONG RowId,
  59. IN LONG Flags,
  60. IN ICertView *pvw)
  61. {
  62. HRESULT hr;
  63. if (NULL == pvw)
  64. {
  65. hr = E_POINTER;
  66. _JumpError(hr, error, "NULL parm");
  67. }
  68. m_RowId = RowId;
  69. m_Flags = Flags;
  70. m_pvw = pvw;
  71. m_pvw->AddRef();
  72. if (0 != Flags)
  73. {
  74. hr = E_INVALIDARG;
  75. _JumpError(hr, error, "Flags");
  76. }
  77. hr = Reset();
  78. _JumpIfError2(hr, error, "Reset", S_FALSE);
  79. error:
  80. return(hr);
  81. }
  82. STDMETHODIMP
  83. CEnumCERTVIEWATTRIBUTE::Next(
  84. /* [out, retval] */ LONG *pIndex)
  85. {
  86. HRESULT hr;
  87. DWORD celt;
  88. CERTTRANSBLOB ctbAttributes;
  89. ctbAttributes.pb = NULL;
  90. if (NULL == pIndex)
  91. {
  92. hr = E_POINTER;
  93. _JumpError(hr, error, "NULL parm");
  94. }
  95. *pIndex = -1;
  96. if (m_ieltCurrent + 1 >= m_celtCurrent && !m_fNoMore)
  97. {
  98. hr = ((CCertView *) m_pvw)->EnumAttributesOrExtensions(
  99. m_RowId,
  100. CDBENUM_ATTRIBUTES,
  101. NULL == m_aelt?
  102. NULL :
  103. m_aelt[m_ieltCurrent].pwszName,
  104. CEXT_CHUNK,
  105. &celt,
  106. &ctbAttributes);
  107. if (S_FALSE == hr)
  108. {
  109. m_fNoMore = TRUE;
  110. }
  111. else
  112. {
  113. _JumpIfError(hr, error, "EnumAttributesOrExtensions");
  114. }
  115. hr = _SaveAttributes(celt, &ctbAttributes);
  116. _JumpIfError(hr, error, "_SaveAttributes");
  117. m_ieltCurrent = -1;
  118. m_celtCurrent = celt;
  119. }
  120. if (m_ieltCurrent + 1 >= m_celtCurrent)
  121. {
  122. hr = S_FALSE;
  123. goto error;
  124. }
  125. m_ielt++;
  126. m_ieltCurrent++;
  127. *pIndex = m_ielt;
  128. m_fNoCurrentRecord = FALSE;
  129. hr = S_OK;
  130. error:
  131. if (NULL != ctbAttributes.pb)
  132. {
  133. CoTaskMemFree(ctbAttributes.pb);
  134. }
  135. return(_SetErrorInfo(hr, L"CEnumCERTVIEWATTRIBUTE::Next"));
  136. }
  137. HRESULT
  138. CEnumCERTVIEWATTRIBUTE::_SaveAttributes(
  139. IN DWORD celt,
  140. IN CERTTRANSBLOB const *pctbAttributes)
  141. {
  142. HRESULT hr;
  143. DWORD cbNew;
  144. CERTDBATTRIBUTE *peltNew = NULL;
  145. CERTDBATTRIBUTE *pelt;
  146. CERTTRANSDBATTRIBUTE *ptelt;
  147. CERTTRANSDBATTRIBUTE *pteltEnd;
  148. BYTE *pbNext;
  149. BYTE *pbEnd;
  150. if (NULL == pctbAttributes)
  151. {
  152. hr = E_POINTER;
  153. _JumpError(hr, error, "NULL parm");
  154. }
  155. cbNew = pctbAttributes->cb + celt * (sizeof(*pelt) - sizeof(*ptelt));
  156. peltNew = (CERTDBATTRIBUTE *) LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, cbNew);
  157. if (NULL == peltNew)
  158. {
  159. hr = E_OUTOFMEMORY;
  160. _JumpError(hr, error, "LocalAlloc");
  161. }
  162. pteltEnd = &((CERTTRANSDBATTRIBUTE *) pctbAttributes->pb)[celt];
  163. if ((BYTE *) pteltEnd > &pctbAttributes->pb[pctbAttributes->cb])
  164. {
  165. hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
  166. _JumpError(hr, error, "bad marshalled data");
  167. }
  168. pelt = peltNew;
  169. pbNext = (BYTE *) &peltNew[celt];
  170. pbEnd = (BYTE *) Add2Ptr(peltNew, cbNew);
  171. for (ptelt = (CERTTRANSDBATTRIBUTE *) pctbAttributes->pb;
  172. ptelt < pteltEnd;
  173. ptelt++, pelt++)
  174. {
  175. hr = CopyMarshalledString(
  176. pctbAttributes,
  177. ptelt->obwszName,
  178. pbEnd,
  179. &pbNext,
  180. &pelt->pwszName);
  181. _JumpIfError(hr, error, "CopyMarshalledString");
  182. hr = CopyMarshalledString(
  183. pctbAttributes,
  184. ptelt->obwszValue,
  185. pbEnd,
  186. &pbNext,
  187. &pelt->pwszValue);
  188. _JumpIfError(hr, error, "CopyMarshalledString");
  189. }
  190. CSASSERT(pbNext == (BYTE *) Add2Ptr(peltNew, cbNew));
  191. if (NULL != m_aelt)
  192. {
  193. LocalFree(m_aelt);
  194. }
  195. m_aelt = peltNew;
  196. peltNew = NULL;
  197. hr = S_OK;
  198. error:
  199. if (NULL != peltNew)
  200. {
  201. LocalFree(peltNew);
  202. }
  203. return(hr);
  204. }
  205. HRESULT
  206. CEnumCERTVIEWATTRIBUTE::_FindAttribute(
  207. OUT CERTDBATTRIBUTE const **ppcda)
  208. {
  209. HRESULT hr;
  210. if (NULL == ppcda)
  211. {
  212. hr = E_POINTER;
  213. _JumpError(hr, error, "NULL parm");
  214. }
  215. if (NULL == m_aelt)
  216. {
  217. hr = E_UNEXPECTED;
  218. _JumpError(hr, error, "NULL m_aelt");
  219. }
  220. if (m_fNoCurrentRecord ||
  221. m_ieltCurrent < 0 ||
  222. m_ieltCurrent >= m_celtCurrent)
  223. {
  224. hr = E_INVALIDARG;
  225. _JumpError(hr, error, "m_fNoCurrentRecord || m_ieltCurrent");
  226. }
  227. *ppcda = &m_aelt[m_ieltCurrent];
  228. hr = S_OK;
  229. error:
  230. return(hr);
  231. }
  232. STDMETHODIMP
  233. CEnumCERTVIEWATTRIBUTE::GetName(
  234. /* [out, retval] */ BSTR *pstrOut)
  235. {
  236. HRESULT hr;
  237. CERTDBATTRIBUTE const *pcda;
  238. if (NULL == pstrOut)
  239. {
  240. hr = E_POINTER;
  241. _JumpError(hr, error, "NULL parm");
  242. }
  243. hr = _FindAttribute(&pcda);
  244. _JumpIfError(hr, error, "_FindAttribute");
  245. if (!ConvertWszToBstr(pstrOut, pcda->pwszName, -1))
  246. {
  247. hr = E_OUTOFMEMORY;
  248. _JumpError(hr, error, "ConvertWszToBstr");
  249. }
  250. error:
  251. return(_SetErrorInfo(hr, L"CEnumCERTVIEWATTRIBUTE::GetName"));
  252. }
  253. STDMETHODIMP
  254. CEnumCERTVIEWATTRIBUTE::GetValue(
  255. /* [out, retval] */ BSTR *pstrOut)
  256. {
  257. HRESULT hr;
  258. CERTDBATTRIBUTE const *pcda;
  259. if (NULL == pstrOut)
  260. {
  261. hr = E_POINTER;
  262. _JumpError(hr, error, "NULL parm");
  263. }
  264. hr = _FindAttribute(&pcda);
  265. _JumpIfError(hr, error, "_FindAttribute");
  266. if (L'\0' == *pcda->pwszValue)
  267. {
  268. hr = CERTSRV_E_PROPERTY_EMPTY;
  269. _JumpError(hr, error, "NULL value");
  270. }
  271. if (!ConvertWszToBstr(pstrOut, pcda->pwszValue, -1))
  272. {
  273. hr = E_OUTOFMEMORY;
  274. _JumpError(hr, error, "ConvertWszToBstr");
  275. }
  276. error:
  277. return(_SetErrorInfo(hr, L"CEnumCERTVIEWATTRIBUTE::GetValue"));
  278. }
  279. STDMETHODIMP
  280. CEnumCERTVIEWATTRIBUTE::Skip(
  281. /* [in] */ LONG celt)
  282. {
  283. HRESULT hr;
  284. LONG ieltnew = m_ielt + celt;
  285. if (-1 > ieltnew)
  286. {
  287. hr = E_INVALIDARG;
  288. _JumpError(hr, error, "Skip back to before start");
  289. }
  290. m_ielt = ieltnew;
  291. m_ieltCurrent += celt;
  292. m_fNoCurrentRecord = TRUE;
  293. hr = S_OK;
  294. error:
  295. return(_SetErrorInfo(hr, L"CEnumCERTVIEWATTRIBUTE::Skip"));
  296. }
  297. STDMETHODIMP
  298. CEnumCERTVIEWATTRIBUTE::Reset(VOID)
  299. {
  300. HRESULT hr;
  301. DWORD celt;
  302. CERTTRANSBLOB ctbAttributes;
  303. ctbAttributes.pb = NULL;
  304. m_fNoMore = FALSE;
  305. hr = ((CCertView *) m_pvw)->EnumAttributesOrExtensions(
  306. m_RowId,
  307. CDBENUM_ATTRIBUTES,
  308. NULL,
  309. CEXT_CHUNK,
  310. &celt,
  311. &ctbAttributes);
  312. if (S_FALSE == hr)
  313. {
  314. m_fNoMore = TRUE;
  315. }
  316. else
  317. {
  318. _JumpIfError(hr, error, "EnumAttributesOrExtensions");
  319. }
  320. hr = _SaveAttributes(celt, &ctbAttributes);
  321. _JumpIfError(hr, error, "_SaveAttributes");
  322. m_ielt = -1;
  323. m_ieltCurrent = -1;
  324. m_celtCurrent = celt;
  325. m_fNoCurrentRecord = TRUE;
  326. error:
  327. if (NULL != ctbAttributes.pb)
  328. {
  329. CoTaskMemFree(ctbAttributes.pb);
  330. }
  331. return(_SetErrorInfo(hr, L"CEnumCERTVIEWATTRIBUTE::Reset"));
  332. }
  333. STDMETHODIMP
  334. CEnumCERTVIEWATTRIBUTE::Clone(
  335. /* [out] */ IEnumCERTVIEWATTRIBUTE **ppenum)
  336. {
  337. HRESULT hr;
  338. IEnumCERTVIEWATTRIBUTE *penum = NULL;
  339. if (NULL == ppenum)
  340. {
  341. hr = E_POINTER;
  342. _JumpError(hr, error, "NULL parm");
  343. }
  344. *ppenum = NULL;
  345. penum = new CEnumCERTVIEWATTRIBUTE;
  346. if (NULL == penum)
  347. {
  348. hr = E_OUTOFMEMORY;
  349. _JumpError(hr, error, "new CEnumCERTVIEWATTRIBUTE");
  350. }
  351. hr = ((CEnumCERTVIEWATTRIBUTE *) penum)->Open(m_RowId, m_Flags, m_pvw);
  352. _JumpIfError(hr, error, "Open");
  353. if (-1 != m_ielt)
  354. {
  355. hr = penum->Skip(m_ielt);
  356. _JumpIfError(hr, error, "Skip");
  357. if (!m_fNoCurrentRecord)
  358. {
  359. LONG Index;
  360. hr = penum->Next(&Index);
  361. _JumpIfError(hr, error, "Next");
  362. CSASSERT(Index == m_ielt);
  363. }
  364. }
  365. *ppenum = penum;
  366. penum = NULL;
  367. hr = S_OK;
  368. error:
  369. if (NULL != penum)
  370. {
  371. penum->Release();
  372. }
  373. return(_SetErrorInfo(hr, L"CEnumCERTVIEWATTRIBUTE::Clone"));
  374. }
  375. HRESULT
  376. CEnumCERTVIEWATTRIBUTE::_SetErrorInfo(
  377. IN HRESULT hrError,
  378. IN WCHAR const *pwszDescription)
  379. {
  380. CSASSERT(FAILED(hrError) || S_OK == hrError || S_FALSE == hrError);
  381. if (FAILED(hrError))
  382. {
  383. HRESULT hr;
  384. hr = DispatchSetErrorInfo(
  385. hrError,
  386. pwszDescription,
  387. wszCLASS_CERTVIEW L".CEnumCERTVIEWATTRIBUTE",
  388. &IID_IEnumCERTVIEWATTRIBUTE);
  389. CSASSERT(hr == hrError);
  390. }
  391. return(hrError);
  392. }
  393. #if 1
  394. // IUnknown implementation
  395. STDMETHODIMP
  396. CEnumCERTVIEWATTRIBUTE::QueryInterface(
  397. const IID& iid,
  398. void **ppv)
  399. {
  400. HRESULT hr;
  401. if (NULL == ppv)
  402. {
  403. hr = E_POINTER;
  404. _JumpError(hr, error, "NULL parm");
  405. }
  406. if (iid == IID_IUnknown)
  407. {
  408. *ppv = static_cast<IEnumCERTVIEWATTRIBUTE *>(this);
  409. }
  410. else if (iid == IID_IDispatch)
  411. {
  412. *ppv = static_cast<IEnumCERTVIEWATTRIBUTE *>(this);
  413. }
  414. else if (iid == IID_IEnumCERTVIEWATTRIBUTE)
  415. {
  416. *ppv = static_cast<IEnumCERTVIEWATTRIBUTE *>(this);
  417. }
  418. else
  419. {
  420. *ppv = NULL;
  421. hr = E_NOINTERFACE;
  422. _JumpError(hr, error, "IID");
  423. }
  424. reinterpret_cast<IUnknown *>(*ppv)->AddRef();
  425. hr = S_OK;
  426. error:
  427. return(hr);
  428. }
  429. ULONG STDMETHODCALLTYPE
  430. CEnumCERTVIEWATTRIBUTE::AddRef()
  431. {
  432. return(InterlockedIncrement(&m_cRef));
  433. }
  434. ULONG STDMETHODCALLTYPE
  435. CEnumCERTVIEWATTRIBUTE::Release()
  436. {
  437. ULONG cRef = InterlockedDecrement(&m_cRef);
  438. if (0 == cRef)
  439. {
  440. delete this;
  441. }
  442. return(cRef);
  443. }
  444. #endif