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.

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