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.

467 lines
14 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 "certsrv.h"
  10. #include "setupids.h"
  11. #include "misc.h"
  12. #ifdef _DEBUG
  13. #undef THIS_FILE
  14. static char THIS_FILE[] = __FILE__;
  15. #endif
  16. /////////////////////////////////////////////////////////////////////////////
  17. // Event handlers for IFrame::Notify
  18. HRESULT CSnapin::OnAddImages(MMC_COOKIE cookie, LPARAM arg, LPARAM param)
  19. {
  20. if (arg == 0)
  21. return E_INVALIDARG;
  22. ASSERT(m_pImageResult != NULL);
  23. ASSERT((IImageList*)arg == m_pImageResult);
  24. CBitmap bmpResultStrip16x16, bmpResultStrip32x32;
  25. if (NULL == bmpResultStrip16x16.LoadBitmap(IDB_16x16))
  26. return S_FALSE;
  27. if (NULL == bmpResultStrip32x32.LoadBitmap(IDB_32x32))
  28. return S_FALSE;
  29. // Set the images
  30. m_pImageResult->ImageListSetStrip(reinterpret_cast<LONG_PTR*>(static_cast<HBITMAP>(bmpResultStrip16x16)),
  31. reinterpret_cast<LONG_PTR*>(static_cast<HBITMAP>(bmpResultStrip32x32)),
  32. 0, RGB(255, 0, 255));
  33. return S_OK;
  34. }
  35. HRESULT CSnapin::OnShow(MMC_COOKIE cookie, LPARAM arg, LPARAM param)
  36. {
  37. HRESULT hr;
  38. CFolder* pFolder = dynamic_cast<CComponentDataImpl*>(m_pComponentData)->FindObject(cookie);
  39. // Note - arg is TRUE when it is time to enumerate
  40. if (arg == TRUE)
  41. {
  42. m_pCurrentlySelectedScopeFolder = pFolder;
  43. // if list view on display
  44. if (m_CustomViewID == VIEW_DEFAULT_LV)
  45. {
  46. // Show the headers for this nodetype
  47. hr = InitializeHeaders(cookie);
  48. // virtual list support
  49. if (m_bVirtualView)
  50. m_pResult->SetItemCount(1, 0);
  51. }
  52. }
  53. else
  54. {
  55. // if list view is on display
  56. if (m_CustomViewID == VIEW_DEFAULT_LV)
  57. {
  58. // Free data associated with the result pane items, because
  59. // your node is no longer being displayed.
  60. }
  61. // Note: The console will remove the items from the result pane
  62. }
  63. return S_OK;
  64. }
  65. HRESULT CSnapin::GetRowColContents(CFolder* pFolder, LONG idxRow, LPCWSTR szColHead, PBYTE* ppbData, DWORD* pcbData, BOOL fStringFmt /*FALSE*/)
  66. {
  67. HRESULT hr;
  68. LONG idxCol;
  69. IEnumCERTVIEWROW* pRow = NULL;
  70. IEnumCERTVIEWCOLUMN* pCol = NULL;
  71. ICertView* pView = NULL;
  72. #if DBG
  73. DWORD dwVerifySize;
  74. #endif
  75. CComponentDataImpl* pCompData = dynamic_cast<CComponentDataImpl*>(m_pComponentData);
  76. ASSERT(pFolder != NULL);
  77. // pollute the row enumerator we've got
  78. hr = m_RowEnum.GetRowEnum(pFolder->GetCA(), &pRow);
  79. _JumpIfError(hr, Ret, "GetRowEnum");
  80. hr = m_RowEnum.SetRowEnumPos(idxRow);
  81. _JumpIfError(hr, Ret, "SetRowEnumPos");
  82. // now we have the correct row; siphon data out of the correct column
  83. hr = m_RowEnum.GetView(pFolder->GetCA(), &pView);
  84. _JumpIfError(hr, Ret, "GetView");
  85. // get column number in schema
  86. idxCol = pCompData->FindColIdx(szColHead);
  87. // retrieve and alloc
  88. *pcbData = 0;
  89. hr = GetCellContents(&m_RowEnum, pFolder->GetCA(), idxRow, idxCol, NULL, pcbData, fStringFmt);
  90. _JumpIfError(hr, Ret, "GetCellContents");
  91. *ppbData = new BYTE[*pcbData];
  92. _JumpIfOutOfMemory(hr, Ret, *ppbData);
  93. #if DBG
  94. dwVerifySize = *pcbData;
  95. #endif
  96. hr = GetCellContents(&m_RowEnum, pFolder->GetCA(), idxRow, idxCol, *ppbData, pcbData, fStringFmt);
  97. _JumpIfError(hr, Ret, "GetCellContents");
  98. #if DBG
  99. ASSERT(dwVerifySize == *pcbData);
  100. #endif
  101. Ret:
  102. // catch column inclusion errors, handle in a smart way
  103. if (hr == HRESULT_FROM_WIN32(ERROR_INVALID_INDEX) ||
  104. hr == HRESULT_FROM_WIN32(ERROR_CONTINUE))
  105. {
  106. CString cstrFormat;
  107. cstrFormat.LoadString(IDS_COLUMN_INCLUSION_ERROR);
  108. LPCWSTR pszLocalizedCol = NULL;
  109. hr = myGetColumnDisplayName(szColHead, &pszLocalizedCol);
  110. ASSERT ((hr == S_OK) && (NULL != pszLocalizedCol));
  111. CString cstrTmp;
  112. cstrTmp.Format(cstrFormat, pszLocalizedCol);
  113. cstrFormat.Empty();
  114. cstrFormat.LoadString(IDS_MSG_TITLE);
  115. m_pConsole->MessageBoxW(cstrTmp, cstrFormat, MB_OK, NULL);
  116. hr = ERROR_CANCELLED; // this is a cancellation so bail silently, we've shown error
  117. }
  118. return hr;
  119. }
  120. HRESULT
  121. GetBinaryColumnFormat(
  122. IN WCHAR const *pwszColumnName,
  123. OUT LONG *pFormat)
  124. {
  125. LONG Format = CV_OUT_BINARY;
  126. if (0 == lstrcmpi(
  127. wszPROPREQUESTDOT wszPROPREQUESTRAWREQUEST,
  128. pwszColumnName))
  129. {
  130. Format = CV_OUT_BASE64REQUESTHEADER;
  131. }
  132. else
  133. if (0 == lstrcmpi(wszPROPRAWCERTIFICATE, pwszColumnName) ||
  134. 0 == lstrcmpi(
  135. wszPROPREQUESTDOT wszPROPREQUESTRAWOLDCERTIFICATE,
  136. pwszColumnName))
  137. {
  138. Format = CV_OUT_BASE64HEADER;
  139. }
  140. else
  141. {
  142. Format = CV_OUT_HEX;
  143. }
  144. *pFormat = Format;
  145. return(S_OK);
  146. }
  147. // Build the display name for templates: "friendly name (internal name)"
  148. HRESULT CSnapin::BuildTemplateDisplayName(
  149. LPCWSTR pcwszFriendlyName,
  150. LPCWSTR pcwszTemplateName,
  151. VARIANT& varDisplayName)
  152. {
  153. CString strName;
  154. strName = pcwszFriendlyName;
  155. strName += L" (";
  156. strName += pcwszTemplateName;
  157. strName += L")";
  158. V_VT(&varDisplayName) = VT_BSTR;
  159. V_BSTR(&varDisplayName) = ::SysAllocString(strName);
  160. if(!V_BSTR(&varDisplayName))
  161. return E_OUTOFMEMORY;
  162. return S_OK;
  163. }
  164. // copies cell to pbData, truncates if necessary. Real size passed out in pcbData
  165. HRESULT CSnapin::GetCellContents(CertViewRowEnum* pCRowEnum, CertSvrCA* pCA, LONG idxRow, LONG idxCol, PBYTE pbData, DWORD* pcbData, BOOL fStringFmt)
  166. {
  167. HRESULT hr;
  168. CComponentDataImpl* pCompData = dynamic_cast<CComponentDataImpl*>(m_pComponentData);
  169. if (NULL == pCompData)
  170. return E_POINTER;
  171. VARIANT varCert;
  172. VariantInit(&varCert);
  173. LONG idxViewCol;
  174. IEnumCERTVIEWROW* pRow;
  175. IEnumCERTVIEWCOLUMN* pCol = NULL;
  176. hr = pCRowEnum->GetRowEnum(pCA, &pRow);
  177. if (hr != S_OK)
  178. return hr;
  179. do
  180. {
  181. hr = pCRowEnum->SetRowEnumPos(idxRow);
  182. if (hr != S_OK)
  183. break;
  184. LONG lType;
  185. LPCWSTR szColHead; // no free needed
  186. hr = pCRowEnum->GetColumnCacheInfo(idxCol, (int*)&idxViewCol);
  187. if (hr != S_OK)
  188. break;
  189. // get col enumerator object
  190. hr = pRow->EnumCertViewColumn(&pCol);
  191. if (hr != S_OK)
  192. break;
  193. hr = pCol->Skip(idxViewCol);
  194. if (hr != S_OK)
  195. break;
  196. // get value there
  197. hr = pCol->Next(&idxViewCol);
  198. if (hr != S_OK)
  199. break;
  200. if (fStringFmt)
  201. {
  202. LONG lFormat = CV_OUT_BINARY;
  203. VARIANT varTmp;
  204. VariantInit(&varTmp);
  205. hr = pCompData->GetDBSchemaEntry(idxCol, &szColHead, &lType, NULL);
  206. if (hr != S_OK)
  207. break;
  208. // New: translate _some_ cols to readable strings
  209. if (PROPTYPE_BINARY == lType)
  210. {
  211. hr = GetBinaryColumnFormat(szColHead, &lFormat);
  212. if (hr != S_OK)
  213. break;
  214. }
  215. hr = pCol->GetValue(lFormat, &varTmp);
  216. if (hr != S_OK)
  217. break;
  218. if (0 == lstrcmpi(wszPROPREQUESTDOT wszPROPREQUESTRAWARCHIVEDKEY, szColHead))
  219. {
  220. if (VT_EMPTY != varTmp.vt)
  221. {
  222. varCert.bstrVal = ::SysAllocString(g_cResources.m_szYes);
  223. varCert.vt = VT_BSTR;
  224. }
  225. }
  226. else if (0 == lstrcmpi(wszPROPCERTTEMPLATE, szColHead))
  227. {
  228. LPCWSTR pcwszOID = NULL;
  229. if (VT_BSTR == varTmp.vt)
  230. {
  231. // Map OID or template name to friendly name
  232. // Try name first
  233. HCERTTYPE hCertType;
  234. LPWSTR *pwszCertTypeName;
  235. hr = CAFindCertTypeByName(
  236. varTmp.bstrVal,
  237. NULL,
  238. CT_ENUM_MACHINE_TYPES |
  239. CT_ENUM_USER_TYPES |
  240. 0,
  241. &hCertType);
  242. if(S_OK==hr)
  243. {
  244. hr = CAGetCertTypeProperty(
  245. hCertType,
  246. CERTTYPE_PROP_FRIENDLY_NAME,
  247. &pwszCertTypeName);
  248. if(S_OK==hr)
  249. {
  250. BuildTemplateDisplayName(
  251. pwszCertTypeName[0],
  252. varTmp.bstrVal,
  253. varCert);
  254. CAFreeCertTypeProperty(
  255. hCertType,
  256. pwszCertTypeName);
  257. }
  258. CACloseCertType(hCertType);
  259. }
  260. // Failed to find by name, try OID
  261. if(S_OK!=hr)
  262. {
  263. pcwszOID = myGetOIDName(varTmp.bstrVal);
  264. varCert.vt = VT_BSTR;
  265. if (EmptyString(pcwszOID))
  266. {
  267. varCert.bstrVal = ::SysAllocString(varTmp.bstrVal);
  268. }
  269. else
  270. {
  271. BuildTemplateDisplayName(
  272. pcwszOID,
  273. varTmp.bstrVal,
  274. varCert);
  275. }
  276. }
  277. }
  278. }
  279. else if (0 == lstrcmpi(wszPROPREQUESTDOT wszPROPREQUESTSTATUSCODE, szColHead))
  280. {
  281. if (VT_I4 == varTmp.vt) // don't be empty
  282. {
  283. WCHAR const *pwszError = myGetErrorMessageText(varTmp.lVal, TRUE);
  284. varCert.bstrVal = ::SysAllocString(pwszError);
  285. varCert.vt = VT_BSTR;
  286. }
  287. }
  288. else if (0 == lstrcmpi(wszPROPREQUESTDOT wszPROPREQUESTREVOKEDREASON, szColHead))
  289. {
  290. if (VT_I4 == varTmp.vt) // don't be empty
  291. {
  292. // Request.Disposition
  293. ASSERT(VT_I4 == varTmp.vt); // we'd better be looking at a dword
  294. switch(varTmp.lVal)
  295. {
  296. case CRL_REASON_KEY_COMPROMISE:
  297. varCert.bstrVal = ::SysAllocString(g_cResources.m_szRevokeReason_KeyCompromise);
  298. break;
  299. case CRL_REASON_CA_COMPROMISE:
  300. varCert.bstrVal = ::SysAllocString(g_cResources.m_szRevokeReason_CaCompromise);
  301. break;
  302. case CRL_REASON_AFFILIATION_CHANGED:
  303. varCert.bstrVal = ::SysAllocString(g_cResources.m_szRevokeReason_Affiliation);
  304. break;
  305. case CRL_REASON_SUPERSEDED:
  306. varCert.bstrVal = ::SysAllocString(g_cResources.m_szRevokeReason_Superseded);
  307. break;
  308. case CRL_REASON_CESSATION_OF_OPERATION:
  309. varCert.bstrVal = ::SysAllocString(g_cResources.m_szRevokeReason_Cessatation);
  310. break;
  311. case CRL_REASON_CERTIFICATE_HOLD:
  312. varCert.bstrVal = ::SysAllocString(g_cResources.m_szRevokeReason_CertHold);
  313. break;
  314. case CRL_REASON_UNSPECIFIED:
  315. varCert.bstrVal = ::SysAllocString(g_cResources.m_szRevokeReason_Unspecified);
  316. break;
  317. case CRL_REASON_REMOVE_FROM_CRL:
  318. varCert.bstrVal = ::SysAllocString(g_cResources.m_szRevokeReason_RemoveFromCRL);
  319. break;
  320. default:
  321. {
  322. // sprint this into a buffer for display
  323. CString cstrSprintVal;
  324. cstrSprintVal.Format(L"%i", varTmp.lVal);
  325. varCert.bstrVal = cstrSprintVal.AllocSysString();
  326. break;
  327. }
  328. }
  329. if (varCert.bstrVal == NULL)
  330. {
  331. hr = E_OUTOFMEMORY;
  332. break;
  333. }
  334. varCert.vt = VT_BSTR;
  335. }
  336. }
  337. if (varCert.vt != VT_BSTR) // if this hasn't been converted yet
  338. {
  339. // default: conversion to string
  340. // returns localized string time (even for date!)
  341. VERIFY( MakeDisplayStrFromDBVariant(&varTmp, &varCert) ); // variant type change failed!?
  342. InplaceStripControlChars(varCert.bstrVal);
  343. }
  344. VariantClear(&varTmp);
  345. }
  346. else
  347. {
  348. hr = pCol->GetValue(CV_OUT_BINARY, &varCert);
  349. if (hr != S_OK)
  350. break;
  351. if (VT_EMPTY == varCert.vt)
  352. {
  353. hr = CERTSRV_E_PROPERTY_EMPTY;
  354. break;
  355. }
  356. }
  357. // finally, copy this value out to pb
  358. // copy, truncate if necessary
  359. DWORD cbTruncate = *pcbData;
  360. if (varCert.vt == VT_BSTR)
  361. {
  362. *pcbData = SysStringByteLen(varCert.bstrVal) + ((fStringFmt)? sizeof(WCHAR):0);
  363. CopyMemory(pbData, varCert.bstrVal, min(cbTruncate, *pcbData));
  364. }
  365. else if (varCert.vt == VT_I4)
  366. {
  367. *pcbData = sizeof(LONG);
  368. if (pbData != NULL)
  369. *(DWORD*)pbData = varCert.lVal;
  370. }
  371. else
  372. {
  373. hr = E_INVALIDARG;
  374. break;
  375. }
  376. }while(0);
  377. VariantClear(&varCert);
  378. if (pCol)
  379. pCol->Release();
  380. return hr;
  381. }