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.

739 lines
21 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 2000-2001.
  5. //
  6. // File: SaferUtil.cpp
  7. //
  8. // Contents: Utility methods for Software Restriction Policies extension
  9. //
  10. //----------------------------------------------------------------------------
  11. #include "stdafx.h"
  12. #include <gpedit.h>
  13. #include <wintrust.h>
  14. #include <crypto\wintrustp.h>
  15. #include <softpub.h>
  16. #include "SaferUtil.h"
  17. #include "SaferEntry.h"
  18. #include <winsaferp.h>
  19. #ifdef _DEBUG
  20. #define new DEBUG_NEW
  21. #undef THIS_FILE
  22. static char THIS_FILE[] = __FILE__;
  23. #endif
  24. extern HKEY g_hkeyLastSaferRegistryScope;
  25. bool g_bIsComputer = false;
  26. extern GUID g_guidExtension;
  27. extern GUID g_guidRegExt;
  28. extern GUID g_guidSnapin;
  29. void InitializeSecurityLevelComboBox (
  30. CComboBox& comboBox,
  31. bool bLimit,
  32. DWORD dwLevelID,
  33. HKEY hGroupPolicyKey,
  34. DWORD* pdwSaferLevels,
  35. bool bIsComputer)
  36. {
  37. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  38. if ( !hGroupPolicyKey ) // is RSOP
  39. {
  40. CString szText = SaferGetLevelFriendlyName (dwLevelID,
  41. hGroupPolicyKey, bIsComputer);
  42. int nItem = comboBox.AddString (szText);
  43. ASSERT (nItem >= 0);
  44. if ( nItem >= 0 )
  45. {
  46. VERIFY (CB_ERR != comboBox.SetItemData (nItem, dwLevelID));
  47. VERIFY (CB_ERR != comboBox.SetCurSel (nItem));
  48. }
  49. return;
  50. }
  51. if ( pdwSaferLevels )
  52. {
  53. for (UINT nIndex = 0;
  54. NO_MORE_SAFER_LEVELS != pdwSaferLevels[nIndex];
  55. nIndex++)
  56. {
  57. CString szText;
  58. int nItem = 0;
  59. switch (pdwSaferLevels[nIndex])
  60. {
  61. case SAFER_LEVELID_FULLYTRUSTED:
  62. szText = SaferGetLevelFriendlyName (pdwSaferLevels[nIndex],
  63. hGroupPolicyKey, bIsComputer);
  64. nItem = comboBox.AddString (szText);
  65. ASSERT (nItem >= 0);
  66. if ( nItem >= 0 )
  67. {
  68. VERIFY (CB_ERR != comboBox.SetItemData (nItem, pdwSaferLevels[nIndex]));
  69. if ( pdwSaferLevels[nIndex] == dwLevelID || AUTHZ_UNKNOWN_LEVEL == dwLevelID)
  70. VERIFY (CB_ERR != comboBox.SetCurSel (nItem));
  71. }
  72. break;
  73. case SAFER_LEVELID_CONSTRAINED:
  74. if ( !bLimit )
  75. {
  76. szText = SaferGetLevelFriendlyName (pdwSaferLevels[nIndex],
  77. hGroupPolicyKey, bIsComputer);
  78. nItem = comboBox.AddString (szText);
  79. ASSERT (nItem >= 0);
  80. if ( nItem >= 0 )
  81. {
  82. VERIFY (CB_ERR != comboBox.SetItemData (nItem, pdwSaferLevels[nIndex]));
  83. if ( pdwSaferLevels[nIndex] == dwLevelID )
  84. VERIFY (CB_ERR != comboBox.SetCurSel (nItem));
  85. }
  86. }
  87. break;
  88. case SAFER_LEVELID_DISALLOWED:
  89. szText = SaferGetLevelFriendlyName (pdwSaferLevels[nIndex],
  90. hGroupPolicyKey, bIsComputer);
  91. nItem = comboBox.AddString (szText);
  92. ASSERT (nItem >= 0);
  93. if ( nItem >= 0 )
  94. {
  95. VERIFY (CB_ERR != comboBox.SetItemData (nItem, pdwSaferLevels[nIndex]));
  96. if ( pdwSaferLevels[nIndex] == dwLevelID )
  97. VERIFY (CB_ERR != comboBox.SetCurSel (nItem));
  98. }
  99. break;
  100. case SAFER_LEVELID_NORMALUSER:
  101. case SAFER_LEVELID_UNTRUSTED:
  102. if ( !bLimit )
  103. {
  104. if ( hGroupPolicyKey )
  105. {
  106. szText = SaferGetLevelFriendlyName (pdwSaferLevels[nIndex],
  107. hGroupPolicyKey, bIsComputer);
  108. nItem = comboBox.AddString (szText);
  109. ASSERT (nItem >= 0);
  110. if ( nItem >= 0 )
  111. {
  112. VERIFY (CB_ERR != comboBox.SetItemData (nItem, pdwSaferLevels[nIndex]));
  113. if ( pdwSaferLevels[nIndex] == dwLevelID )
  114. VERIFY (CB_ERR != comboBox.SetCurSel (nItem));
  115. }
  116. }
  117. }
  118. break;
  119. default:
  120. ASSERT (0);
  121. break;
  122. }
  123. }
  124. }
  125. }
  126. class CLevelPair {
  127. public:
  128. CLevelPair () :
  129. m_dwLevelID ((DWORD) -1)
  130. {
  131. }
  132. virtual ~CLevelPair () {}
  133. DWORD m_dwLevelID;
  134. CString m_szLevelName;
  135. };
  136. CString SaferGetLevelFriendlyName (DWORD dwLevelID, HKEY hGroupPolicyKey, const bool bIsComputer)
  137. {
  138. CString szLevelName;
  139. SAFER_LEVEL_HANDLE hLevel = 0;
  140. BOOL bRVal = FALSE;
  141. const int NUM_LEVEL_PAIRS = 10;
  142. static CLevelPair levelPairs[NUM_LEVEL_PAIRS];
  143. for (int nLevelIndex = 0; nLevelIndex < NUM_LEVEL_PAIRS; nLevelIndex++)
  144. {
  145. if ( -1 == levelPairs[nLevelIndex].m_dwLevelID )
  146. break;
  147. else if ( dwLevelID == levelPairs[nLevelIndex].m_dwLevelID )
  148. {
  149. return levelPairs[nLevelIndex].m_szLevelName;
  150. }
  151. }
  152. if ( hGroupPolicyKey )
  153. {
  154. if ( !g_hkeyLastSaferRegistryScope )
  155. SetRegistryScope (hGroupPolicyKey, bIsComputer);
  156. bRVal = SaferCreateLevel (SAFER_SCOPEID_REGISTRY,
  157. dwLevelID,
  158. SAFER_LEVEL_OPEN,
  159. &hLevel,
  160. hGroupPolicyKey);
  161. }
  162. else
  163. {
  164. bRVal = SaferCreateLevel (SAFER_SCOPEID_MACHINE,
  165. dwLevelID,
  166. SAFER_LEVEL_OPEN,
  167. &hLevel,
  168. 0);
  169. }
  170. if ( bRVal )
  171. {
  172. DWORD dwBufferSize = 0;
  173. DWORD dwErr = 0;
  174. bRVal = SaferGetLevelInformation(hLevel,
  175. SaferObjectFriendlyName,
  176. 0,
  177. dwBufferSize,
  178. &dwBufferSize);
  179. if ( !bRVal && ERROR_INSUFFICIENT_BUFFER == GetLastError () )
  180. {
  181. PWSTR pszLevelName = (PWSTR) LocalAlloc (LPTR, dwBufferSize);
  182. if ( pszLevelName )
  183. {
  184. bRVal = SaferGetLevelInformation(hLevel,
  185. SaferObjectFriendlyName,
  186. pszLevelName,
  187. dwBufferSize,
  188. &dwBufferSize);
  189. ASSERT (bRVal);
  190. if ( bRVal )
  191. {
  192. szLevelName = pszLevelName;
  193. }
  194. else
  195. {
  196. dwErr = GetLastError ();
  197. _TRACE (0, L"SaferGetLevelInformation(SaferObjectFriendlyName) failed: %d\n",
  198. dwErr);
  199. }
  200. LocalFree (pszLevelName);
  201. }
  202. }
  203. else if ( !bRVal )
  204. {
  205. dwErr = GetLastError ();
  206. _TRACE (0, L"SaferGetLevelInformation(SaferObjectFriendlyName) failed: %d\n",
  207. dwErr);
  208. }
  209. VERIFY (SaferCloseLevel (hLevel));
  210. }
  211. else
  212. {
  213. DWORD dwErr = GetLastError ();
  214. _TRACE (0, L"SaferCloseLevel (SAFER_SCOPEID_REGISTRY, 0x%x, SAFER_LEVEL_OPEN) failed: %d\n",
  215. dwLevelID, dwErr);
  216. }
  217. if ( nLevelIndex < NUM_LEVEL_PAIRS && !szLevelName.IsEmpty () )
  218. {
  219. levelPairs[nLevelIndex].m_dwLevelID = dwLevelID;
  220. levelPairs[nLevelIndex].m_szLevelName = szLevelName;
  221. }
  222. return szLevelName;
  223. }
  224. CString SaferGetLevelDescription (DWORD dwLevelID, HKEY hGroupPolicyKey, const bool bIsComputer)
  225. {
  226. CString szDescription;
  227. SAFER_LEVEL_HANDLE hLevel = 0;
  228. BOOL bRVal = FALSE;
  229. if ( hGroupPolicyKey )
  230. {
  231. if ( !g_hkeyLastSaferRegistryScope )
  232. SetRegistryScope (hGroupPolicyKey, bIsComputer);
  233. bRVal = SaferCreateLevel (SAFER_SCOPEID_REGISTRY,
  234. dwLevelID,
  235. SAFER_LEVEL_OPEN,
  236. &hLevel,
  237. hGroupPolicyKey);
  238. }
  239. else
  240. {
  241. bRVal = SaferCreateLevel (SAFER_SCOPEID_MACHINE,
  242. dwLevelID,
  243. SAFER_LEVEL_OPEN,
  244. &hLevel,
  245. 0);
  246. }
  247. ASSERT (bRVal);
  248. if ( bRVal )
  249. {
  250. DWORD dwBufferSize = 0;
  251. DWORD dwErr = 0;
  252. bRVal = SaferGetLevelInformation(hLevel,
  253. SaferObjectDescription,
  254. 0,
  255. dwBufferSize,
  256. &dwBufferSize);
  257. if ( !bRVal && ERROR_INSUFFICIENT_BUFFER == GetLastError () )
  258. {
  259. PWSTR pszDescription = (PWSTR) LocalAlloc (LPTR, dwBufferSize);
  260. if ( pszDescription )
  261. {
  262. bRVal = SaferGetLevelInformation(hLevel,
  263. SaferObjectDescription,
  264. pszDescription,
  265. dwBufferSize,
  266. &dwBufferSize);
  267. ASSERT (bRVal);
  268. if ( bRVal )
  269. {
  270. szDescription = pszDescription;
  271. }
  272. else
  273. {
  274. dwErr = GetLastError ();
  275. _TRACE (0, L"SaferGetLevelInformation(SaferObjectFriendlyName) failed: %d\n",
  276. dwErr);
  277. }
  278. LocalFree (pszDescription);
  279. }
  280. }
  281. else if ( !bRVal )
  282. {
  283. dwErr = GetLastError ();
  284. _TRACE (0, L"SaferGetLevelInformation(SaferObjectFriendlyName) failed: %d\n",
  285. dwErr);
  286. }
  287. if ( ERROR_NOT_FOUND == dwErr || szDescription.IsEmpty () )
  288. {
  289. VERIFY (szDescription.LoadString (IDS_NOT_AVAILABLE));
  290. }
  291. VERIFY (SaferCloseLevel (hLevel));
  292. }
  293. else
  294. {
  295. DWORD dwErr = GetLastError ();
  296. _TRACE (0, L"SaferCloseLevel (SAFER_SCOPEID_REGISTRY, 0x%x, SAFER_LEVEL_OPEN) failed: %d\n",
  297. dwLevelID, dwErr);
  298. }
  299. return szDescription;
  300. }
  301. HRESULT SaferGetLevelID (SAFER_LEVEL_HANDLE hLevel, DWORD& dwLevelID)
  302. {
  303. ASSERT (0 != g_hkeyLastSaferRegistryScope);
  304. DWORD dwBufferSize = sizeof (DWORD);
  305. HRESULT hr = S_OK;
  306. BOOL bRVal = SaferGetLevelInformation(hLevel,
  307. SaferObjectLevelId,
  308. &dwLevelID,
  309. dwBufferSize,
  310. &dwBufferSize);
  311. ASSERT (bRVal);
  312. if ( !bRVal )
  313. {
  314. DWORD dwErr = GetLastError ();
  315. hr = HRESULT_FROM_WIN32 (dwErr);
  316. _TRACE (0, L"SaferGetLevelInformation(SaferObjectLevelId) failed: %d\n",
  317. dwErr);
  318. }
  319. return hr;
  320. }
  321. CSaferEntries::CSaferEntries(
  322. bool bIsMachine,
  323. PCWSTR pszMachineName,
  324. PCWSTR pszObjectName,
  325. IGPEInformation* pGPEInformation,
  326. IRSOPInformation* pRSOPInformation,
  327. CRSOPObjectArray& rsopObjectArray,
  328. LPCONSOLE pConsole)
  329. : CCertMgrCookie (bIsMachine ? CERTMGR_SAFER_COMPUTER_ENTRIES : CERTMGR_SAFER_USER_ENTRIES,
  330. pszMachineName, pszObjectName),
  331. m_pTrustedPublishersStore (0),
  332. m_pDisallowedStore (0)
  333. {
  334. if ( pGPEInformation )
  335. {
  336. m_pTrustedPublishersStore = new CCertStoreSafer (
  337. CERT_SYSTEM_STORE_RELOCATE_FLAG,
  338. L"",
  339. SAFER_TRUSTED_PUBLISHER_STORE_FRIENDLY_NAME,
  340. SAFER_TRUSTED_PUBLISHER_STORE_NAME,
  341. L"",
  342. pGPEInformation,
  343. bIsMachine ? NODEID_Machine : NODEID_User,
  344. pConsole);
  345. m_pDisallowedStore = new CCertStoreSafer (
  346. CERT_SYSTEM_STORE_RELOCATE_FLAG,
  347. L"",
  348. SAFER_DISALLOWED_STORE_FRIENDLY_NAME,
  349. SAFER_DISALLOWED_STORE_NAME,
  350. L"",
  351. pGPEInformation,
  352. bIsMachine ? NODEID_Machine : NODEID_User,
  353. pConsole);
  354. }
  355. else if ( pRSOPInformation )
  356. {
  357. m_pTrustedPublishersStore = new CCertStoreRSOP (
  358. CERT_SYSTEM_STORE_RELOCATE_FLAG,
  359. L"",
  360. SAFER_TRUSTED_PUBLISHER_STORE_FRIENDLY_NAME,
  361. SAFER_TRUSTED_PUBLISHER_STORE_NAME,
  362. L"",
  363. rsopObjectArray,
  364. bIsMachine ? NODEID_Machine : NODEID_User,
  365. pConsole);
  366. m_pDisallowedStore = new CCertStoreRSOP (
  367. CERT_SYSTEM_STORE_RELOCATE_FLAG,
  368. L"",
  369. SAFER_DISALLOWED_STORE_FRIENDLY_NAME,
  370. SAFER_DISALLOWED_STORE_NAME,
  371. L"",
  372. rsopObjectArray,
  373. bIsMachine ? NODEID_Machine : NODEID_User,
  374. pConsole);
  375. }
  376. }
  377. CSaferEntries::~CSaferEntries ()
  378. {
  379. if ( m_pTrustedPublishersStore )
  380. m_pTrustedPublishersStore->Release ();
  381. if ( m_pDisallowedStore )
  382. m_pDisallowedStore->Release ();
  383. }
  384. HRESULT CSaferEntries::GetTrustedPublishersStore(CCertStore **ppStore)
  385. {
  386. if ( !ppStore )
  387. return E_POINTER;
  388. if ( m_pTrustedPublishersStore )
  389. {
  390. m_pTrustedPublishersStore->AddRef ();
  391. *ppStore = m_pTrustedPublishersStore;
  392. }
  393. else
  394. return E_FAIL;
  395. return S_OK;
  396. }
  397. HRESULT CSaferEntries::GetDisallowedStore(CCertStore **ppStore)
  398. {
  399. if ( !ppStore )
  400. return E_POINTER;
  401. if ( m_pDisallowedStore )
  402. {
  403. m_pDisallowedStore->AddRef ();
  404. *ppStore = m_pDisallowedStore;
  405. }
  406. else
  407. return E_FAIL;
  408. return S_OK;
  409. }
  410. HRESULT SetRegistryScope (HKEY hKey, bool bIsComputer)
  411. {
  412. HRESULT hr = S_OK;
  413. if ( g_hkeyLastSaferRegistryScope != hKey || g_bIsComputer != bIsComputer )
  414. {
  415. BOOL bRVal = SaferiChangeRegistryScope (hKey, REG_OPTION_NON_VOLATILE);
  416. ASSERT (bRVal);
  417. if ( bRVal )
  418. {
  419. g_hkeyLastSaferRegistryScope = hKey;
  420. g_bIsComputer = bIsComputer;
  421. }
  422. else
  423. {
  424. DWORD dwErr = GetLastError ();
  425. hr = HRESULT_FROM_WIN32 (dwErr);
  426. _TRACE (0, L"SaferiChangeRegistryScope (%s) failed: %d\n",
  427. hKey ? L"hKey" : L"0", dwErr);
  428. }
  429. }
  430. return hr;
  431. }
  432. ///////////////////////////////////////////////////////////////////////////////
  433. // Returns S_OK if the file has a valid signed hash
  434. HRESULT GetSignedFileHash(
  435. IN LPCWSTR pwszFilename,
  436. OUT BYTE rgbFileHash[SAFER_MAX_HASH_SIZE],
  437. OUT DWORD *pcbFileHash,
  438. OUT ALG_ID *pHashAlgid
  439. )
  440. {
  441. HRESULT hr = S_OK;
  442. if ( !pwszFilename || !rgbFileHash || !pcbFileHash || !pHashAlgid )
  443. return E_POINTER;
  444. _TRACE (1, L"Entering GetSignedFileHash (%s)\n", pwszFilename);
  445. // Returns S_OK and the hash if the file was signed and contains a valid
  446. // hash
  447. *pcbFileHash = SAFER_MAX_HASH_SIZE;
  448. hr = WTHelperGetFileHash(
  449. pwszFilename,
  450. 0,
  451. NULL,
  452. rgbFileHash,
  453. pcbFileHash,
  454. pHashAlgid);
  455. if ( FAILED (hr) )
  456. {
  457. _TRACE (0, L"WTHelperGetFileHash (%s) failed: 0x%x\n", pwszFilename, hr);
  458. }
  459. _TRACE (-1, L"Leaving GetSignedFileHash (%s): 0x%x\n", pwszFilename, hr);
  460. return hr;
  461. }
  462. HRESULT ComputeMD5Hash(IN HANDLE hFile, BYTE hashResult[SAFER_MAX_HASH_SIZE], DWORD& dwHashSize)
  463. /*++
  464. Routine Description:
  465. Computes the MD5 hash of a given file's contents and prints the
  466. resulting hash value to the screen.
  467. Arguments:
  468. szFilename - filename to compute hash of.
  469. Return Value:
  470. Returns 0 on success, or a non-zero exit code on failure.
  471. --*/
  472. {
  473. _TRACE (1, L"Entering ComputeMD5Hash ()\n");
  474. HRESULT hr = S_OK;
  475. //
  476. // Open the specified file and map it into memory.
  477. //
  478. HANDLE hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
  479. if ( hMapping )
  480. {
  481. DWORD dwDataLen = GetFileSize (hFile, NULL);
  482. if ( -1 != dwDataLen )
  483. {
  484. LPBYTE pbData = (LPBYTE) ::MapViewOfFile (hMapping, FILE_MAP_READ, 0, 0, dwDataLen);
  485. if ( pbData )
  486. {
  487. //
  488. // Generate the hash value of the specified file.
  489. //
  490. HCRYPTPROV hProvider = 0;
  491. if ( CryptAcquireContext(&hProvider, NULL, NULL,
  492. PROV_RSA_SIG, CRYPT_VERIFYCONTEXT) ||
  493. CryptAcquireContext(&hProvider, NULL, NULL,
  494. PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) )
  495. {
  496. HCRYPTHASH hHash = 0;
  497. if ( CryptCreateHash(hProvider, CALG_MD5, 0, 0, &hHash) )
  498. {
  499. if ( CryptHashData (hHash, pbData, dwDataLen, 0) )
  500. {
  501. dwHashSize = SAFER_MAX_HASH_SIZE;
  502. if (!CryptGetHashParam(hHash, HP_HASHVAL, hashResult, &dwHashSize, 0))
  503. {
  504. dwHashSize = 0;
  505. DWORD dwErr = GetLastError ();
  506. hr = HRESULT_FROM_WIN32 (dwErr);
  507. _TRACE (0, L"CryptHashData () failed: 0x%x\n", hr);
  508. }
  509. }
  510. else
  511. {
  512. DWORD dwErr = GetLastError ();
  513. hr = HRESULT_FROM_WIN32 (dwErr);
  514. _TRACE (0, L"CryptHashData () failed: 0x%x\n", hr);
  515. }
  516. CryptDestroyHash(hHash);
  517. }
  518. else
  519. {
  520. DWORD dwErr = GetLastError ();
  521. hr = HRESULT_FROM_WIN32 (dwErr);
  522. _TRACE (0, L"CryptCreateHash () failed: 0x%x\n", hr);
  523. }
  524. CryptReleaseContext(hProvider, 0);
  525. }
  526. else
  527. {
  528. DWORD dwErr = GetLastError ();
  529. hr = HRESULT_FROM_WIN32 (dwErr);
  530. _TRACE (0, L"CryptAcquireContext () failed: 0x%x\n", hr);
  531. }
  532. ::UnmapViewOfFile(pbData);
  533. }
  534. else
  535. {
  536. DWORD dwErr = GetLastError ();
  537. _TRACE (0, L"MapViewOfFile () failed: 0x%x\n", dwErr);
  538. hr = HRESULT_FROM_WIN32 (dwErr);
  539. }
  540. }
  541. else
  542. {
  543. DWORD dwErr = GetLastError ();
  544. _TRACE (0, L"GetFileSize () failed: 0x%x\n", dwErr);
  545. hr = HRESULT_FROM_WIN32 (dwErr);
  546. }
  547. VERIFY (CloseHandle(hMapping));
  548. hMapping = 0;
  549. }
  550. else
  551. {
  552. DWORD dwErr = GetLastError ();
  553. _TRACE (0, L"CreateFileMapping () failed: 0x%x\n", dwErr);
  554. hr = HRESULT_FROM_WIN32 (dwErr);
  555. }
  556. _TRACE (-1, L"Leaving ComputeMD5Hash (): 0x%x\n", hr);
  557. return hr;
  558. }
  559. CString GetURLZoneFriendlyName (DWORD dwURLZoneID)
  560. {
  561. CString szFriendlyName;
  562. switch (dwURLZoneID)
  563. {
  564. case URLZONE_LOCAL_MACHINE:
  565. VERIFY (szFriendlyName.LoadString (IDS_URLZONE_LOCAL_MACHINE));
  566. break;
  567. case URLZONE_INTRANET:
  568. VERIFY (szFriendlyName.LoadString (IDS_URLZONE_INTRANET));
  569. break;
  570. case URLZONE_TRUSTED:
  571. VERIFY (szFriendlyName.LoadString (IDS_URLZONE_TRUSTED));
  572. break;
  573. case URLZONE_INTERNET:
  574. VERIFY (szFriendlyName.LoadString (IDS_URLZONE_INTERNET));
  575. break;
  576. case URLZONE_UNTRUSTED:
  577. VERIFY (szFriendlyName.LoadString (IDS_URLZONE_UNTRUSTED));
  578. break;
  579. default:
  580. ASSERT (0);
  581. VERIFY (szFriendlyName.LoadString (IDS_URLZONE_UNKNOWN));
  582. break;
  583. }
  584. return szFriendlyName;
  585. }
  586. //
  587. // Given a GUID in string format it returns a GUID struct
  588. //
  589. // e.g. "{00299570-246d-11d0-a768-00aa006e0529}" to a struct form
  590. //
  591. BOOL GuidFromString(GUID* pGuid, LPCWSTR lpszGuidString)
  592. {
  593. ZeroMemory(pGuid, sizeof(GUID));
  594. if (lpszGuidString == NULL)
  595. {
  596. return FALSE;
  597. }
  598. int nLen = lstrlen(lpszGuidString);
  599. // the string length should be 38
  600. if (nLen != 38)
  601. return FALSE;
  602. return SUCCEEDED(::CLSIDFromString (const_cast <LPOLESTR>(lpszGuidString), pGuid));
  603. }
  604. HRESULT SaferSetDefinedFileTypes (
  605. HWND hWnd,
  606. HKEY hGroupPolicyKey,
  607. PCWSTR pszFileTypes,
  608. int nBufLen)
  609. {
  610. HRESULT hr = S_OK;
  611. DWORD dwDisposition = 0;
  612. HKEY hKey = 0;
  613. LONG lResult = ::RegCreateKeyEx (hGroupPolicyKey, // handle of an open key
  614. SAFER_COMPUTER_CODEIDS_REGKEY, // address of subkey name
  615. 0, // reserved
  616. L"", // address of class string
  617. REG_OPTION_NON_VOLATILE, // special options flag
  618. KEY_ALL_ACCESS, // desired security access
  619. NULL, // address of key security structure
  620. &hKey, // address of buffer for opened handle
  621. &dwDisposition); // address of disposition value buffer
  622. ASSERT (ERROR_SUCCESS == lResult);
  623. if ( ERROR_SUCCESS == lResult )
  624. {
  625. lResult = ::RegSetValueEx (
  626. hKey, // handle to key
  627. SAFER_EXETYPES_REGVALUE, // value name
  628. 0, // reserved
  629. REG_MULTI_SZ, // value type
  630. (PBYTE) pszFileTypes, // value data
  631. nBufLen); // size of value data
  632. if ( ERROR_SUCCESS != lResult )
  633. {
  634. DisplaySystemError (hWnd, lResult);
  635. _TRACE (0, L"RegSetValueEx (SAFER_EXETYPES_REGVALUE, %s) failed: %d\n",
  636. pszFileTypes, lResult);
  637. hr = HRESULT_FROM_WIN32 (lResult);
  638. }
  639. RegCloseKey (hKey);
  640. }
  641. else
  642. {
  643. DisplaySystemError (hWnd, lResult);
  644. _TRACE (0, L"RegCreateKeyEx (SAFER_CODEID_KEY) failed: %d\n", lResult);
  645. hr = HRESULT_FROM_WIN32 (lResult);
  646. }
  647. return hr;
  648. }