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.

1681 lines
43 KiB

  1. //
  2. // Application Verifier UI
  3. // Copyright (c) Microsoft Corporation, 2001
  4. //
  5. //
  6. //
  7. // module: Setting.cpp
  8. // author: DMihai
  9. // created: 02/22/2001
  10. //
  11. // Description:
  12. //
  13. //
  14. #include "stdafx.h"
  15. #include "appverif.h"
  16. #include "Setting.h"
  17. #include "AVUtil.h"
  18. #include "DBSupport.h"
  19. #include "AVGlobal.h"
  20. #ifdef _DEBUG
  21. #define new DEBUG_NEW
  22. #undef THIS_FILE
  23. static char THIS_FILE[] = __FILE__;
  24. #endif
  25. /////////////////////////////////////////////////////////////////////////////
  26. /////////////////////////////////////////////////////////////////////////////
  27. /////////////////////////////////////////////////////////////////////////////
  28. //
  29. // Global data:
  30. /////////////////////////////////////////////////////////////////////////////
  31. //
  32. // New app verifier settings
  33. //
  34. CAVSettings g_NewSettings;
  35. //
  36. // Current settings bits - used as temporary variable
  37. // to store custom settings bits between the settings bits
  38. // page and the app selection page.
  39. //
  40. DWORD g_dwNewSettingBits;
  41. /////////////////////////////////////////////////////////////////////////////
  42. //
  43. // Changed settings? If yes, the program will exit with AV_EXIT_CODE_RESTART
  44. //
  45. BOOL g_bChangedSettings = FALSE;
  46. /////////////////////////////////////////////////////////////////////////////
  47. CAppAndBitsArray g_aAppsAndBitsFromRegistry;
  48. /////////////////////////////////////////////////////////////////////////////
  49. //
  50. // Registry keys/values names
  51. //
  52. const TCHAR g_szImageOptionsKeyName[] = _T( "Software\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options" );
  53. const TCHAR g_szGlobalFlagValueName[] = _T( "GlobalFlag" );
  54. const TCHAR g_szVerifierFlagsValueName[] = _T( "VerifierFlags" );
  55. /////////////////////////////////////////////////////////////////////////////
  56. //
  57. // Bit names
  58. //
  59. BIT_LISTNAME_CMDLINESWITCH g_AllNamesAndBits[ 5 ] =
  60. {
  61. {
  62. IDS_PAGEHEAP_CMD_LINE,
  63. IDS_PAGE_HEAP,
  64. RTL_VRF_FLG_FULL_PAGE_HEAP
  65. },
  66. {
  67. IDS_LOCKS_CMD_LINE,
  68. IDS_VERIFY_LOCKS_CHECKS,
  69. RTL_VRF_FLG_LOCK_CHECKS
  70. },
  71. {
  72. IDS_HANDLES_CMD_LINE,
  73. IDS_VERIFY_HANDLE_CHECKS,
  74. RTL_VRF_FLG_HANDLE_CHECKS
  75. },
  76. {
  77. IDS_STACKS_CMD_LINE,
  78. IDS_VERIFY_STACK_CHECKS,
  79. RTL_VRF_FLG_STACK_CHECKS
  80. },
  81. {
  82. IDS_APPCOMPAT_CMD_LINE,
  83. IDS_VERIFY_APPCOMPAT_CHECKS,
  84. RTL_VRF_FLG_APPCOMPAT_CHECKS
  85. },
  86. };
  87. /////////////////////////////////////////////////////////////////////////////
  88. /////////////////////////////////////////////////////////////////////////////
  89. /////////////////////////////////////////////////////////////////////////////
  90. //
  91. // CApplicationData class
  92. //
  93. CApplicationData::CApplicationData( LPCTSTR szFileName,
  94. LPCTSTR szFullPath,
  95. ULONG uSettingsBits )
  96. {
  97. m_strExeFileName = szFileName;
  98. m_uCustomFlags = uSettingsBits;
  99. m_bSaved = FALSE;
  100. LoadAppVersionData( szFullPath );
  101. }
  102. /////////////////////////////////////////////////////////////////////////////
  103. //
  104. // This version of the constructor will not try to load version info
  105. //
  106. CApplicationData::CApplicationData( LPCTSTR szFileName,
  107. ULONG uSettingsBits )
  108. {
  109. ASSERT( FALSE != g_bCommandLineMode );
  110. m_strExeFileName = szFileName;
  111. m_uCustomFlags = uSettingsBits;
  112. m_bSaved = FALSE;
  113. }
  114. /////////////////////////////////////////////////////////////////////////////
  115. VOID CApplicationData::LoadAppVersionData( LPCTSTR szFileName )
  116. {
  117. BOOL bResult;
  118. PVOID pWholeVerBlock;
  119. PVOID pTranslationInfoBuffer;
  120. LPCTSTR szVariableValue;
  121. LPTSTR szAppFullPath;
  122. DWORD dwWholeBlockSize;
  123. DWORD dwDummyHandle;
  124. UINT uInfoLengthInTChars;
  125. TCHAR szLocale[ 32 ];
  126. TCHAR szBlockName[ 64 ];
  127. CString strAppFullPath;
  128. bResult = FALSE;
  129. //
  130. // Get the size of the file info block
  131. //
  132. // GetFileVersionInfoSize doesn't know about
  133. // const pointers so we need to GetBuffer here :-(
  134. //
  135. strAppFullPath = szFileName;
  136. szAppFullPath = strAppFullPath.GetBuffer( strAppFullPath.GetLength() + 1 );
  137. if( NULL == szAppFullPath )
  138. {
  139. goto InitializeWithDefaults;
  140. }
  141. dwWholeBlockSize = GetFileVersionInfoSize( szAppFullPath,
  142. &dwDummyHandle );
  143. strAppFullPath.ReleaseBuffer();
  144. if( dwWholeBlockSize == 0 )
  145. {
  146. //
  147. // Couldn't read version information
  148. //
  149. goto InitializeWithDefaults;
  150. }
  151. //
  152. // Allocate the buffer for the version information
  153. //
  154. pWholeVerBlock = malloc( dwWholeBlockSize );
  155. if( pWholeVerBlock == NULL )
  156. {
  157. goto InitializeWithDefaults;
  158. }
  159. //
  160. // Get the version information
  161. //
  162. // GetFileVersionInfo doesn't know about
  163. // const pointers so we need to GetBuffer here :-(
  164. //
  165. szAppFullPath = strAppFullPath.GetBuffer( strAppFullPath.GetLength() + 1 );
  166. if( NULL == szAppFullPath )
  167. {
  168. free( pWholeVerBlock );
  169. goto InitializeWithDefaults;
  170. }
  171. bResult = GetFileVersionInfo(
  172. szAppFullPath,
  173. dwDummyHandle,
  174. dwWholeBlockSize,
  175. pWholeVerBlock );
  176. strAppFullPath.ReleaseBuffer();
  177. if( bResult != TRUE )
  178. {
  179. free( pWholeVerBlock );
  180. goto InitializeWithDefaults;
  181. }
  182. //
  183. // Get the locale info
  184. //
  185. bResult = VerQueryValue(
  186. pWholeVerBlock,
  187. _T( "\\VarFileInfo\\Translation" ),
  188. &pTranslationInfoBuffer,
  189. &uInfoLengthInTChars );
  190. if( TRUE != bResult || NULL == pTranslationInfoBuffer )
  191. {
  192. free( pWholeVerBlock );
  193. goto InitializeWithDefaults;
  194. }
  195. //
  196. // Locale info comes back as two little endian words.
  197. // Flip 'em, 'cause we need them big endian for our calls.
  198. //
  199. _stprintf(
  200. szLocale,
  201. _T( "%02X%02X%02X%02X" ),
  202. HIBYTE( LOWORD ( * (LPDWORD) pTranslationInfoBuffer) ),
  203. LOBYTE( LOWORD ( * (LPDWORD) pTranslationInfoBuffer) ),
  204. HIBYTE( HIWORD ( * (LPDWORD) pTranslationInfoBuffer) ),
  205. LOBYTE( HIWORD ( * (LPDWORD) pTranslationInfoBuffer) ) );
  206. //
  207. // Get the file version
  208. //
  209. _stprintf(
  210. szBlockName,
  211. _T( "\\StringFileInfo\\%s\\FileVersion" ),
  212. szLocale );
  213. bResult = VerQueryValue(
  214. pWholeVerBlock,
  215. szBlockName,
  216. (PVOID*) &szVariableValue,
  217. &uInfoLengthInTChars );
  218. if( TRUE != bResult || 0 == uInfoLengthInTChars )
  219. {
  220. //
  221. // Couldn't find the version
  222. //
  223. VERIFY( m_strFileVersion.LoadString( IDS_UNKNOWN ) );
  224. }
  225. else
  226. {
  227. //
  228. // Found the version
  229. //
  230. m_strFileVersion = szVariableValue;
  231. }
  232. //
  233. // Get the company name
  234. //
  235. _stprintf(
  236. szBlockName,
  237. _T( "\\StringFileInfo\\%s\\CompanyName" ),
  238. szLocale );
  239. bResult = VerQueryValue(
  240. pWholeVerBlock,
  241. szBlockName,
  242. (PVOID*) &szVariableValue,
  243. &uInfoLengthInTChars );
  244. if( TRUE != bResult || uInfoLengthInTChars == 0 )
  245. {
  246. //
  247. // Coudln't find the company name
  248. //
  249. m_strCompanyName.LoadString( IDS_UNKNOWN );
  250. }
  251. else
  252. {
  253. m_strCompanyName = szVariableValue;
  254. }
  255. //
  256. // Get the ProductName
  257. //
  258. _stprintf(
  259. szBlockName,
  260. _T( "\\StringFileInfo\\%s\\ProductName" ),
  261. szLocale );
  262. bResult = VerQueryValue(
  263. pWholeVerBlock,
  264. szBlockName,
  265. (PVOID*) &szVariableValue,
  266. &uInfoLengthInTChars );
  267. if( TRUE != bResult || uInfoLengthInTChars == 0 )
  268. {
  269. //
  270. // Coudln't find the ProductName
  271. //
  272. m_strProductName.LoadString( IDS_UNKNOWN );
  273. }
  274. else
  275. {
  276. m_strProductName = szVariableValue;
  277. }
  278. //
  279. // clean-up
  280. //
  281. free( pWholeVerBlock );
  282. goto Done;
  283. InitializeWithDefaults:
  284. m_strCompanyName.LoadString( IDS_UNKNOWN );
  285. m_strFileVersion.LoadString( IDS_UNKNOWN );
  286. m_strProductName.LoadString( IDS_UNKNOWN );
  287. Done:
  288. NOTHING;
  289. }
  290. /////////////////////////////////////////////////////////////////////////////
  291. /////////////////////////////////////////////////////////////////////////////
  292. /////////////////////////////////////////////////////////////////////////////
  293. //
  294. // CApplicationDataArray class
  295. //
  296. CApplicationDataArray::~CApplicationDataArray()
  297. {
  298. DeleteAll();
  299. }
  300. /////////////////////////////////////////////////////////////////////////////
  301. CApplicationData *CApplicationDataArray::GetAt( INT_PTR nIndex )
  302. {
  303. CApplicationData *pRetValue = (CApplicationData *)CObArray::GetAt( nIndex );
  304. ASSERT_VALID( pRetValue );
  305. return pRetValue;
  306. }
  307. /////////////////////////////////////////////////////////////////////////////
  308. VOID CApplicationDataArray::DeleteAll()
  309. {
  310. INT_PTR nArraySize;
  311. CApplicationData *pCrtAppData;
  312. nArraySize = GetSize();
  313. while( nArraySize > 0 )
  314. {
  315. nArraySize -= 1;
  316. pCrtAppData = GetAt( nArraySize );
  317. ASSERT_VALID( pCrtAppData );
  318. delete pCrtAppData;
  319. }
  320. RemoveAll();
  321. }
  322. /////////////////////////////////////////////////////////////////////////////
  323. VOID CApplicationDataArray::DeleteAt( INT_PTR nIndex )
  324. {
  325. CApplicationData *pCrtAppData;
  326. pCrtAppData = GetAt( nIndex );
  327. ASSERT_VALID( pCrtAppData );
  328. delete pCrtAppData;
  329. RemoveAt( nIndex );
  330. }
  331. /////////////////////////////////////////////////////////////////////////////
  332. BOOL CApplicationDataArray::IsFileNameInList( LPCTSTR szFileName )
  333. {
  334. INT_PTR nCrtElement;
  335. INT_PTR nSize;
  336. BOOL bFound;
  337. CApplicationData *pCrtAppData;
  338. bFound = FALSE;
  339. nSize = GetSize();
  340. for( nCrtElement = 0; nCrtElement < nSize; nCrtElement += 1 )
  341. {
  342. pCrtAppData = GetAt( nCrtElement );
  343. ASSERT_VALID( pCrtAppData );
  344. if( 0 == pCrtAppData->m_strExeFileName.CompareNoCase( szFileName ) )
  345. {
  346. bFound = TRUE;
  347. break;
  348. }
  349. }
  350. return bFound;
  351. }
  352. /////////////////////////////////////////////////////////////////////////////
  353. INT_PTR CApplicationDataArray::FileNameIndex( LPCTSTR szFileName )
  354. {
  355. INT_PTR nCrtElement;
  356. INT_PTR nSize;
  357. BOOL bFound;
  358. CApplicationData *pCrtAppData;
  359. bFound = FALSE;
  360. nSize = GetSize();
  361. for( nCrtElement = 0; nCrtElement < nSize; nCrtElement += 1 )
  362. {
  363. pCrtAppData = GetAt( nCrtElement );
  364. ASSERT_VALID( pCrtAppData );
  365. if( 0 == pCrtAppData->m_strExeFileName.CompareNoCase( szFileName ) )
  366. {
  367. bFound = TRUE;
  368. break;
  369. }
  370. }
  371. if( FALSE == bFound )
  372. {
  373. nCrtElement = -1;
  374. }
  375. return nCrtElement;
  376. }
  377. /////////////////////////////////////////////////////////////////////////////
  378. INT_PTR CApplicationDataArray::AddNewAppData( LPCTSTR szFileName,
  379. LPCTSTR szFullPath,
  380. ULONG uSettingsBits )
  381. {
  382. INT_PTR nIndexInArray;
  383. CApplicationData *pNewAppData;
  384. nIndexInArray = -1;
  385. pNewAppData = new CApplicationData( szFileName,
  386. szFullPath,
  387. uSettingsBits );
  388. if( NULL != pNewAppData )
  389. {
  390. nIndexInArray = Add( pNewAppData );
  391. }
  392. return nIndexInArray;
  393. }
  394. /////////////////////////////////////////////////////////////////////////////
  395. INT_PTR CApplicationDataArray::AddNewAppDataConsoleMode( LPCTSTR szFileName,
  396. ULONG uSettingsBits )
  397. {
  398. INT_PTR nIndexInArray;
  399. CApplicationData *pNewAppData;
  400. ASSERT( FALSE != g_bCommandLineMode );
  401. nIndexInArray = -1;
  402. //
  403. // This version of the constructor will not try to load version info
  404. //
  405. pNewAppData = new CApplicationData( szFileName,
  406. uSettingsBits );
  407. if( NULL != pNewAppData )
  408. {
  409. nIndexInArray = Add( pNewAppData );
  410. }
  411. return nIndexInArray;
  412. }
  413. /////////////////////////////////////////////////////////////////////////////
  414. VOID CApplicationDataArray::SetAllSaved( BOOL bSaved )
  415. {
  416. INT_PTR nCrtElement;
  417. INT_PTR nSize;
  418. CApplicationData *pCrtAppData;
  419. nSize = GetSize();
  420. for( nCrtElement = 0; nCrtElement < nSize; nCrtElement += 1 )
  421. {
  422. pCrtAppData = GetAt( nCrtElement );
  423. ASSERT_VALID( pCrtAppData );
  424. pCrtAppData->m_bSaved = bSaved;
  425. }
  426. }
  427. /////////////////////////////////////////////////////////////////////////////
  428. /////////////////////////////////////////////////////////////////////////////
  429. /////////////////////////////////////////////////////////////////////////////
  430. //
  431. // CAVSettings class
  432. //
  433. CAVSettings::CAVSettings()
  434. {
  435. m_SettingsType = AVSettingsTypeUnknown;
  436. }
  437. /////////////////////////////////////////////////////////////////////////////
  438. /////////////////////////////////////////////////////////////////////////////
  439. /////////////////////////////////////////////////////////////////////////////
  440. //
  441. // CAppAndBits class
  442. //
  443. CAppAndBits::CAppAndBits( LPCTSTR szAppName, DWORD dwEnabledBits )
  444. : m_strAppName( szAppName ),
  445. m_dwEnabledBits( dwEnabledBits )
  446. {
  447. NOTHING;
  448. }
  449. /////////////////////////////////////////////////////////////////////////////
  450. /////////////////////////////////////////////////////////////////////////////
  451. /////////////////////////////////////////////////////////////////////////////
  452. //
  453. // CAppAndBitsArray class
  454. //
  455. CAppAndBitsArray::~CAppAndBitsArray()
  456. {
  457. DeleteAll();
  458. }
  459. /////////////////////////////////////////////////////////////////////////////
  460. CAppAndBits *CAppAndBitsArray::GetAt( INT_PTR nIndex )
  461. {
  462. CAppAndBits *pRetValue = (CAppAndBits *)CObArray::GetAt( nIndex );
  463. ASSERT_VALID( pRetValue );
  464. return pRetValue;
  465. }
  466. /////////////////////////////////////////////////////////////////////////////
  467. VOID CAppAndBitsArray::DeleteAll()
  468. {
  469. INT_PTR nArraySize;
  470. CAppAndBits *pCrtElem;
  471. nArraySize = GetSize();
  472. while( nArraySize > 0 )
  473. {
  474. nArraySize -= 1;
  475. pCrtElem = GetAt( nArraySize );
  476. ASSERT_VALID( pCrtElem );
  477. delete pCrtElem;
  478. }
  479. RemoveAll();
  480. }
  481. /////////////////////////////////////////////////////////////////////////////
  482. /////////////////////////////////////////////////////////////////////////////
  483. /////////////////////////////////////////////////////////////////////////////
  484. //
  485. // Helper functions
  486. //
  487. BOOL AVSetVerifierFlags( HKEY hKey,
  488. DWORD dwNewVerifierFlags,
  489. BOOL bTryReadingOldValues,
  490. BOOL *pbValuesChanged,
  491. BOOL bDeleteOtherSettings )
  492. {
  493. BOOL bSuccess;
  494. LONG lResult;
  495. DWORD dwOldVerifierFlags;
  496. DWORD dwDataSize;
  497. DWORD dwType;
  498. bSuccess = TRUE;
  499. if( FALSE != bTryReadingOldValues )
  500. {
  501. //
  502. // Read the existing app verifier flags
  503. //
  504. dwDataSize = sizeof( dwOldVerifierFlags );
  505. lResult = RegQueryValueEx( hKey,
  506. g_szVerifierFlagsValueName,
  507. NULL,
  508. &dwType,
  509. (LPBYTE) &dwOldVerifierFlags,
  510. &dwDataSize );
  511. if( lResult != ERROR_SUCCESS )
  512. {
  513. switch( lResult )
  514. {
  515. case ERROR_FILE_NOT_FOUND:
  516. //
  517. // No VerifierFlags for this image currently
  518. //
  519. dwOldVerifierFlags = 0;
  520. break;
  521. case ERROR_ACCESS_DENIED:
  522. AVErrorResourceFormat( IDS_ACCESS_IS_DENIED );
  523. bSuccess = FALSE;
  524. goto Done;
  525. default:
  526. AVErrorResourceFormat( IDS_REGQUERYVALUEEX_FAILED,
  527. g_szVerifierFlagsValueName,
  528. (DWORD)lResult);
  529. bSuccess = FALSE;
  530. goto Done;
  531. }
  532. }
  533. else
  534. {
  535. if( REG_DWORD != dwType )
  536. {
  537. AVErrorResourceFormat( IDS_INCORRECT_VALUE_TYPE,
  538. g_szVerifierFlagsValueName,
  539. dwType );
  540. bSuccess = FALSE;
  541. goto Done;
  542. }
  543. }
  544. }
  545. else
  546. {
  547. //
  548. // We know this is a new regkey so we don't have any verifier flags yet
  549. //
  550. dwOldVerifierFlags = 0;
  551. }
  552. //
  553. // New app verifier flags
  554. //
  555. if( dwNewVerifierFlags != dwOldVerifierFlags || dwNewVerifierFlags == 0 )
  556. {
  557. lResult = RegSetValueEx( hKey,
  558. g_szVerifierFlagsValueName,
  559. 0,
  560. REG_DWORD,
  561. (PBYTE) &dwNewVerifierFlags,
  562. sizeof( dwNewVerifierFlags ) );
  563. if( lResult != ERROR_SUCCESS )
  564. {
  565. if( ERROR_ACCESS_DENIED == lResult )
  566. {
  567. AVErrorResourceFormat( IDS_ACCESS_IS_DENIED );
  568. }
  569. else
  570. {
  571. AVErrorResourceFormat( IDS_REGSETVALUEEX_FAILED,
  572. g_szVerifierFlagsValueName,
  573. (DWORD)lResult);
  574. }
  575. bSuccess = FALSE;
  576. }
  577. else
  578. {
  579. *pbValuesChanged = TRUE;
  580. }
  581. }
  582. Done:
  583. return bSuccess;
  584. }
  585. /////////////////////////////////////////////////////////////////////////////
  586. BOOL AVSetVerifierFlagsForExe( LPCTSTR szExeName,
  587. DWORD dwNewVerifierFlags )
  588. {
  589. LONG lResult;
  590. HKEY hImageOptionsKey = NULL, hSubKey = NULL;
  591. BOOL bValuesChanged;
  592. BOOL bSuccess;
  593. DWORD dwValueType;
  594. DWORD dwGlobalFlagValueBufferSize;
  595. TCHAR szOldGlobalFlagValue[ 32 ];
  596. //
  597. // Open the Image File Execution Options regkey
  598. //
  599. lResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  600. g_szImageOptionsKeyName,
  601. 0,
  602. KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS,
  603. &hImageOptionsKey );
  604. if( lResult != ERROR_SUCCESS )
  605. {
  606. return FALSE;
  607. }
  608. lResult = RegCreateKeyEx( hImageOptionsKey,
  609. szExeName,
  610. 0,
  611. NULL,
  612. REG_OPTION_NON_VOLATILE,
  613. KEY_QUERY_VALUE | KEY_SET_VALUE,
  614. NULL,
  615. &hSubKey,
  616. NULL );
  617. if( lResult == ERROR_SUCCESS )
  618. {
  619. dwGlobalFlagValueBufferSize = sizeof( szOldGlobalFlagValue );
  620. lResult = RegQueryValueEx( hSubKey,
  621. g_szGlobalFlagValueName,
  622. NULL,
  623. &dwValueType,
  624. (LPBYTE) &szOldGlobalFlagValue[ 0 ],
  625. &dwGlobalFlagValueBufferSize );
  626. if( lResult == ERROR_FILE_NOT_FOUND )
  627. {
  628. szOldGlobalFlagValue[ 0 ] = (TCHAR)0;
  629. lResult = ERROR_SUCCESS;
  630. }
  631. if( lResult == ERROR_SUCCESS )
  632. {
  633. DWORD dwGlobalFlags;
  634. BOOL bSuccesfullyConverted;
  635. bSuccesfullyConverted = AVRtlCharToInteger( szOldGlobalFlagValue,
  636. 0,
  637. &dwGlobalFlags );
  638. if( !bSuccesfullyConverted )
  639. {
  640. dwGlobalFlags = 0;
  641. }
  642. if ( dwNewVerifierFlags == 0)
  643. {
  644. dwGlobalFlags &= ~FLG_APPLICATION_VERIFIER;
  645. }
  646. else
  647. {
  648. dwGlobalFlags |= FLG_APPLICATION_VERIFIER;
  649. }
  650. bSuccess = AVWriteStringHexValueToRegistry( hSubKey,
  651. g_szGlobalFlagValueName,
  652. dwGlobalFlags );
  653. bSuccess = bSuccess && AVSetVerifierFlags( hSubKey,
  654. dwNewVerifierFlags,
  655. FALSE,
  656. &bValuesChanged,
  657. TRUE );
  658. }
  659. }
  660. if ( hSubKey != NULL )
  661. {
  662. VERIFY( ERROR_SUCCESS == RegCloseKey( hSubKey ) );
  663. }
  664. if ( hImageOptionsKey != NULL )
  665. {
  666. VERIFY( ERROR_SUCCESS == RegCloseKey( hImageOptionsKey ) );
  667. }
  668. return bSuccess;
  669. }
  670. /////////////////////////////////////////////////////////////////////////////
  671. BOOL AVCreateAppSettings( HKEY hKey,
  672. BOOL bTryReadingOldValues,
  673. LPCTSTR szOldGlobalFlagValue,
  674. CApplicationData *pCrtAppData,
  675. PBOOL pbValuesChanged,
  676. CStringArray &astrAppCompatTestedExes,
  677. BOOL bDeleteOtherSettings )
  678. {
  679. BOOL bSuccess;
  680. BOOL bSuccesfullyConverted;
  681. DWORD dwOldGlobalFlags;
  682. DWORD dwNewGlobalFlags;
  683. DWORD dwNewVerifierFlags;
  684. bSuccess = TRUE;
  685. *pbValuesChanged = FALSE;
  686. if( NULL != pCrtAppData )
  687. {
  688. ASSERT_VALID( pCrtAppData );
  689. }
  690. if( FALSE != bTryReadingOldValues )
  691. {
  692. //
  693. // Convert the REG_SZ GlobalFlag value to a DWORD
  694. //
  695. bSuccesfullyConverted = AVRtlCharToInteger( szOldGlobalFlagValue,
  696. 0,
  697. &dwOldGlobalFlags );
  698. if( FALSE == bSuccesfullyConverted )
  699. {
  700. dwOldGlobalFlags = 0;
  701. }
  702. }
  703. else
  704. {
  705. //
  706. // This is a new regkey so we know we don't have any GlobalFlag yet
  707. //
  708. dwOldGlobalFlags = 0;
  709. }
  710. if( 0 != (FLG_APPLICATION_VERIFIER & dwOldGlobalFlags) )
  711. {
  712. //
  713. // This app used to have the verifier enabled
  714. //
  715. if( NULL == pCrtAppData ||
  716. ( AVSettingsTypeCustom == g_NewSettings.m_SettingsType &&
  717. 0 == pCrtAppData->m_uCustomFlags ) )
  718. {
  719. //
  720. // The user didn't specify this app to verified
  721. //
  722. if( FALSE != bDeleteOtherSettings )
  723. {
  724. //
  725. // This app will not have the verifier enabled from now on
  726. //
  727. dwNewGlobalFlags = dwOldGlobalFlags & ~FLG_APPLICATION_VERIFIER;
  728. }
  729. else
  730. {
  731. //
  732. // Even if the user didn't specify this app
  733. // she actually wants to keep the existing settings for this app.
  734. //
  735. goto Done;
  736. }
  737. }
  738. else
  739. {
  740. //
  741. // This app will continue to have the verifier enabled from now on.
  742. // Set the new verifier flags though.
  743. //
  744. if( AVSettingsTypeStandard == g_NewSettings.m_SettingsType )
  745. {
  746. dwNewVerifierFlags = AV_ALL_STANDARD_VERIFIER_FLAGS;
  747. }
  748. else
  749. {
  750. dwNewVerifierFlags = pCrtAppData->m_uCustomFlags;
  751. }
  752. bSuccess = AVSetVerifierFlags( hKey,
  753. dwNewVerifierFlags,
  754. bTryReadingOldValues,
  755. pbValuesChanged,
  756. bDeleteOtherSettings );
  757. if( FALSE != bSuccess &&
  758. ( dwNewVerifierFlags & RTL_VRF_FLG_APPCOMPAT_CHECKS ) != 0 )
  759. {
  760. //
  761. // This app has app compat checks enabled
  762. //
  763. astrAppCompatTestedExes.Add( pCrtAppData->m_strExeFileName );
  764. }
  765. goto Done;
  766. }
  767. }
  768. else
  769. {
  770. //
  771. // This app didn't have the app verifier enabled until now
  772. //
  773. if( NULL == pCrtAppData ||
  774. ( AVSettingsTypeCustom == g_NewSettings.m_SettingsType &&
  775. 0 == pCrtAppData->m_uCustomFlags ) )
  776. {
  777. //
  778. // This app will NOT have the verifier enabled from now on.
  779. // Nothing to change.
  780. //
  781. goto Done;
  782. }
  783. else
  784. {
  785. //
  786. // This app will have the verifier enabled from now on.
  787. //
  788. dwNewGlobalFlags = dwOldGlobalFlags | FLG_APPLICATION_VERIFIER;
  789. }
  790. }
  791. ASSERT( dwNewGlobalFlags != dwOldGlobalFlags );
  792. //
  793. // Write the new global flags for this app
  794. //
  795. bSuccess = AVWriteStringHexValueToRegistry( hKey,
  796. g_szGlobalFlagValueName,
  797. dwNewGlobalFlags );
  798. if( FALSE != bSuccess )
  799. {
  800. *pbValuesChanged = TRUE;
  801. //
  802. // Set the new verifier flags
  803. //
  804. if( AVSettingsTypeStandard == g_NewSettings.m_SettingsType )
  805. {
  806. dwNewVerifierFlags = AV_ALL_STANDARD_VERIFIER_FLAGS;
  807. }
  808. else
  809. {
  810. if( NULL != pCrtAppData )
  811. {
  812. dwNewVerifierFlags = pCrtAppData->m_uCustomFlags;
  813. }
  814. else
  815. {
  816. dwNewVerifierFlags = 0;
  817. }
  818. }
  819. bSuccess = AVSetVerifierFlags( hKey,
  820. dwNewVerifierFlags,
  821. bTryReadingOldValues,
  822. pbValuesChanged,
  823. bDeleteOtherSettings );
  824. if( FALSE != bSuccess &&
  825. NULL != pCrtAppData &&
  826. ( dwNewVerifierFlags & RTL_VRF_FLG_APPCOMPAT_CHECKS ) != 0 )
  827. {
  828. //
  829. // This app has app compat checks enabled
  830. //
  831. astrAppCompatTestedExes.Add( pCrtAppData->m_strExeFileName );
  832. }
  833. }
  834. Done:
  835. return bSuccess;
  836. }
  837. /////////////////////////////////////////////////////////////////////////////
  838. //
  839. // Save the new app verifier settings for one image
  840. //
  841. BOOL AVSaveAppNewSettings( HKEY hKey,
  842. BOOL bTryReadingOldValues,
  843. LPCTSTR szAppName,
  844. PBOOL pbAnythingChanged,
  845. CStringArray &astrAppCompatTestedExes,
  846. BOOL bDeleteOtherSettings )
  847. {
  848. BOOL bSuccess;
  849. BOOL bValuesChanged;
  850. INT_PTR nIndexInArray;
  851. LONG lResult;
  852. DWORD dwGlobalFlagValueBufferSize;
  853. DWORD dwValueType;
  854. CApplicationData *pCrtAppData;
  855. TCHAR szOldGlobalFlagValue[ 32 ];
  856. bSuccess = TRUE;
  857. if( FALSE != bTryReadingOldValues )
  858. {
  859. //
  860. // See if the app verifier flag is currently enabled for this app
  861. //
  862. dwGlobalFlagValueBufferSize = sizeof( szOldGlobalFlagValue );
  863. lResult = RegQueryValueEx( hKey,
  864. g_szGlobalFlagValueName,
  865. NULL,
  866. &dwValueType,
  867. (LPBYTE) &szOldGlobalFlagValue[ 0 ],
  868. &dwGlobalFlagValueBufferSize );
  869. if( lResult != ERROR_SUCCESS )
  870. {
  871. switch( lResult )
  872. {
  873. case ERROR_FILE_NOT_FOUND:
  874. //
  875. // No GlobalFlag for this image currently
  876. //
  877. szOldGlobalFlagValue[ 0 ] = (TCHAR)0;
  878. break;
  879. case ERROR_ACCESS_DENIED:
  880. AVErrorResourceFormat( IDS_ACCESS_IS_DENIED );
  881. bSuccess = FALSE;
  882. goto Done;
  883. default:
  884. AVErrorResourceFormat( IDS_REGQUERYVALUEEX_FAILED,
  885. g_szGlobalFlagValueName,
  886. (DWORD)lResult);
  887. bSuccess = FALSE;
  888. goto Done;
  889. }
  890. }
  891. else
  892. {
  893. if( REG_SZ != dwValueType )
  894. {
  895. AVErrorResourceFormat( IDS_INCORRECT_VALUE_TYPE,
  896. g_szGlobalFlagValueName,
  897. dwValueType );
  898. bSuccess = FALSE;
  899. goto Done;
  900. }
  901. }
  902. }
  903. else
  904. {
  905. //
  906. // This is a new subkey so we don't have any GlobalFlag yet
  907. //
  908. szOldGlobalFlagValue[ 0 ] = (TCHAR)0;
  909. }
  910. nIndexInArray = g_NewSettings.m_aApplicationData.FileNameIndex( szAppName );
  911. if( nIndexInArray >= 0 )
  912. {
  913. //
  914. // This app will be verified from now on.
  915. //
  916. pCrtAppData = g_NewSettings.m_aApplicationData.GetAt( nIndexInArray );
  917. ASSERT_VALID( pCrtAppData );
  918. }
  919. else
  920. {
  921. //
  922. // This app will not be verified from now on.
  923. //
  924. pCrtAppData = NULL;
  925. }
  926. bSuccess = AVCreateAppSettings( hKey,
  927. bTryReadingOldValues,
  928. szOldGlobalFlagValue,
  929. pCrtAppData,
  930. &bValuesChanged,
  931. astrAppCompatTestedExes,
  932. bDeleteOtherSettings );
  933. if( FALSE != bSuccess )
  934. {
  935. if( NULL != pCrtAppData )
  936. {
  937. pCrtAppData->m_bSaved = TRUE;
  938. }
  939. *pbAnythingChanged = *pbAnythingChanged || bValuesChanged;
  940. }
  941. Done:
  942. return bSuccess;
  943. }
  944. /////////////////////////////////////////////////////////////////////////////
  945. //
  946. // Save the new app verifier settings for all images
  947. //
  948. BOOL AVSaveNewSettings( BOOL bDeleteOtherSettings /*= TRUE*/ )
  949. {
  950. BOOL bSuccess;
  951. LONG lResult;
  952. DWORD dwSubkeyIndex;
  953. DWORD dwKeyNameBufferLen;
  954. HKEY hImageOptionsKey;
  955. HKEY hSubKey;
  956. INT_PTR nAppsToVerify;
  957. INT_PTR nCrtAppToVerify;
  958. FILETIME LastWriteTime;
  959. CApplicationData *pCrtAppData;
  960. CStringArray astrAppCompatTestedExes;
  961. TCHAR szKeyNameBuffer[ 256 ];
  962. g_bChangedSettings = FALSE;
  963. bSuccess = FALSE;
  964. g_NewSettings.m_aApplicationData.SetAllSaved( FALSE );
  965. //
  966. // Open the Image File Execution Options regkey
  967. //
  968. lResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  969. g_szImageOptionsKeyName,
  970. 0,
  971. KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS,
  972. &hImageOptionsKey );
  973. if( lResult != ERROR_SUCCESS )
  974. {
  975. if( lResult == ERROR_ACCESS_DENIED )
  976. {
  977. AVErrorResourceFormat(
  978. IDS_ACCESS_IS_DENIED );
  979. }
  980. else
  981. {
  982. AVErrorResourceFormat(
  983. IDS_REGOPENKEYEX_FAILED,
  984. g_szImageOptionsKeyName,
  985. (DWORD)lResult);
  986. }
  987. goto Done;
  988. }
  989. //
  990. // Enumerate all the existing subkeys for app execution options
  991. //
  992. for( dwSubkeyIndex = 0; TRUE; dwSubkeyIndex += 1 )
  993. {
  994. dwKeyNameBufferLen = ARRAY_LENGTH( szKeyNameBuffer );
  995. lResult = RegEnumKeyEx( hImageOptionsKey,
  996. dwSubkeyIndex,
  997. szKeyNameBuffer,
  998. &dwKeyNameBufferLen,
  999. NULL,
  1000. NULL,
  1001. NULL,
  1002. &LastWriteTime );
  1003. if( lResult != ERROR_SUCCESS )
  1004. {
  1005. if( lResult == ERROR_NO_MORE_ITEMS )
  1006. {
  1007. //
  1008. // We finished looking at all the existing subkeys
  1009. //
  1010. break;
  1011. }
  1012. else
  1013. {
  1014. if( lResult == ERROR_ACCESS_DENIED )
  1015. {
  1016. AVErrorResourceFormat(
  1017. IDS_ACCESS_IS_DENIED );
  1018. }
  1019. else
  1020. {
  1021. AVErrorResourceFormat(
  1022. IDS_REGENUMKEYEX_FAILED,
  1023. g_szImageOptionsKeyName,
  1024. (DWORD)lResult);
  1025. }
  1026. goto CleanUpAndDone;
  1027. }
  1028. }
  1029. //
  1030. // Open the subkey
  1031. //
  1032. lResult = RegOpenKeyEx( hImageOptionsKey,
  1033. szKeyNameBuffer,
  1034. 0,
  1035. KEY_QUERY_VALUE | KEY_SET_VALUE,
  1036. &hSubKey );
  1037. if( lResult != ERROR_SUCCESS )
  1038. {
  1039. if( lResult == ERROR_ACCESS_DENIED )
  1040. {
  1041. AVErrorResourceFormat(
  1042. IDS_ACCESS_IS_DENIED );
  1043. }
  1044. else
  1045. {
  1046. AVErrorResourceFormat(
  1047. IDS_REGOPENKEYEX_FAILED,
  1048. szKeyNameBuffer,
  1049. (DWORD)lResult);
  1050. }
  1051. goto CleanUpAndDone;
  1052. }
  1053. bSuccess = AVSaveAppNewSettings( hSubKey,
  1054. TRUE,
  1055. szKeyNameBuffer,
  1056. &g_bChangedSettings,
  1057. astrAppCompatTestedExes,
  1058. bDeleteOtherSettings ) ;
  1059. VERIFY( ERROR_SUCCESS == RegCloseKey( hSubKey ) );
  1060. }
  1061. //
  1062. // Add any new image execution options keys necessary
  1063. //
  1064. nAppsToVerify = g_NewSettings.m_aApplicationData.GetSize();
  1065. for( nCrtAppToVerify = 0; nCrtAppToVerify < nAppsToVerify; nCrtAppToVerify += 1 )
  1066. {
  1067. pCrtAppData = g_NewSettings.m_aApplicationData.GetAt( nCrtAppToVerify );
  1068. ASSERT_VALID( pCrtAppData );
  1069. if( FALSE == pCrtAppData->m_bSaved )
  1070. {
  1071. lResult = RegCreateKeyEx( hImageOptionsKey,
  1072. (LPCTSTR) pCrtAppData->m_strExeFileName,
  1073. 0,
  1074. NULL,
  1075. REG_OPTION_NON_VOLATILE,
  1076. KEY_QUERY_VALUE | KEY_SET_VALUE,
  1077. NULL,
  1078. &hSubKey,
  1079. NULL );
  1080. if( STATUS_SUCCESS != lResult )
  1081. {
  1082. if( lResult == ERROR_ACCESS_DENIED )
  1083. {
  1084. AVErrorResourceFormat(
  1085. IDS_ACCESS_IS_DENIED );
  1086. }
  1087. else
  1088. {
  1089. AVErrorResourceFormat(
  1090. IDS_REGCREATEKEYEX_FAILED,
  1091. (LPCTSTR) pCrtAppData->m_strExeFileName,
  1092. (DWORD)lResult);
  1093. }
  1094. goto CleanUpAndDone;
  1095. }
  1096. //
  1097. // Create the app verifier settings for this app
  1098. //
  1099. bSuccess = AVSaveAppNewSettings( hSubKey,
  1100. FALSE,
  1101. (LPCTSTR) pCrtAppData->m_strExeFileName,
  1102. &g_bChangedSettings,
  1103. astrAppCompatTestedExes,
  1104. FALSE ) ;
  1105. VERIFY( ERROR_SUCCESS == RegCloseKey( hSubKey ) );
  1106. }
  1107. }
  1108. //
  1109. // Update the app compat settings
  1110. //
  1111. if( FALSE != bSuccess && FALSE != g_bChangedSettings )
  1112. {
  1113. AppCompatSaveSettings( astrAppCompatTestedExes );
  1114. }
  1115. //
  1116. // Let the user know if we have changed any settings
  1117. //
  1118. if( FALSE != g_bChangedSettings )
  1119. {
  1120. if( 0 < nAppsToVerify )
  1121. {
  1122. AVMesssageFromResource( IDS_SETTINGS_SAVED );
  1123. }
  1124. else
  1125. {
  1126. AVMesssageFromResource( IDS_SETTINGS_DELETED );
  1127. }
  1128. }
  1129. else
  1130. {
  1131. AVMesssageFromResource( IDS_NO_SETTINGS_CHANGED );
  1132. }
  1133. CleanUpAndDone:
  1134. VERIFY( ERROR_SUCCESS == RegCloseKey( hImageOptionsKey ) );
  1135. Done:
  1136. return bSuccess;
  1137. }
  1138. /////////////////////////////////////////////////////////////////////////////
  1139. //
  1140. // Dump the current registry settings to the console
  1141. //
  1142. VOID AVDumpRegistrySettingsToConsole()
  1143. {
  1144. INT_PTR nCrtFlag;
  1145. INT_PTR nAppsNo;
  1146. INT_PTR nCrtApp;
  1147. BOOL bDisplayedThisApp;
  1148. CAppAndBits *pCrtElem;
  1149. TCHAR szBitName[ 64 ];
  1150. //
  1151. // Read the current registry settings
  1152. //
  1153. AVReadCrtRegistrySettings();
  1154. nAppsNo = g_aAppsAndBitsFromRegistry.GetSize();
  1155. if( nAppsNo > 0 )
  1156. {
  1157. AVPrintStringFromResources( IDS_VERIFIED_APPS );
  1158. }
  1159. //
  1160. // Parse all the elements and print out the enabled flags
  1161. //
  1162. for( nCrtApp = 0; nCrtApp < nAppsNo; nCrtApp += 1 )
  1163. {
  1164. pCrtElem = g_aAppsAndBitsFromRegistry.GetAt( nCrtApp );
  1165. ASSERT_VALID( pCrtElem );
  1166. ASSERT( 0 != pCrtElem->m_dwEnabledBits );
  1167. bDisplayedThisApp = FALSE;
  1168. for( nCrtFlag = 0; nCrtFlag < ARRAY_LENGTH( g_AllNamesAndBits ); nCrtFlag += 1 )
  1169. {
  1170. if( (pCrtElem->m_dwEnabledBits & g_AllNamesAndBits[ nCrtFlag ].m_dwBit) != 0 )
  1171. {
  1172. //
  1173. // This verifier bit is enabled.
  1174. // Display the app name, if not displayed already, then the bit name.
  1175. //
  1176. if( FALSE == bDisplayedThisApp )
  1177. {
  1178. _putts( _T( " " ) );
  1179. _putts( (LPCTSTR)pCrtElem->m_strAppName );
  1180. _putts( _T( " " ) );
  1181. AVPrintStringFromResources( IDS_TESTS );
  1182. _putts( _T( " " ) );
  1183. bDisplayedThisApp = TRUE;
  1184. }
  1185. VERIFY( AVLoadString( g_AllNamesAndBits[ nCrtFlag ].m_uNameStringId,
  1186. szBitName,
  1187. ARRAY_LENGTH( szBitName ) ) );
  1188. _putts( szBitName );
  1189. }
  1190. }
  1191. _putts( _T( " " ) );
  1192. }
  1193. if( nAppsNo == 0 )
  1194. {
  1195. AVPrintStringFromResources( IDS_NO_APPS_VERIFIED );
  1196. }
  1197. }
  1198. /////////////////////////////////////////////////////////////////////////////
  1199. //
  1200. // Read the current registry settings
  1201. //
  1202. VOID AVReadCrtRegistrySettings()
  1203. {
  1204. HKEY hImageOptionsKey;
  1205. HKEY hSubKey;
  1206. DWORD dwSubkeyIndex;
  1207. DWORD dwDataSize;
  1208. DWORD dwValueType;
  1209. DWORD dwFlags;
  1210. LONG lResult;
  1211. BOOL bSuccesfullyConverted;
  1212. FILETIME LastWriteTime;
  1213. CAppAndBits *pNewElem;
  1214. TCHAR szOldGlobalFlagValue[ 32 ];
  1215. TCHAR szKeyNameBuffer[ 256 ];
  1216. g_aAppsAndBitsFromRegistry.DeleteAll();
  1217. //
  1218. // Open the Image File Execution Options regkey
  1219. //
  1220. lResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  1221. g_szImageOptionsKeyName,
  1222. 0,
  1223. KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS,
  1224. &hImageOptionsKey );
  1225. if( lResult != ERROR_SUCCESS )
  1226. {
  1227. if( lResult == ERROR_ACCESS_DENIED )
  1228. {
  1229. AVErrorResourceFormat(
  1230. IDS_ACCESS_IS_DENIED );
  1231. }
  1232. else
  1233. {
  1234. AVErrorResourceFormat(
  1235. IDS_REGOPENKEYEX_FAILED,
  1236. g_szImageOptionsKeyName,
  1237. (DWORD)lResult);
  1238. }
  1239. goto Done;
  1240. }
  1241. //
  1242. // Enumerate all the existing subkeys for app execution options
  1243. //
  1244. for( dwSubkeyIndex = 0; TRUE; dwSubkeyIndex += 1 )
  1245. {
  1246. dwDataSize = ARRAY_LENGTH( szKeyNameBuffer );
  1247. lResult = RegEnumKeyEx( hImageOptionsKey,
  1248. dwSubkeyIndex,
  1249. szKeyNameBuffer,
  1250. &dwDataSize,
  1251. NULL,
  1252. NULL,
  1253. NULL,
  1254. &LastWriteTime );
  1255. if( lResult != ERROR_SUCCESS )
  1256. {
  1257. if( lResult == ERROR_NO_MORE_ITEMS )
  1258. {
  1259. //
  1260. // We finished looking at all the existing subkeys
  1261. //
  1262. break;
  1263. }
  1264. else
  1265. {
  1266. if( lResult == ERROR_ACCESS_DENIED )
  1267. {
  1268. AVErrorResourceFormat(
  1269. IDS_ACCESS_IS_DENIED );
  1270. }
  1271. else
  1272. {
  1273. AVErrorResourceFormat(
  1274. IDS_REGENUMKEYEX_FAILED,
  1275. g_szImageOptionsKeyName,
  1276. (DWORD)lResult);
  1277. }
  1278. goto CleanUpAndDone;
  1279. }
  1280. }
  1281. //
  1282. // Open the subkey
  1283. //
  1284. lResult = RegOpenKeyEx( hImageOptionsKey,
  1285. szKeyNameBuffer,
  1286. 0,
  1287. KEY_QUERY_VALUE | KEY_SET_VALUE,
  1288. &hSubKey );
  1289. if( lResult != ERROR_SUCCESS )
  1290. {
  1291. if( lResult == ERROR_ACCESS_DENIED )
  1292. {
  1293. AVErrorResourceFormat(
  1294. IDS_ACCESS_IS_DENIED );
  1295. }
  1296. else
  1297. {
  1298. AVErrorResourceFormat(
  1299. IDS_REGOPENKEYEX_FAILED,
  1300. szKeyNameBuffer,
  1301. (DWORD)lResult);
  1302. }
  1303. goto CleanUpAndDone;
  1304. }
  1305. //
  1306. // Read the GlobalFlag value
  1307. //
  1308. dwDataSize = sizeof( szOldGlobalFlagValue );
  1309. lResult = RegQueryValueEx( hSubKey,
  1310. g_szGlobalFlagValueName,
  1311. NULL,
  1312. &dwValueType,
  1313. (LPBYTE) &szOldGlobalFlagValue[ 0 ],
  1314. &dwDataSize );
  1315. if( ERROR_SUCCESS == lResult )
  1316. {
  1317. bSuccesfullyConverted = AVRtlCharToInteger( szOldGlobalFlagValue,
  1318. 0,
  1319. &dwFlags );
  1320. if( ( FALSE != bSuccesfullyConverted ) &&
  1321. ( ( dwFlags & FLG_APPLICATION_VERIFIER ) != 0 ) )
  1322. {
  1323. //
  1324. // App verifier is enabled for this app - read the verifier flags
  1325. //
  1326. dwDataSize = sizeof( dwFlags );
  1327. lResult = RegQueryValueEx( hSubKey,
  1328. g_szVerifierFlagsValueName,
  1329. NULL,
  1330. &dwValueType,
  1331. (LPBYTE) &dwFlags,
  1332. &dwDataSize );
  1333. if( ERROR_SUCCESS == lResult && REG_DWORD == dwValueType && 0 != dwFlags )
  1334. {
  1335. //
  1336. // Add this app top our global array
  1337. //
  1338. pNewElem = new CAppAndBits( szKeyNameBuffer,
  1339. dwFlags );
  1340. if( NULL != pNewElem )
  1341. {
  1342. g_aAppsAndBitsFromRegistry.Add( pNewElem );
  1343. }
  1344. }
  1345. }
  1346. }
  1347. VERIFY( ERROR_SUCCESS == RegCloseKey( hSubKey ) );
  1348. }
  1349. CleanUpAndDone:
  1350. VERIFY( ERROR_SUCCESS == RegCloseKey( hImageOptionsKey ) );
  1351. Done:
  1352. NOTHING;
  1353. }