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.

1077 lines
38 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997-2001.
  5. //
  6. // File: cmponent.cpp
  7. //
  8. // Contents: Implementation of CCertMgrComponent
  9. //
  10. //----------------------------------------------------------------------------
  11. #include "stdafx.h"
  12. #include <gpedit.h>
  13. #include "compdata.h" // CCertMgrComponentData
  14. #include "cmponent.h" // CCertMgrComponent
  15. #include "SaferLevel.h"
  16. #include "SaferEntry.h"
  17. #include "storeGPE.h"
  18. #include "SaferUtil.h"
  19. #include "PolicyKey.h"
  20. #ifdef _DEBUG
  21. #ifndef ALPHA
  22. #define new DEBUG_NEW
  23. #endif
  24. #undef THIS_FILE
  25. static char THIS_FILE[] = __FILE__;
  26. #endif
  27. HKEY g_hkeyLastSaferRegistryScope = 0;
  28. extern PCWSTR pcszNEWLINE;
  29. HRESULT CCertMgrComponent::AddSaferLevels(
  30. bool bIsComputer,
  31. PCWSTR pszServerName,
  32. HKEY hGroupPolicyKey)
  33. {
  34. _TRACE (1, L"Entering CCertMgrComponent::AddSaferLevels ()\n");
  35. HRESULT hr = S_OK;
  36. CWaitCursor cursor;
  37. CCertMgrComponentData& dataRef = QueryComponentDataRef ();
  38. if ( dataRef.m_pdwSaferLevels )
  39. {
  40. for (UINT nIndex = 0;
  41. NO_MORE_SAFER_LEVELS != dataRef.m_pdwSaferLevels[nIndex] && SUCCEEDED (hr);
  42. nIndex++)
  43. {
  44. CString szLevel;
  45. switch (dataRef.m_pdwSaferLevels[nIndex])
  46. {
  47. case SAFER_LEVELID_FULLYTRUSTED:
  48. case SAFER_LEVELID_CONSTRAINED:
  49. case SAFER_LEVELID_DISALLOWED:
  50. case SAFER_LEVELID_NORMALUSER:
  51. case SAFER_LEVELID_UNTRUSTED:
  52. szLevel = SaferGetLevelFriendlyName (dataRef.m_pdwSaferLevels[nIndex],
  53. hGroupPolicyKey, bIsComputer);
  54. hr = AddLevel (szLevel, dataRef.m_pdwSaferLevels[nIndex],
  55. bIsComputer,
  56. pszServerName);
  57. break;
  58. default:
  59. ASSERT (0);
  60. _TRACE (0, L"Unexpected safer level while enumerating levels: 0x%x\n",
  61. dataRef.m_pdwSaferLevels[nIndex]);
  62. break;
  63. }
  64. }
  65. }
  66. else
  67. hr = E_FAIL;
  68. _TRACE (-1, L"Leaving CCertMgrComponent::AddSaferLevels (): 0x%x\n", hr);
  69. return hr;
  70. }
  71. HRESULT CCertMgrComponent::AddLevel (
  72. const CString& szLevel,
  73. DWORD dwLevel,
  74. bool fIsMachine,
  75. PCWSTR pszServerName)
  76. {
  77. _TRACE (1, L"Entering CCertMgrComponent::AddLevel ()\n");
  78. HRESULT hr = S_OK;
  79. CCertMgrComponentData& dataRef = QueryComponentDataRef ();
  80. CCookie& rootCookie = dataRef.QueryBaseRootCookie ();
  81. RESULTDATAITEM rdItem;
  82. ::ZeroMemory (&rdItem, sizeof (rdItem));
  83. rdItem.mask = RDI_STR | RDI_PARAM | RDI_IMAGE;
  84. rdItem.nCol = 0;
  85. CSaferLevel* pNewLevel = new CSaferLevel (
  86. dwLevel,
  87. fIsMachine,
  88. pszServerName,
  89. szLevel,
  90. dataRef.m_pGPEInformation,
  91. fIsMachine ?
  92. dataRef.m_rsopObjectArrayComputer :
  93. dataRef.m_rsopObjectArrayUser);
  94. if ( pNewLevel )
  95. {
  96. if ( pNewLevel->IsDefault () )
  97. {
  98. rdItem.nImage = iIconDefaultSaferLevel;
  99. dataRef.m_dwDefaultSaferLevel = pNewLevel->GetLevel ();
  100. }
  101. else
  102. rdItem.nImage = iIconSaferLevel;
  103. rootCookie.m_listResultCookieBlocks.AddHead (pNewLevel);
  104. rdItem.str = MMC_TEXTCALLBACK ;
  105. rdItem.lParam = (LPARAM) pNewLevel;
  106. pNewLevel->m_resultDataID = m_pResultData;
  107. hr = m_pResultData->InsertItem (&rdItem);
  108. if ( FAILED (hr) )
  109. {
  110. _TRACE (0, L"IResultData::InsertItem () failed: 0x%x\n", hr);
  111. }
  112. }
  113. else
  114. {
  115. hr = E_OUTOFMEMORY;
  116. }
  117. _TRACE (-1, L"Leaving CCertMgrComponent::AddLevel () : 0x%x\n", hr);
  118. return hr;
  119. }
  120. HRESULT CCertMgrComponent::SaferEnumerateEntries (
  121. bool bIsComputer,
  122. CSaferEntries* pSaferEntries)
  123. {
  124. if ( !pSaferEntries )
  125. return E_POINTER;
  126. _TRACE (1, L"Entering CCertMgrComponent::SaferEnumerateEntries ()\n");
  127. HRESULT hr = S_OK;
  128. CCertMgrComponentData& dataRef = QueryComponentDataRef ();
  129. if ( dataRef.m_pGPEInformation )
  130. {
  131. CPolicyKey policyKey (dataRef.m_pGPEInformation,
  132. SAFER_HKLM_REGBASE,
  133. bIsComputer);
  134. hr = SetRegistryScope (policyKey.GetKey (), bIsComputer);
  135. if ( SUCCEEDED (hr) )
  136. {
  137. hr = SaferEnumerateNonCertEntries (policyKey.GetKey (),
  138. bIsComputer);
  139. hr = SaferEnumerateCertEntries (
  140. bIsComputer,
  141. pSaferEntries);
  142. }
  143. }
  144. else if ( dataRef.m_bIsRSOP )
  145. {
  146. hr = SaferEnumerateRSOPNonCertEntries (bIsComputer, pSaferEntries);
  147. hr = SaferEnumerateCertEntries (bIsComputer,
  148. pSaferEntries);
  149. }
  150. else
  151. hr = E_UNEXPECTED;
  152. _TRACE (-1, L"Leaving CCertMgrComponent::SaferEnumerateEntries () : 0x%x\n", hr);
  153. return hr;
  154. }
  155. HRESULT CCertMgrComponent::SaferEnumerateRSOPNonCertEntries (
  156. bool bIsComputer,
  157. CSaferEntries* pSaferEntries)
  158. {
  159. if ( !pSaferEntries )
  160. return E_POINTER;
  161. _TRACE (1, L"Entering CCertMgrComponent::SaferEnumerateRSOPNonCertEntries\n");
  162. HRESULT hr = S_OK;
  163. int nIndex = 0;
  164. CCertMgrComponentData& dataRef = QueryComponentDataRef ();
  165. CString szKeyStart (SAFER_HKLM_REGBASE);
  166. const CRSOPObjectArray* pObjectArray = bIsComputer ?
  167. dataRef.GetRSOPObjectArrayComputer () : dataRef.GetRSOPObjectArrayUser ();
  168. INT_PTR nUpperBound = pObjectArray->GetUpperBound ();
  169. szKeyStart += L"\\";
  170. szKeyStart += SAFER_CODEIDS_REGSUBKEY;
  171. size_t nKeyStartLen = wcslen (szKeyStart);
  172. // Skip the common text and get the level
  173. long dwLevel = 0;
  174. long dwPreviousLevel = 0;
  175. CString szLevel;
  176. CString szType; // hash, url, path
  177. SAFER_ENTRY_TYPE type = SAFER_ENTRY_TYPE_UNKNOWN; // hash, url, path
  178. SAFER_ENTRY_TYPE previousType = SAFER_ENTRY_TYPE_UNKNOWN;
  179. CString szGUID;
  180. GUID guid;
  181. ::ZeroMemory (&guid, sizeof (GUID));
  182. bool bCreateNew = false;
  183. PSAFER_IDENTIFICATION_HEADER pCaiCommon = 0;
  184. CString szPreviousKey;
  185. CString szKey;
  186. CRSOPObject* pCurrObject = 0;
  187. while ( nUpperBound >= nIndex )
  188. {
  189. if ( pCurrObject )
  190. szPreviousKey = pCurrObject->GetRegistryKey ();
  191. pCurrObject = pObjectArray->GetAt (nIndex);
  192. if ( pCurrObject )
  193. {
  194. szKey = pCurrObject->GetRegistryKey ();
  195. if ( !wcsncmp (szKey, szKeyStart, nKeyStartLen) )
  196. {
  197. szKey = szKey.Right ((int) (wcslen (szKey) - (nKeyStartLen + 1)));
  198. if ( !szKey.IsEmpty () )
  199. {
  200. // get level
  201. int nPos = szKey.Find (L'\\');
  202. szLevel = szKey.Left (nPos);
  203. dwPreviousLevel = dwLevel;
  204. dwLevel = wcstol(szLevel, 0, 10);
  205. szKey = szKey.Right ((int)(wcslen (szKey) - (nPos + 1)));
  206. // get type
  207. nPos = szKey.Find (L'\\');
  208. szType = szKey.Left (nPos);
  209. if ( SAFER_PATHS_REGSUBKEY == szType )
  210. type = SAFER_ENTRY_TYPE_PATH;
  211. else if ( SAFER_HASHMD5_REGSUBKEY == szType )
  212. type = SAFER_ENTRY_TYPE_HASH;
  213. else if ( SAFER_SOURCEURL_REGSUBKEY == szType )
  214. type = SAFER_ENTRY_TYPE_URLZONE;
  215. else
  216. {
  217. ASSERT (0);
  218. }
  219. if ( SAFER_ENTRY_TYPE_UNKNOWN == previousType )
  220. previousType = type;
  221. szKey = szKey.Right ((int) (wcslen (szKey) - (nPos + 1)));
  222. // get guid
  223. if ( szKey != szGUID )
  224. {
  225. szGUID = szKey;
  226. if ( !GuidFromString (&guid, szGUID) )
  227. continue;
  228. bCreateNew = true;
  229. }
  230. else
  231. bCreateNew = false;
  232. if ( bCreateNew && pCaiCommon )
  233. {
  234. // If we were working on an old one, create the
  235. // CSaferEntry with the available information and add
  236. // it to the result pane
  237. hr = SaferFinishEntryAndAdd (previousType, pCaiCommon,
  238. bIsComputer, dwPreviousLevel, pSaferEntries,
  239. szPreviousKey);
  240. if ( SUCCEEDED (hr) )
  241. {
  242. pCaiCommon = 0;
  243. }
  244. else if ( E_OUTOFMEMORY == hr )
  245. {
  246. ::LocalFree (pCaiCommon);
  247. pCaiCommon = 0;
  248. }
  249. previousType = type;
  250. }
  251. switch (type)
  252. {
  253. case SAFER_ENTRY_TYPE_PATH:
  254. if ( bCreateNew )
  255. {
  256. ASSERT (!pCaiCommon);
  257. pCaiCommon = (PSAFER_IDENTIFICATION_HEADER)
  258. ::LocalAlloc (LPTR, sizeof (SAFER_PATHNAME_IDENTIFICATION));
  259. if ( pCaiCommon )
  260. {
  261. ((SAFER_PATHNAME_IDENTIFICATION*)pCaiCommon)->header.cbStructSize =
  262. sizeof (SAFER_PATHNAME_IDENTIFICATION);
  263. memcpy (&((SAFER_PATHNAME_IDENTIFICATION*)pCaiCommon)->header.IdentificationGuid,
  264. &guid, sizeof (GUID));
  265. ((SAFER_PATHNAME_IDENTIFICATION*)pCaiCommon)->header.dwIdentificationType =
  266. SaferIdentityTypeImageName;
  267. }
  268. else
  269. hr = E_OUTOFMEMORY;
  270. }
  271. if ( SUCCEEDED (hr) && pCaiCommon )
  272. {
  273. if ( SAFER_IDS_DESCRIPTION_REGVALUE == pCurrObject->GetValueName () )
  274. {
  275. BSTR bstr = 0;
  276. if ( SUCCEEDED (pCurrObject->GetBSTR (&bstr)) )
  277. {
  278. wcsncpy (((SAFER_PATHNAME_IDENTIFICATION*)pCaiCommon)->Description,
  279. bstr,
  280. SAFER_MAX_DESCRIPTION_SIZE);
  281. SysFreeString (bstr);
  282. }
  283. }
  284. else if ( SAFER_IDS_ITEMDATA_REGVALUE == pCurrObject->GetValueName () )
  285. {
  286. ASSERT ( MAX_PATH * sizeof (WCHAR) >= pCurrObject->GetBlobLength ());
  287. ((SAFER_PATHNAME_IDENTIFICATION*)pCaiCommon)->ImageName =
  288. (PWCHAR) pCurrObject->GetBlob ();
  289. }
  290. else if ( SAFER_IDS_LASTMODIFIED_REGVALUE == pCurrObject->GetValueName () )
  291. {
  292. pCurrObject->GetFileTime (
  293. ((SAFER_PATHNAME_IDENTIFICATION*)pCaiCommon)->header.lastModified);
  294. }
  295. else if ( SAFER_IDS_SAFERFLAGS_REGVALUE == pCurrObject->GetValueName () )
  296. {
  297. ((SAFER_PATHNAME_IDENTIFICATION*)pCaiCommon)->dwSaferFlags =
  298. pCurrObject->GetDWORDValue ();
  299. }
  300. }
  301. break;
  302. case SAFER_ENTRY_TYPE_HASH:
  303. if ( bCreateNew )
  304. {
  305. ASSERT (!pCaiCommon);
  306. pCaiCommon = (PSAFER_IDENTIFICATION_HEADER)
  307. ::LocalAlloc (LPTR, sizeof (SAFER_HASH_IDENTIFICATION));
  308. if ( pCaiCommon )
  309. {
  310. ((SAFER_HASH_IDENTIFICATION*)pCaiCommon)->header.cbStructSize =
  311. sizeof (SAFER_HASH_IDENTIFICATION);
  312. memcpy (&((SAFER_HASH_IDENTIFICATION*)pCaiCommon)->header.IdentificationGuid,
  313. &guid, sizeof (GUID));
  314. ((SAFER_HASH_IDENTIFICATION*)pCaiCommon)->header.dwIdentificationType =
  315. SaferIdentityTypeImageHash;
  316. // NTRAID# 424997 SAFER: File hash not displayed on hash rule property sheets in RSOP mode.
  317. ((SAFER_HASH_IDENTIFICATION*)pCaiCommon)->HashSize = 16;
  318. }
  319. else
  320. hr = E_OUTOFMEMORY;
  321. }
  322. if ( SUCCEEDED (hr) && pCaiCommon && !pCurrObject->GetValueName ().IsEmpty () )
  323. {
  324. if ( SAFER_IDS_ITEMDATA_REGVALUE == pCurrObject->GetValueName () )
  325. {
  326. ASSERT (SAFER_MAX_HASH_SIZE >= pCurrObject->GetBlobLength ());
  327. memcpy (&((SAFER_HASH_IDENTIFICATION*)pCaiCommon)->ImageHash,
  328. pCurrObject->GetBlob (),
  329. pCurrObject->GetBlobLength ());
  330. }
  331. else if ( SAFER_IDS_LASTMODIFIED_REGVALUE == pCurrObject->GetValueName () )
  332. {
  333. pCurrObject->GetFileTime (
  334. ((SAFER_HASH_IDENTIFICATION*)pCaiCommon)->header.lastModified);
  335. }
  336. else if ( SAFER_IDS_SAFERFLAGS_REGVALUE == pCurrObject->GetValueName () )
  337. {
  338. ((SAFER_HASH_IDENTIFICATION*)pCaiCommon)->dwSaferFlags =
  339. pCurrObject->GetDWORDValue ();
  340. }
  341. else if ( SAFER_IDS_FRIENDLYNAME_REGVALUE == pCurrObject->GetValueName () )
  342. {
  343. BSTR bstr = 0;
  344. if ( SUCCEEDED (pCurrObject->GetBSTR (&bstr)) )
  345. {
  346. wcsncpy (((SAFER_HASH_IDENTIFICATION*)pCaiCommon)->FriendlyName,
  347. bstr,
  348. SAFER_MAX_FRIENDLYNAME_SIZE);
  349. SysFreeString (bstr);
  350. }
  351. }
  352. else if ( SAFER_IDS_HASHALG_REGVALUE == pCurrObject->GetValueName () )
  353. {
  354. ASSERT (sizeof (ALG_ID) == pCurrObject->GetBlobLength ()); memcpy (&((SAFER_HASH_IDENTIFICATION*)pCaiCommon)->HashAlgorithm,
  355. pCurrObject->GetBlob (),
  356. pCurrObject->GetBlobLength ());
  357. }
  358. else if ( SAFER_IDS_ITEMSIZE_REGVALUE == pCurrObject->GetValueName () )
  359. {
  360. ASSERT (sizeof (LARGE_INTEGER) == pCurrObject->GetBlobLength ());
  361. memcpy (&((SAFER_HASH_IDENTIFICATION*)pCaiCommon)->ImageSize,
  362. pCurrObject->GetBlob (),
  363. pCurrObject->GetBlobLength ());
  364. }
  365. else if ( SAFER_IDS_DESCRIPTION_REGVALUE == pCurrObject->GetValueName () )
  366. {
  367. BSTR bstr = 0;
  368. if ( SUCCEEDED (pCurrObject->GetBSTR (&bstr)) )
  369. {
  370. wcsncpy (((SAFER_HASH_IDENTIFICATION*)pCaiCommon)->Description,
  371. bstr,
  372. SAFER_MAX_DESCRIPTION_SIZE);
  373. SysFreeString (bstr);
  374. }
  375. }
  376. else if ( SAFER_VALUE_NAME_HASH_SIZE == pCurrObject->GetValueName () )
  377. {
  378. ASSERT (sizeof (LARGE_INTEGER) == pCurrObject->GetBlobLength ());
  379. memcpy (&((SAFER_HASH_IDENTIFICATION*)pCaiCommon)->HashSize,
  380. pCurrObject->GetBlob (),
  381. pCurrObject->GetBlobLength ());
  382. }
  383. }
  384. break;
  385. case SAFER_ENTRY_TYPE_URLZONE:
  386. if ( bCreateNew )
  387. {
  388. ASSERT (!pCaiCommon);
  389. pCaiCommon = (PSAFER_IDENTIFICATION_HEADER)
  390. ::LocalAlloc (LPTR, sizeof (SAFER_URLZONE_IDENTIFICATION));
  391. if ( pCaiCommon )
  392. {
  393. ((SAFER_URLZONE_IDENTIFICATION*)pCaiCommon)->header.cbStructSize =
  394. sizeof (SAFER_URLZONE_IDENTIFICATION);
  395. memcpy (&((SAFER_URLZONE_IDENTIFICATION*)pCaiCommon)->header.IdentificationGuid,
  396. &guid, sizeof (GUID));
  397. ((SAFER_URLZONE_IDENTIFICATION*)pCaiCommon)->header.dwIdentificationType =
  398. SaferIdentityTypeUrlZone;
  399. }
  400. else
  401. hr = E_OUTOFMEMORY;
  402. }
  403. if ( SUCCEEDED (hr) && pCaiCommon )
  404. {
  405. if ( SAFER_IDS_ITEMDATA_REGVALUE == pCurrObject->GetValueName () )
  406. {
  407. memcpy (&((SAFER_URLZONE_IDENTIFICATION*)pCaiCommon)->UrlZoneId,
  408. pCurrObject->GetBlob (),
  409. pCurrObject->GetBlobLength ());
  410. #if DBG
  411. SAFER_URLZONE_IDENTIFICATION* pCaiUrlZone =
  412. (SAFER_URLZONE_IDENTIFICATION*) pCaiCommon;
  413. ASSERT (URLZONE_LOCAL_MACHINE == pCaiUrlZone->UrlZoneId ||
  414. URLZONE_INTRANET == pCaiUrlZone->UrlZoneId ||
  415. URLZONE_TRUSTED == pCaiUrlZone->UrlZoneId ||
  416. URLZONE_INTERNET == pCaiUrlZone->UrlZoneId ||
  417. URLZONE_UNTRUSTED == pCaiUrlZone->UrlZoneId);
  418. #endif DBG
  419. }
  420. else if ( SAFER_IDS_LASTMODIFIED_REGVALUE == pCurrObject->GetValueName () )
  421. {
  422. pCurrObject->GetFileTime (
  423. ((SAFER_URLZONE_IDENTIFICATION*)pCaiCommon)->header.lastModified);
  424. }
  425. else if ( SAFER_IDS_SAFERFLAGS_REGVALUE == pCurrObject->GetValueName () )
  426. {
  427. ((SAFER_URLZONE_IDENTIFICATION*)pCaiCommon)->dwSaferFlags =
  428. pCurrObject->GetDWORDValue ();
  429. }
  430. }
  431. break;
  432. default:
  433. ASSERT (0);
  434. break;
  435. }
  436. }
  437. }
  438. }
  439. else
  440. break;
  441. nIndex++;
  442. }
  443. if ( pCaiCommon )
  444. {
  445. // If we were working on an old one, create the
  446. // CSaferEntry with the available information and add
  447. // it to the result pane
  448. hr = SaferFinishEntryAndAdd (previousType, pCaiCommon,
  449. bIsComputer, dwLevel, pSaferEntries,
  450. szPreviousKey);
  451. if ( SUCCEEDED (hr) )
  452. {
  453. pCaiCommon = 0;
  454. }
  455. else if ( E_OUTOFMEMORY == hr )
  456. {
  457. ::LocalFree (pCaiCommon);
  458. pCaiCommon = 0;
  459. }
  460. }
  461. _TRACE (-1, L"Leaving CCertMgrComponent::SaferEnumerateRSOPNonCertEntries: 0x%x\n", hr);
  462. return hr;
  463. }
  464. HRESULT CCertMgrComponent::SaferFinishEntryAndAdd (SAFER_ENTRY_TYPE previousType,
  465. PSAFER_IDENTIFICATION_HEADER pCaiCommon,
  466. bool bIsComputer,
  467. long dwLevel,
  468. CSaferEntries* pSaferEntries,
  469. const CString& szPreviousKey)
  470. {
  471. HRESULT hr = S_OK;
  472. CString szSubjectName;
  473. switch (previousType)
  474. {
  475. case SAFER_ENTRY_TYPE_PATH:
  476. szSubjectName = ((SAFER_PATHNAME_IDENTIFICATION*)pCaiCommon)->ImageName;
  477. break;
  478. case SAFER_ENTRY_TYPE_HASH:
  479. szSubjectName = ((PSAFER_HASH_IDENTIFICATION) (pCaiCommon))->FriendlyName;
  480. szSubjectName.Replace (pcszNEWLINE, L" ");
  481. break;
  482. case SAFER_ENTRY_TYPE_URLZONE:
  483. szSubjectName = GetURLZoneFriendlyName (
  484. ((SAFER_URLZONE_IDENTIFICATION*) pCaiCommon)->UrlZoneId);
  485. break;
  486. default:
  487. ASSERT (0);
  488. break;
  489. }
  490. ASSERT (pCaiCommon);
  491. if ( pCaiCommon )
  492. {
  493. hr = InsertNewSaferEntry (
  494. previousType,
  495. bIsComputer,
  496. szSubjectName,
  497. pCaiCommon,
  498. dwLevel,
  499. pSaferEntries,
  500. QueryComponentDataRef ().m_pGPEInformation,
  501. 0,
  502. szPreviousKey);
  503. }
  504. return hr;
  505. }
  506. HRESULT CCertMgrComponent::InsertNewSaferEntry (
  507. SAFER_ENTRY_TYPE type,
  508. bool bIsComputer,
  509. PCWSTR pwcszObjectName,
  510. PSAFER_IDENTIFICATION_HEADER pCaiCommon,
  511. DWORD dwLevel,
  512. CSaferEntries* pSaferEntries,
  513. IGPEInformation* pGPEInformation,
  514. CCertificate* pCert,
  515. PCWSTR pszRSOPRegistryKey)
  516. {
  517. _TRACE (1, L"Entering CCertMgrComponent::InsertNewSaferEntry (%s)\n", pwcszObjectName);
  518. HRESULT hr = S_OK;
  519. switch (type)
  520. {
  521. case SAFER_ENTRY_TYPE_PATH:
  522. ASSERT (pCaiCommon &&
  523. SaferIdentityTypeImageName == pCaiCommon->dwIdentificationType);
  524. break;
  525. case SAFER_ENTRY_TYPE_HASH:
  526. ASSERT (pCaiCommon &&
  527. SaferIdentityTypeImageHash == pCaiCommon->dwIdentificationType);
  528. break;
  529. case SAFER_ENTRY_TYPE_URLZONE:
  530. ASSERT (pCaiCommon &&
  531. SaferIdentityTypeUrlZone == pCaiCommon->dwIdentificationType);
  532. break;
  533. case SAFER_ENTRY_TYPE_CERT:
  534. ASSERT (pCert);
  535. break;
  536. default:
  537. ASSERT (0);
  538. break;
  539. }
  540. CSaferEntry* pNewEntry = new CSaferEntry (
  541. type,
  542. bIsComputer,
  543. L"",
  544. pwcszObjectName,
  545. pCaiCommon,
  546. dwLevel,
  547. pGPEInformation,
  548. pCert,
  549. pSaferEntries,
  550. bIsComputer ? QueryComponentDataRef ().m_rsopObjectArrayComputer :
  551. QueryComponentDataRef ().m_rsopObjectArrayUser,
  552. pszRSOPRegistryKey);
  553. if ( pNewEntry )
  554. {
  555. RESULTDATAITEM rdItem;
  556. ::ZeroMemory (&rdItem, sizeof (rdItem));
  557. rdItem.mask = RDI_STR | RDI_IMAGE | RDI_PARAM;
  558. switch (type)
  559. {
  560. case SAFER_ENTRY_TYPE_HASH:
  561. rdItem.nImage = iIconSaferHashEntry;
  562. break;
  563. case SAFER_ENTRY_TYPE_PATH:
  564. rdItem.nImage = iIconSaferNameEntry;
  565. break;
  566. case SAFER_ENTRY_TYPE_CERT:
  567. rdItem.nImage = iIconSaferCertEntry;
  568. break;
  569. case SAFER_ENTRY_TYPE_URLZONE:
  570. rdItem.nImage = iIconSaferURLEntry;
  571. break;
  572. default:
  573. ASSERT (0);
  574. break;
  575. }
  576. rdItem.nCol = 0;
  577. rdItem.str = MMC_TEXTCALLBACK;
  578. QueryComponentDataRef ().QueryBaseRootCookie ().m_listResultCookieBlocks.AddHead (pNewEntry);
  579. rdItem.lParam = (LPARAM) pNewEntry;
  580. pNewEntry->m_resultDataID = m_pResultData;
  581. hr = m_pResultData->InsertItem (&rdItem);
  582. if ( FAILED (hr) )
  583. {
  584. _TRACE (0, L"IResultData::InsertItem () failed: 0x%x\n", hr);
  585. }
  586. }
  587. else
  588. hr = E_OUTOFMEMORY;
  589. _TRACE (-1, L"Leaving CCertMgrComponent::InsertNewSaferEntry (%s): 0x%x\n", pwcszObjectName, hr);
  590. return hr;
  591. }
  592. HRESULT CCertMgrComponent::SaferEnumerateNonCertEntries (
  593. HKEY hGroupPolicyKey,
  594. bool bIsComputer)
  595. {
  596. _TRACE (1, L"Entering CCertMgrComponent::SaferEnumerateNonCertEntries ()\n");
  597. ASSERT (0 != g_hkeyLastSaferRegistryScope);
  598. HRESULT hr = S_OK;
  599. DWORD* pdwLevels = 0;
  600. DWORD cbBuffer = 0;
  601. SetRegistryScope (hGroupPolicyKey, bIsComputer);
  602. BOOL bRVal = SaferGetPolicyInformation (
  603. SAFER_SCOPEID_REGISTRY,
  604. SaferPolicyLevelList,
  605. cbBuffer,
  606. pdwLevels,
  607. &cbBuffer,
  608. 0);
  609. if ( !bRVal && GetLastError () == ERROR_INSUFFICIENT_BUFFER )
  610. {
  611. DWORD nLevels = cbBuffer/sizeof (DWORD);
  612. pdwLevels = new DWORD[nLevels];
  613. if ( pdwLevels )
  614. {
  615. bRVal = SaferGetPolicyInformation (
  616. SAFER_SCOPEID_REGISTRY,
  617. SaferPolicyLevelList,
  618. cbBuffer,
  619. pdwLevels,
  620. &cbBuffer,
  621. 0);
  622. ASSERT (bRVal);
  623. if ( bRVal )
  624. {
  625. for (DWORD dwIndex = 0; dwIndex < nLevels; dwIndex++)
  626. {
  627. hr = SaferEnumerateEntriesAtLevel (
  628. bIsComputer,
  629. hGroupPolicyKey,
  630. pdwLevels[dwIndex]);
  631. }
  632. }
  633. else
  634. {
  635. DWORD dwErr = GetLastError ();
  636. hr = HRESULT_FROM_WIN32 (dwErr);
  637. _TRACE (0, L"SaferGetPolicyInformation (SAFER_SCOPEID_REGISTRY, SaferPolicyLevelList) failed: %d\n",
  638. dwErr);
  639. }
  640. delete [] pdwLevels;
  641. }
  642. else
  643. hr = E_OUTOFMEMORY;
  644. }
  645. else if ( !bRVal )
  646. {
  647. ASSERT (0);
  648. DWORD dwErr = GetLastError ();
  649. hr = HRESULT_FROM_WIN32 (dwErr);
  650. _TRACE (0, L"SaferGetPolicyInformation (SAFER_SCOPEID_REGISTRY, SaferPolicyLevelList) failed: %d\n",
  651. dwErr);
  652. }
  653. _TRACE (-1, L"Leaving CCertMgrComponent::SaferEnumerateNonCertEntries (): 0x%x\n", hr);
  654. return hr;
  655. }
  656. HRESULT CCertMgrComponent::SaferEnumerateCertEntries (
  657. bool bIsComputer,
  658. CSaferEntries* pSaferEntries)
  659. {
  660. if ( !pSaferEntries )
  661. return E_POINTER;
  662. _TRACE (1, L"Entering CCertMgrComponent::SaferEnumerateCertEntries ()\n");
  663. HRESULT hr = S_OK;
  664. CCertStore* pTrustedPublisherStore = 0;
  665. hr = pSaferEntries->GetTrustedPublishersStore (&pTrustedPublisherStore);
  666. if ( pTrustedPublisherStore )
  667. {
  668. hr = EnumSaferCertificates (
  669. bIsComputer,
  670. *pTrustedPublisherStore,
  671. pSaferEntries);
  672. if ( SUCCEEDED (hr) )
  673. {
  674. m_currResultNodeType = bIsComputer ?
  675. CERTMGR_SAFER_COMPUTER_ENTRY : CERTMGR_SAFER_USER_ENTRY;
  676. m_pResultData->Sort (m_nSelectedSaferEntryColumn, 0,
  677. (long) m_currResultNodeType);
  678. }
  679. pTrustedPublisherStore->Release ();
  680. }
  681. else
  682. hr = E_OUTOFMEMORY;
  683. CCertStore* pDisallowedStore = 0;
  684. hr = pSaferEntries->GetDisallowedStore (&pDisallowedStore);
  685. if ( pDisallowedStore )
  686. {
  687. hr = EnumSaferCertificates (
  688. bIsComputer,
  689. *pDisallowedStore,
  690. pSaferEntries);
  691. if ( SUCCEEDED (hr) )
  692. {
  693. m_currResultNodeType = bIsComputer ?
  694. CERTMGR_SAFER_COMPUTER_ENTRY : CERTMGR_SAFER_USER_ENTRY;
  695. m_pResultData->Sort (m_nSelectedSaferEntryColumn, 0,
  696. (long) m_currResultNodeType);
  697. }
  698. pDisallowedStore->Release ();
  699. }
  700. else
  701. hr = E_OUTOFMEMORY;
  702. _TRACE (-1, L"Leaving CCertMgrComponent::SaferEnumerateCertEntries (): 0x%x\n", hr);
  703. return hr;
  704. }
  705. HRESULT CCertMgrComponent::EnumSaferCertificates (
  706. bool bIsComputer,
  707. CCertStore& rCertStore,
  708. CSaferEntries* pSaferEntries)
  709. {
  710. if ( !pSaferEntries )
  711. return E_POINTER;
  712. _TRACE (1, L"Entering CCertMgrComponent::EnumCertificates\n");
  713. CWaitCursor cursor;
  714. PCCERT_CONTEXT pCertContext = 0;
  715. HRESULT hr = 0;
  716. CCertificate* pCert = 0;
  717. DWORD dwLevelID = SAFER_TRUSTED_PUBLISHER_STORE == rCertStore.GetStoreType () ?
  718. SAFER_LEVELID_FULLYTRUSTED : SAFER_LEVELID_DISALLOWED;
  719. // Iterate through the list of certificates in the system store,
  720. // allocate new certificates with the CERT_CONTEXT returned,
  721. // and store them in the certificate list.
  722. while ( 1 )
  723. {
  724. pCertContext = rCertStore.EnumCertificates (pCertContext);
  725. if ( !pCertContext )
  726. break;
  727. pCert =
  728. new CCertificate (pCertContext, &rCertStore);
  729. if ( pCert )
  730. {
  731. hr = InsertNewSaferEntry (SAFER_ENTRY_TYPE_CERT,
  732. bIsComputer,
  733. pCert->GetSubjectName (),
  734. 0,
  735. dwLevelID,
  736. pSaferEntries,
  737. QueryComponentDataRef ().m_pGPEInformation,
  738. pCert);
  739. if ( FAILED (hr) )
  740. break;
  741. pCert->Release ();
  742. }
  743. else
  744. {
  745. hr = E_OUTOFMEMORY;
  746. break;
  747. }
  748. }
  749. rCertStore.Close ();
  750. _TRACE (-1, L"Leaving CCertMgrComponent::EnumCertificates: 0x%x\n", hr);
  751. return hr;
  752. }
  753. HRESULT CCertMgrComponent::SaferEnumerateEntriesAtLevel (
  754. bool bIsComputer,
  755. HKEY hGroupPolicyKey,
  756. DWORD dwLevel)
  757. {
  758. _TRACE (1, L"Entering CCertMgrComponent::SaferEnumerateEntriesAtLevel (%d)\n", dwLevel);
  759. SetRegistryScope (hGroupPolicyKey, bIsComputer);
  760. HRESULT hr = S_OK;
  761. SAFER_LEVEL_HANDLE hLevel = 0;
  762. BOOL bRVal = SaferCreateLevel (SAFER_SCOPEID_REGISTRY,
  763. dwLevel,
  764. SAFER_LEVEL_OPEN,
  765. &hLevel,
  766. hGroupPolicyKey);
  767. ASSERT (bRVal);
  768. if ( bRVal )
  769. {
  770. DWORD dwBufferSize = 0;
  771. bRVal = SaferGetLevelInformation(hLevel,
  772. SaferObjectAllIdentificationGuids,
  773. 0,
  774. dwBufferSize,
  775. &dwBufferSize);
  776. if ( !bRVal && ERROR_INSUFFICIENT_BUFFER == GetLastError () )
  777. {
  778. DWORD nGuids = dwBufferSize/sizeof (GUID);
  779. GUID* pGuids = new GUID[nGuids];
  780. if ( pGuids )
  781. {
  782. bRVal = SaferGetLevelInformation(hLevel,
  783. SaferObjectAllIdentificationGuids,
  784. pGuids,
  785. dwBufferSize,
  786. &dwBufferSize);
  787. ASSERT (bRVal);
  788. if ( bRVal )
  789. {
  790. for (DWORD dwIndex = 0; dwIndex < nGuids; dwIndex++)
  791. {
  792. hr = SaferGetSingleEntry (bIsComputer, hLevel,
  793. pGuids[dwIndex], dwLevel);
  794. }
  795. }
  796. else
  797. {
  798. DWORD dwErr = GetLastError ();
  799. hr = HRESULT_FROM_WIN32 (dwErr);
  800. _TRACE (0, L"SaferGetLevelInformation (SaferObjectAllIdentificationGuids) failed: %d\n",
  801. dwErr);
  802. }
  803. delete [] pGuids;
  804. }
  805. else
  806. hr = E_OUTOFMEMORY;
  807. }
  808. else if ( !bRVal )
  809. {
  810. DWORD dwErr = GetLastError ();
  811. ASSERT (ERROR_NOT_FOUND == dwErr);
  812. hr = HRESULT_FROM_WIN32 (dwErr);
  813. _TRACE (0, L"SaferGetLevelInformation (SaferObjectAllIdentificationGuids) failed: %d\n",
  814. dwErr);
  815. }
  816. VERIFY (SaferCloseLevel (hLevel));
  817. }
  818. else
  819. {
  820. DWORD dwErr = GetLastError ();
  821. hr = HRESULT_FROM_WIN32 (dwErr);
  822. _TRACE (0, L"SaferCreateLevel (SAFER_SCOPEID_REGISTRY, 0x%x, SAFER_LEVEL_OPEN) failed: %d\n",
  823. dwLevel, dwErr);
  824. }
  825. _TRACE (-1, L"Leaving CCertMgrComponent::SaferEnumerateEntriesAtLevel () : 0x%x\n", hr);
  826. return hr;
  827. }
  828. HRESULT CCertMgrComponent::SaferGetSingleEntry(
  829. bool bIsComputer,
  830. SAFER_LEVEL_HANDLE hLevel,
  831. GUID &rEntryGuid,
  832. DWORD dwLevelID)
  833. {
  834. _TRACE (1, L"Entering CCertMgrComponent::SaferGetSingleEntry ()\n");
  835. ASSERT (0 != g_hkeyLastSaferRegistryScope);
  836. HRESULT hr = S_OK;
  837. DWORD dwBufferSize = sizeof (SAFER_IDENTIFICATION_HEADER);
  838. SAFER_IDENTIFICATION_HEADER caiCommon;
  839. ::ZeroMemory (&caiCommon, sizeof (SAFER_IDENTIFICATION_HEADER));
  840. caiCommon.cbStructSize = dwBufferSize;
  841. memcpy (&caiCommon.IdentificationGuid, &rEntryGuid, sizeof (GUID));
  842. BOOL bRVal = SaferGetLevelInformation(hLevel,
  843. SaferObjectSingleIdentification,
  844. &caiCommon,
  845. dwBufferSize,
  846. &dwBufferSize);
  847. if ( !bRVal && ERROR_INSUFFICIENT_BUFFER == GetLastError () )
  848. {
  849. PBYTE pBytes = (PBYTE) LocalAlloc (LPTR, dwBufferSize);
  850. if ( pBytes )
  851. {
  852. SAFER_ENTRY_TYPE saferEntryType = SAFER_ENTRY_TYPE_UNKNOWN;
  853. PSAFER_IDENTIFICATION_HEADER pCommon = (PSAFER_IDENTIFICATION_HEADER) pBytes;
  854. pCommon->cbStructSize = dwBufferSize;
  855. memcpy (&pCommon->IdentificationGuid, &rEntryGuid, sizeof (GUID));
  856. bRVal = SaferGetLevelInformation(hLevel,
  857. SaferObjectSingleIdentification,
  858. pBytes,
  859. dwBufferSize,
  860. &dwBufferSize);
  861. ASSERT (bRVal);
  862. if ( bRVal )
  863. {
  864. CString szObjectName;
  865. switch (pCommon->dwIdentificationType)
  866. {
  867. case SaferIdentityTypeImageName:
  868. szObjectName = ((PSAFER_PATHNAME_IDENTIFICATION) (pCommon))->ImageName;
  869. saferEntryType = SAFER_ENTRY_TYPE_PATH;
  870. break;
  871. case SaferIdentityTypeImageHash:
  872. szObjectName = ((PSAFER_HASH_IDENTIFICATION) (pCommon))->FriendlyName;
  873. // replace new-line characters with spaces
  874. szObjectName.Replace (pcszNEWLINE, L" ");
  875. saferEntryType = SAFER_ENTRY_TYPE_HASH;
  876. break;
  877. case SaferIdentityTypeUrlZone:
  878. szObjectName = GetURLZoneFriendlyName (
  879. ((PSAFER_URLZONE_IDENTIFICATION) (pCommon))->UrlZoneId);
  880. saferEntryType = SAFER_ENTRY_TYPE_URLZONE;
  881. break;
  882. default:
  883. ASSERT (0);
  884. break;
  885. }
  886. hr = InsertNewSaferEntry (
  887. saferEntryType,
  888. bIsComputer,
  889. szObjectName,
  890. pCommon,
  891. dwLevelID,
  892. 0,
  893. QueryComponentDataRef ().m_pGPEInformation,
  894. 0);
  895. if ( E_OUTOFMEMORY == hr )
  896. ::LocalFree (pBytes);
  897. }
  898. else
  899. {
  900. DWORD dwErr = GetLastError ();
  901. hr = HRESULT_FROM_WIN32 (dwErr);
  902. _TRACE (0, L"SaferGetLevelInformation (SaferObjectSingleIdentification) failed: %d\n",
  903. dwErr);
  904. }
  905. // pBytes is freed in ~CSaferEntry
  906. }
  907. else
  908. hr = E_OUTOFMEMORY;
  909. }
  910. else if ( !bRVal )
  911. {
  912. ASSERT (0);
  913. DWORD dwErr = GetLastError ();
  914. hr = HRESULT_FROM_WIN32 (dwErr);
  915. _TRACE (0, L"SaferGetLevelInformation (SaferObjectSingleIdentification) failed: %d\n",
  916. dwErr);
  917. }
  918. _TRACE (-1, L"Leaving CCertMgrComponent::SaferGetSingleEntry (): 0x%x\n", hr);
  919. return hr;
  920. }
  921. HRESULT CCertMgrComponent::DeleteSaferEntryFromResultPane (
  922. CSaferEntry * pSaferEntry,
  923. LPDATAOBJECT pDataObject,
  924. bool bDoCommit)
  925. {
  926. _TRACE (1, L"Entering CCertMgrComponent::DeleteSaferEntryFromResultPane\n");
  927. HRESULT hr = S_OK;
  928. hr = pSaferEntry->Delete (bDoCommit);
  929. if ( SUCCEEDED (hr) )
  930. {
  931. HRESULTITEM itemID = 0;
  932. hr = m_pResultData->FindItemByLParam ( (LPARAM) pSaferEntry, &itemID);
  933. if ( SUCCEEDED (hr) )
  934. {
  935. hr = m_pResultData->DeleteItem (itemID, 0);
  936. }
  937. // If we can't succeed in removing this one item, then update the whole panel.
  938. if ( !SUCCEEDED (hr) )
  939. {
  940. hr = m_pConsole->UpdateAllViews (pDataObject, 0, 0);
  941. }
  942. }
  943. else
  944. {
  945. CString text;
  946. CString caption;
  947. VERIFY (caption.LoadString (IDS_SAFER_WINDOWS_NODE_NAME));
  948. text.FormatMessage (IDS_CANT_DELETE_SAFER_ENTRY, GetSystemMessage (hr));
  949. int iRetVal = 0;
  950. VERIFY (SUCCEEDED (m_pConsole->MessageBox (text, caption,
  951. MB_OK, &iRetVal)));
  952. }
  953. _TRACE (-1, L"Leaving CCertMgrComponent::DeleteSaferEntryFromResultPane: 0x%x\n", hr);
  954. return hr;
  955. }
  956. HRESULT CCertMgrComponent::OnNotifyCanPasteOutOfProc (LPBOOL pbCanHandle)
  957. {
  958. if ( !pbCanHandle )
  959. return E_POINTER;
  960. CCertMgrComponentData& dataRef = QueryComponentDataRef ();
  961. CLSID clsID;
  962. if ( SUCCEEDED (dataRef.GetClassID (&clsID)) )
  963. {
  964. if ( CLSID_SaferWindowsExtension == clsID )
  965. *pbCanHandle = TRUE;
  966. }
  967. return S_OK; // snapins should redefine this
  968. }