1682 lines
43 KiB
C++
1682 lines
43 KiB
C++
|
//
|
||
|
// Application Verifier UI
|
||
|
// Copyright (c) Microsoft Corporation, 2001
|
||
|
//
|
||
|
//
|
||
|
//
|
||
|
// module: Setting.cpp
|
||
|
// author: DMihai
|
||
|
// created: 02/22/2001
|
||
|
//
|
||
|
// Description:
|
||
|
//
|
||
|
//
|
||
|
|
||
|
#include "stdafx.h"
|
||
|
#include "appverif.h"
|
||
|
|
||
|
#include "Setting.h"
|
||
|
#include "AVUtil.h"
|
||
|
#include "DBSupport.h"
|
||
|
#include "AVGlobal.h"
|
||
|
|
||
|
#ifdef _DEBUG
|
||
|
#define new DEBUG_NEW
|
||
|
#undef THIS_FILE
|
||
|
static char THIS_FILE[] = __FILE__;
|
||
|
#endif
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Global data:
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// New app verifier settings
|
||
|
//
|
||
|
|
||
|
CAVSettings g_NewSettings;
|
||
|
|
||
|
//
|
||
|
// Current settings bits - used as temporary variable
|
||
|
// to store custom settings bits between the settings bits
|
||
|
// page and the app selection page.
|
||
|
//
|
||
|
|
||
|
DWORD g_dwNewSettingBits;
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Changed settings? If yes, the program will exit with AV_EXIT_CODE_RESTART
|
||
|
//
|
||
|
|
||
|
BOOL g_bChangedSettings = FALSE;
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
CAppAndBitsArray g_aAppsAndBitsFromRegistry;
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Registry keys/values names
|
||
|
//
|
||
|
|
||
|
const TCHAR g_szImageOptionsKeyName[] = _T( "Software\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options" );
|
||
|
const TCHAR g_szGlobalFlagValueName[] = _T( "GlobalFlag" );
|
||
|
const TCHAR g_szVerifierFlagsValueName[] = _T( "VerifierFlags" );
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Bit names
|
||
|
//
|
||
|
|
||
|
BIT_LISTNAME_CMDLINESWITCH g_AllNamesAndBits[ 5 ] =
|
||
|
{
|
||
|
{
|
||
|
IDS_PAGEHEAP_CMD_LINE,
|
||
|
IDS_PAGE_HEAP,
|
||
|
RTL_VRF_FLG_FULL_PAGE_HEAP
|
||
|
},
|
||
|
{
|
||
|
IDS_LOCKS_CMD_LINE,
|
||
|
IDS_VERIFY_LOCKS_CHECKS,
|
||
|
RTL_VRF_FLG_LOCK_CHECKS
|
||
|
},
|
||
|
{
|
||
|
IDS_HANDLES_CMD_LINE,
|
||
|
IDS_VERIFY_HANDLE_CHECKS,
|
||
|
RTL_VRF_FLG_HANDLE_CHECKS
|
||
|
},
|
||
|
{
|
||
|
IDS_STACKS_CMD_LINE,
|
||
|
IDS_VERIFY_STACK_CHECKS,
|
||
|
RTL_VRF_FLG_STACK_CHECKS
|
||
|
},
|
||
|
{
|
||
|
IDS_APPCOMPAT_CMD_LINE,
|
||
|
IDS_VERIFY_APPCOMPAT_CHECKS,
|
||
|
RTL_VRF_FLG_APPCOMPAT_CHECKS
|
||
|
},
|
||
|
};
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// CApplicationData class
|
||
|
//
|
||
|
|
||
|
CApplicationData::CApplicationData( LPCTSTR szFileName,
|
||
|
LPCTSTR szFullPath,
|
||
|
ULONG uSettingsBits )
|
||
|
{
|
||
|
m_strExeFileName = szFileName;
|
||
|
m_uCustomFlags = uSettingsBits;
|
||
|
|
||
|
m_bSaved = FALSE;
|
||
|
|
||
|
LoadAppVersionData( szFullPath );
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// This version of the constructor will not try to load version info
|
||
|
//
|
||
|
|
||
|
CApplicationData::CApplicationData( LPCTSTR szFileName,
|
||
|
ULONG uSettingsBits )
|
||
|
{
|
||
|
ASSERT( FALSE != g_bCommandLineMode );
|
||
|
|
||
|
m_strExeFileName = szFileName;
|
||
|
m_uCustomFlags = uSettingsBits;
|
||
|
|
||
|
m_bSaved = FALSE;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
VOID CApplicationData::LoadAppVersionData( LPCTSTR szFileName )
|
||
|
{
|
||
|
BOOL bResult;
|
||
|
PVOID pWholeVerBlock;
|
||
|
PVOID pTranslationInfoBuffer;
|
||
|
LPCTSTR szVariableValue;
|
||
|
LPTSTR szAppFullPath;
|
||
|
DWORD dwWholeBlockSize;
|
||
|
DWORD dwDummyHandle;
|
||
|
UINT uInfoLengthInTChars;
|
||
|
TCHAR szLocale[ 32 ];
|
||
|
TCHAR szBlockName[ 64 ];
|
||
|
CString strAppFullPath;
|
||
|
|
||
|
bResult = FALSE;
|
||
|
|
||
|
//
|
||
|
// Get the size of the file info block
|
||
|
//
|
||
|
// GetFileVersionInfoSize doesn't know about
|
||
|
// const pointers so we need to GetBuffer here :-(
|
||
|
//
|
||
|
|
||
|
strAppFullPath = szFileName;
|
||
|
|
||
|
szAppFullPath = strAppFullPath.GetBuffer( strAppFullPath.GetLength() + 1 );
|
||
|
|
||
|
if( NULL == szAppFullPath )
|
||
|
{
|
||
|
goto InitializeWithDefaults;
|
||
|
}
|
||
|
|
||
|
dwWholeBlockSize = GetFileVersionInfoSize( szAppFullPath,
|
||
|
&dwDummyHandle );
|
||
|
|
||
|
strAppFullPath.ReleaseBuffer();
|
||
|
|
||
|
if( dwWholeBlockSize == 0 )
|
||
|
{
|
||
|
//
|
||
|
// Couldn't read version information
|
||
|
//
|
||
|
|
||
|
goto InitializeWithDefaults;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Allocate the buffer for the version information
|
||
|
//
|
||
|
|
||
|
pWholeVerBlock = malloc( dwWholeBlockSize );
|
||
|
|
||
|
if( pWholeVerBlock == NULL )
|
||
|
{
|
||
|
goto InitializeWithDefaults;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Get the version information
|
||
|
//
|
||
|
// GetFileVersionInfo doesn't know about
|
||
|
// const pointers so we need to GetBuffer here :-(
|
||
|
//
|
||
|
|
||
|
szAppFullPath = strAppFullPath.GetBuffer( strAppFullPath.GetLength() + 1 );
|
||
|
|
||
|
if( NULL == szAppFullPath )
|
||
|
{
|
||
|
free( pWholeVerBlock );
|
||
|
|
||
|
goto InitializeWithDefaults;
|
||
|
}
|
||
|
|
||
|
bResult = GetFileVersionInfo(
|
||
|
szAppFullPath,
|
||
|
dwDummyHandle,
|
||
|
dwWholeBlockSize,
|
||
|
pWholeVerBlock );
|
||
|
|
||
|
strAppFullPath.ReleaseBuffer();
|
||
|
|
||
|
if( bResult != TRUE )
|
||
|
{
|
||
|
free( pWholeVerBlock );
|
||
|
|
||
|
goto InitializeWithDefaults;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Get the locale info
|
||
|
//
|
||
|
|
||
|
bResult = VerQueryValue(
|
||
|
pWholeVerBlock,
|
||
|
_T( "\\VarFileInfo\\Translation" ),
|
||
|
&pTranslationInfoBuffer,
|
||
|
&uInfoLengthInTChars );
|
||
|
|
||
|
if( TRUE != bResult || NULL == pTranslationInfoBuffer )
|
||
|
{
|
||
|
free( pWholeVerBlock );
|
||
|
|
||
|
goto InitializeWithDefaults;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Locale info comes back as two little endian words.
|
||
|
// Flip 'em, 'cause we need them big endian for our calls.
|
||
|
//
|
||
|
|
||
|
_stprintf(
|
||
|
szLocale,
|
||
|
_T( "%02X%02X%02X%02X" ),
|
||
|
HIBYTE( LOWORD ( * (LPDWORD) pTranslationInfoBuffer) ),
|
||
|
LOBYTE( LOWORD ( * (LPDWORD) pTranslationInfoBuffer) ),
|
||
|
HIBYTE( HIWORD ( * (LPDWORD) pTranslationInfoBuffer) ),
|
||
|
LOBYTE( HIWORD ( * (LPDWORD) pTranslationInfoBuffer) ) );
|
||
|
|
||
|
//
|
||
|
// Get the file version
|
||
|
//
|
||
|
|
||
|
_stprintf(
|
||
|
szBlockName,
|
||
|
_T( "\\StringFileInfo\\%s\\FileVersion" ),
|
||
|
szLocale );
|
||
|
|
||
|
bResult = VerQueryValue(
|
||
|
pWholeVerBlock,
|
||
|
szBlockName,
|
||
|
(PVOID*) &szVariableValue,
|
||
|
&uInfoLengthInTChars );
|
||
|
|
||
|
if( TRUE != bResult || 0 == uInfoLengthInTChars )
|
||
|
{
|
||
|
//
|
||
|
// Couldn't find the version
|
||
|
//
|
||
|
|
||
|
VERIFY( m_strFileVersion.LoadString( IDS_UNKNOWN ) );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//
|
||
|
// Found the version
|
||
|
//
|
||
|
|
||
|
m_strFileVersion = szVariableValue;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Get the company name
|
||
|
//
|
||
|
|
||
|
_stprintf(
|
||
|
szBlockName,
|
||
|
_T( "\\StringFileInfo\\%s\\CompanyName" ),
|
||
|
szLocale );
|
||
|
|
||
|
bResult = VerQueryValue(
|
||
|
pWholeVerBlock,
|
||
|
szBlockName,
|
||
|
(PVOID*) &szVariableValue,
|
||
|
&uInfoLengthInTChars );
|
||
|
|
||
|
if( TRUE != bResult || uInfoLengthInTChars == 0 )
|
||
|
{
|
||
|
//
|
||
|
// Coudln't find the company name
|
||
|
//
|
||
|
|
||
|
m_strCompanyName.LoadString( IDS_UNKNOWN );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_strCompanyName = szVariableValue;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Get the ProductName
|
||
|
//
|
||
|
|
||
|
_stprintf(
|
||
|
szBlockName,
|
||
|
_T( "\\StringFileInfo\\%s\\ProductName" ),
|
||
|
szLocale );
|
||
|
|
||
|
bResult = VerQueryValue(
|
||
|
pWholeVerBlock,
|
||
|
szBlockName,
|
||
|
(PVOID*) &szVariableValue,
|
||
|
&uInfoLengthInTChars );
|
||
|
|
||
|
if( TRUE != bResult || uInfoLengthInTChars == 0 )
|
||
|
{
|
||
|
//
|
||
|
// Coudln't find the ProductName
|
||
|
//
|
||
|
|
||
|
m_strProductName.LoadString( IDS_UNKNOWN );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_strProductName = szVariableValue;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// clean-up
|
||
|
//
|
||
|
|
||
|
free( pWholeVerBlock );
|
||
|
|
||
|
goto Done;
|
||
|
|
||
|
InitializeWithDefaults:
|
||
|
|
||
|
m_strCompanyName.LoadString( IDS_UNKNOWN );
|
||
|
m_strFileVersion.LoadString( IDS_UNKNOWN );
|
||
|
m_strProductName.LoadString( IDS_UNKNOWN );
|
||
|
|
||
|
Done:
|
||
|
|
||
|
NOTHING;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// CApplicationDataArray class
|
||
|
//
|
||
|
|
||
|
CApplicationDataArray::~CApplicationDataArray()
|
||
|
{
|
||
|
DeleteAll();
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
CApplicationData *CApplicationDataArray::GetAt( INT_PTR nIndex )
|
||
|
{
|
||
|
CApplicationData *pRetValue = (CApplicationData *)CObArray::GetAt( nIndex );
|
||
|
|
||
|
ASSERT_VALID( pRetValue );
|
||
|
|
||
|
return pRetValue;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
VOID CApplicationDataArray::DeleteAll()
|
||
|
{
|
||
|
INT_PTR nArraySize;
|
||
|
CApplicationData *pCrtAppData;
|
||
|
|
||
|
nArraySize = GetSize();
|
||
|
|
||
|
while( nArraySize > 0 )
|
||
|
{
|
||
|
nArraySize -= 1;
|
||
|
|
||
|
pCrtAppData = GetAt( nArraySize );
|
||
|
|
||
|
ASSERT_VALID( pCrtAppData );
|
||
|
|
||
|
delete pCrtAppData;
|
||
|
}
|
||
|
|
||
|
RemoveAll();
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
VOID CApplicationDataArray::DeleteAt( INT_PTR nIndex )
|
||
|
{
|
||
|
CApplicationData *pCrtAppData;
|
||
|
|
||
|
pCrtAppData = GetAt( nIndex );
|
||
|
|
||
|
ASSERT_VALID( pCrtAppData );
|
||
|
|
||
|
delete pCrtAppData;
|
||
|
|
||
|
RemoveAt( nIndex );
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
BOOL CApplicationDataArray::IsFileNameInList( LPCTSTR szFileName )
|
||
|
{
|
||
|
INT_PTR nCrtElement;
|
||
|
INT_PTR nSize;
|
||
|
BOOL bFound;
|
||
|
CApplicationData *pCrtAppData;
|
||
|
|
||
|
bFound = FALSE;
|
||
|
|
||
|
nSize = GetSize();
|
||
|
|
||
|
for( nCrtElement = 0; nCrtElement < nSize; nCrtElement += 1 )
|
||
|
{
|
||
|
pCrtAppData = GetAt( nCrtElement );
|
||
|
|
||
|
ASSERT_VALID( pCrtAppData );
|
||
|
|
||
|
if( 0 == pCrtAppData->m_strExeFileName.CompareNoCase( szFileName ) )
|
||
|
{
|
||
|
bFound = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return bFound;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
INT_PTR CApplicationDataArray::FileNameIndex( LPCTSTR szFileName )
|
||
|
{
|
||
|
INT_PTR nCrtElement;
|
||
|
INT_PTR nSize;
|
||
|
BOOL bFound;
|
||
|
CApplicationData *pCrtAppData;
|
||
|
|
||
|
bFound = FALSE;
|
||
|
|
||
|
nSize = GetSize();
|
||
|
|
||
|
for( nCrtElement = 0; nCrtElement < nSize; nCrtElement += 1 )
|
||
|
{
|
||
|
pCrtAppData = GetAt( nCrtElement );
|
||
|
|
||
|
ASSERT_VALID( pCrtAppData );
|
||
|
|
||
|
if( 0 == pCrtAppData->m_strExeFileName.CompareNoCase( szFileName ) )
|
||
|
{
|
||
|
bFound = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if( FALSE == bFound )
|
||
|
{
|
||
|
nCrtElement = -1;
|
||
|
}
|
||
|
|
||
|
return nCrtElement;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
INT_PTR CApplicationDataArray::AddNewAppData( LPCTSTR szFileName,
|
||
|
LPCTSTR szFullPath,
|
||
|
ULONG uSettingsBits )
|
||
|
{
|
||
|
INT_PTR nIndexInArray;
|
||
|
CApplicationData *pNewAppData;
|
||
|
|
||
|
nIndexInArray = -1;
|
||
|
|
||
|
pNewAppData = new CApplicationData( szFileName,
|
||
|
szFullPath,
|
||
|
uSettingsBits );
|
||
|
|
||
|
if( NULL != pNewAppData )
|
||
|
{
|
||
|
nIndexInArray = Add( pNewAppData );
|
||
|
}
|
||
|
|
||
|
return nIndexInArray;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
INT_PTR CApplicationDataArray::AddNewAppDataConsoleMode( LPCTSTR szFileName,
|
||
|
ULONG uSettingsBits )
|
||
|
{
|
||
|
INT_PTR nIndexInArray;
|
||
|
CApplicationData *pNewAppData;
|
||
|
|
||
|
ASSERT( FALSE != g_bCommandLineMode );
|
||
|
|
||
|
nIndexInArray = -1;
|
||
|
|
||
|
//
|
||
|
// This version of the constructor will not try to load version info
|
||
|
//
|
||
|
|
||
|
pNewAppData = new CApplicationData( szFileName,
|
||
|
uSettingsBits );
|
||
|
|
||
|
if( NULL != pNewAppData )
|
||
|
{
|
||
|
nIndexInArray = Add( pNewAppData );
|
||
|
}
|
||
|
|
||
|
return nIndexInArray;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
VOID CApplicationDataArray::SetAllSaved( BOOL bSaved )
|
||
|
{
|
||
|
INT_PTR nCrtElement;
|
||
|
INT_PTR nSize;
|
||
|
CApplicationData *pCrtAppData;
|
||
|
|
||
|
nSize = GetSize();
|
||
|
|
||
|
for( nCrtElement = 0; nCrtElement < nSize; nCrtElement += 1 )
|
||
|
{
|
||
|
pCrtAppData = GetAt( nCrtElement );
|
||
|
|
||
|
ASSERT_VALID( pCrtAppData );
|
||
|
|
||
|
pCrtAppData->m_bSaved = bSaved;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// CAVSettings class
|
||
|
//
|
||
|
|
||
|
CAVSettings::CAVSettings()
|
||
|
{
|
||
|
m_SettingsType = AVSettingsTypeUnknown;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// CAppAndBits class
|
||
|
//
|
||
|
|
||
|
CAppAndBits::CAppAndBits( LPCTSTR szAppName, DWORD dwEnabledBits )
|
||
|
: m_strAppName( szAppName ),
|
||
|
m_dwEnabledBits( dwEnabledBits )
|
||
|
{
|
||
|
NOTHING;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// CAppAndBitsArray class
|
||
|
//
|
||
|
|
||
|
CAppAndBitsArray::~CAppAndBitsArray()
|
||
|
{
|
||
|
DeleteAll();
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
CAppAndBits *CAppAndBitsArray::GetAt( INT_PTR nIndex )
|
||
|
{
|
||
|
CAppAndBits *pRetValue = (CAppAndBits *)CObArray::GetAt( nIndex );
|
||
|
|
||
|
ASSERT_VALID( pRetValue );
|
||
|
|
||
|
return pRetValue;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
VOID CAppAndBitsArray::DeleteAll()
|
||
|
{
|
||
|
INT_PTR nArraySize;
|
||
|
CAppAndBits *pCrtElem;
|
||
|
|
||
|
nArraySize = GetSize();
|
||
|
|
||
|
while( nArraySize > 0 )
|
||
|
{
|
||
|
nArraySize -= 1;
|
||
|
|
||
|
pCrtElem = GetAt( nArraySize );
|
||
|
|
||
|
ASSERT_VALID( pCrtElem );
|
||
|
|
||
|
delete pCrtElem;
|
||
|
}
|
||
|
|
||
|
RemoveAll();
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Helper functions
|
||
|
//
|
||
|
|
||
|
BOOL AVSetVerifierFlags( HKEY hKey,
|
||
|
DWORD dwNewVerifierFlags,
|
||
|
BOOL bTryReadingOldValues,
|
||
|
BOOL *pbValuesChanged,
|
||
|
BOOL bDeleteOtherSettings )
|
||
|
{
|
||
|
BOOL bSuccess;
|
||
|
LONG lResult;
|
||
|
DWORD dwOldVerifierFlags;
|
||
|
DWORD dwDataSize;
|
||
|
DWORD dwType;
|
||
|
|
||
|
bSuccess = TRUE;
|
||
|
|
||
|
if( FALSE != bTryReadingOldValues )
|
||
|
{
|
||
|
//
|
||
|
// Read the existing app verifier flags
|
||
|
//
|
||
|
|
||
|
dwDataSize = sizeof( dwOldVerifierFlags );
|
||
|
|
||
|
lResult = RegQueryValueEx( hKey,
|
||
|
g_szVerifierFlagsValueName,
|
||
|
NULL,
|
||
|
&dwType,
|
||
|
(LPBYTE) &dwOldVerifierFlags,
|
||
|
&dwDataSize );
|
||
|
|
||
|
if( lResult != ERROR_SUCCESS )
|
||
|
{
|
||
|
switch( lResult )
|
||
|
{
|
||
|
case ERROR_FILE_NOT_FOUND:
|
||
|
//
|
||
|
// No VerifierFlags for this image currently
|
||
|
//
|
||
|
|
||
|
dwOldVerifierFlags = 0;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case ERROR_ACCESS_DENIED:
|
||
|
AVErrorResourceFormat( IDS_ACCESS_IS_DENIED );
|
||
|
|
||
|
bSuccess = FALSE;
|
||
|
|
||
|
goto Done;
|
||
|
|
||
|
default:
|
||
|
AVErrorResourceFormat( IDS_REGQUERYVALUEEX_FAILED,
|
||
|
g_szVerifierFlagsValueName,
|
||
|
(DWORD)lResult);
|
||
|
|
||
|
bSuccess = FALSE;
|
||
|
|
||
|
goto Done;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if( REG_DWORD != dwType )
|
||
|
{
|
||
|
AVErrorResourceFormat( IDS_INCORRECT_VALUE_TYPE,
|
||
|
g_szVerifierFlagsValueName,
|
||
|
dwType );
|
||
|
|
||
|
bSuccess = FALSE;
|
||
|
|
||
|
goto Done;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//
|
||
|
// We know this is a new regkey so we don't have any verifier flags yet
|
||
|
//
|
||
|
|
||
|
dwOldVerifierFlags = 0;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// New app verifier flags
|
||
|
//
|
||
|
|
||
|
if( dwNewVerifierFlags != dwOldVerifierFlags || dwNewVerifierFlags == 0 )
|
||
|
{
|
||
|
lResult = RegSetValueEx( hKey,
|
||
|
g_szVerifierFlagsValueName,
|
||
|
0,
|
||
|
REG_DWORD,
|
||
|
(PBYTE) &dwNewVerifierFlags,
|
||
|
sizeof( dwNewVerifierFlags ) );
|
||
|
|
||
|
if( lResult != ERROR_SUCCESS )
|
||
|
{
|
||
|
if( ERROR_ACCESS_DENIED == lResult )
|
||
|
{
|
||
|
AVErrorResourceFormat( IDS_ACCESS_IS_DENIED );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
AVErrorResourceFormat( IDS_REGSETVALUEEX_FAILED,
|
||
|
g_szVerifierFlagsValueName,
|
||
|
(DWORD)lResult);
|
||
|
}
|
||
|
|
||
|
bSuccess = FALSE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*pbValuesChanged = TRUE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Done:
|
||
|
return bSuccess;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
BOOL AVSetVerifierFlagsForExe( LPCTSTR szExeName,
|
||
|
DWORD dwNewVerifierFlags )
|
||
|
{
|
||
|
LONG lResult;
|
||
|
HKEY hImageOptionsKey = NULL, hSubKey = NULL;
|
||
|
BOOL bValuesChanged;
|
||
|
BOOL bSuccess;
|
||
|
DWORD dwValueType;
|
||
|
DWORD dwGlobalFlagValueBufferSize;
|
||
|
TCHAR szOldGlobalFlagValue[ 32 ];
|
||
|
|
||
|
//
|
||
|
// Open the Image File Execution Options regkey
|
||
|
//
|
||
|
|
||
|
lResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
|
||
|
g_szImageOptionsKeyName,
|
||
|
0,
|
||
|
KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS,
|
||
|
&hImageOptionsKey );
|
||
|
|
||
|
if( lResult != ERROR_SUCCESS )
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
lResult = RegCreateKeyEx( hImageOptionsKey,
|
||
|
szExeName,
|
||
|
0,
|
||
|
NULL,
|
||
|
REG_OPTION_NON_VOLATILE,
|
||
|
KEY_QUERY_VALUE | KEY_SET_VALUE,
|
||
|
NULL,
|
||
|
&hSubKey,
|
||
|
NULL );
|
||
|
|
||
|
if( lResult == ERROR_SUCCESS )
|
||
|
{
|
||
|
dwGlobalFlagValueBufferSize = sizeof( szOldGlobalFlagValue );
|
||
|
|
||
|
lResult = RegQueryValueEx( hSubKey,
|
||
|
g_szGlobalFlagValueName,
|
||
|
NULL,
|
||
|
&dwValueType,
|
||
|
(LPBYTE) &szOldGlobalFlagValue[ 0 ],
|
||
|
&dwGlobalFlagValueBufferSize );
|
||
|
|
||
|
if( lResult == ERROR_FILE_NOT_FOUND )
|
||
|
{
|
||
|
szOldGlobalFlagValue[ 0 ] = (TCHAR)0;
|
||
|
lResult = ERROR_SUCCESS;
|
||
|
}
|
||
|
|
||
|
if( lResult == ERROR_SUCCESS )
|
||
|
{
|
||
|
DWORD dwGlobalFlags;
|
||
|
BOOL bSuccesfullyConverted;
|
||
|
|
||
|
bSuccesfullyConverted = AVRtlCharToInteger( szOldGlobalFlagValue,
|
||
|
0,
|
||
|
&dwGlobalFlags );
|
||
|
|
||
|
if( !bSuccesfullyConverted )
|
||
|
{
|
||
|
dwGlobalFlags = 0;
|
||
|
}
|
||
|
|
||
|
if ( dwNewVerifierFlags == 0)
|
||
|
{
|
||
|
dwGlobalFlags &= ~FLG_APPLICATION_VERIFIER;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
dwGlobalFlags |= FLG_APPLICATION_VERIFIER;
|
||
|
}
|
||
|
|
||
|
bSuccess = AVWriteStringHexValueToRegistry( hSubKey,
|
||
|
g_szGlobalFlagValueName,
|
||
|
dwGlobalFlags );
|
||
|
|
||
|
bSuccess = bSuccess && AVSetVerifierFlags( hSubKey,
|
||
|
dwNewVerifierFlags,
|
||
|
FALSE,
|
||
|
&bValuesChanged,
|
||
|
TRUE );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( hSubKey != NULL )
|
||
|
{
|
||
|
VERIFY( ERROR_SUCCESS == RegCloseKey( hSubKey ) );
|
||
|
}
|
||
|
|
||
|
if ( hImageOptionsKey != NULL )
|
||
|
{
|
||
|
VERIFY( ERROR_SUCCESS == RegCloseKey( hImageOptionsKey ) );
|
||
|
}
|
||
|
|
||
|
return bSuccess;
|
||
|
}
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
BOOL AVCreateAppSettings( HKEY hKey,
|
||
|
BOOL bTryReadingOldValues,
|
||
|
LPCTSTR szOldGlobalFlagValue,
|
||
|
CApplicationData *pCrtAppData,
|
||
|
PBOOL pbValuesChanged,
|
||
|
CStringArray &astrAppCompatTestedExes,
|
||
|
BOOL bDeleteOtherSettings )
|
||
|
{
|
||
|
BOOL bSuccess;
|
||
|
BOOL bSuccesfullyConverted;
|
||
|
DWORD dwOldGlobalFlags;
|
||
|
DWORD dwNewGlobalFlags;
|
||
|
DWORD dwNewVerifierFlags;
|
||
|
|
||
|
bSuccess = TRUE;
|
||
|
|
||
|
*pbValuesChanged = FALSE;
|
||
|
|
||
|
if( NULL != pCrtAppData )
|
||
|
{
|
||
|
ASSERT_VALID( pCrtAppData );
|
||
|
}
|
||
|
|
||
|
if( FALSE != bTryReadingOldValues )
|
||
|
{
|
||
|
//
|
||
|
// Convert the REG_SZ GlobalFlag value to a DWORD
|
||
|
//
|
||
|
|
||
|
bSuccesfullyConverted = AVRtlCharToInteger( szOldGlobalFlagValue,
|
||
|
0,
|
||
|
&dwOldGlobalFlags );
|
||
|
|
||
|
if( FALSE == bSuccesfullyConverted )
|
||
|
{
|
||
|
dwOldGlobalFlags = 0;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//
|
||
|
// This is a new regkey so we know we don't have any GlobalFlag yet
|
||
|
//
|
||
|
|
||
|
dwOldGlobalFlags = 0;
|
||
|
}
|
||
|
|
||
|
if( 0 != (FLG_APPLICATION_VERIFIER & dwOldGlobalFlags) )
|
||
|
{
|
||
|
//
|
||
|
// This app used to have the verifier enabled
|
||
|
//
|
||
|
|
||
|
if( NULL == pCrtAppData ||
|
||
|
( AVSettingsTypeCustom == g_NewSettings.m_SettingsType &&
|
||
|
0 == pCrtAppData->m_uCustomFlags ) )
|
||
|
{
|
||
|
//
|
||
|
// The user didn't specify this app to verified
|
||
|
//
|
||
|
|
||
|
if( FALSE != bDeleteOtherSettings )
|
||
|
{
|
||
|
//
|
||
|
// This app will not have the verifier enabled from now on
|
||
|
//
|
||
|
|
||
|
dwNewGlobalFlags = dwOldGlobalFlags & ~FLG_APPLICATION_VERIFIER;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//
|
||
|
// Even if the user didn't specify this app
|
||
|
// she actually wants to keep the existing settings for this app.
|
||
|
//
|
||
|
|
||
|
goto Done;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//
|
||
|
// This app will continue to have the verifier enabled from now on.
|
||
|
// Set the new verifier flags though.
|
||
|
//
|
||
|
|
||
|
if( AVSettingsTypeStandard == g_NewSettings.m_SettingsType )
|
||
|
{
|
||
|
dwNewVerifierFlags = AV_ALL_STANDARD_VERIFIER_FLAGS;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
dwNewVerifierFlags = pCrtAppData->m_uCustomFlags;
|
||
|
}
|
||
|
|
||
|
bSuccess = AVSetVerifierFlags( hKey,
|
||
|
dwNewVerifierFlags,
|
||
|
bTryReadingOldValues,
|
||
|
pbValuesChanged,
|
||
|
bDeleteOtherSettings );
|
||
|
|
||
|
if( FALSE != bSuccess &&
|
||
|
( dwNewVerifierFlags & RTL_VRF_FLG_APPCOMPAT_CHECKS ) != 0 )
|
||
|
{
|
||
|
//
|
||
|
// This app has app compat checks enabled
|
||
|
//
|
||
|
|
||
|
astrAppCompatTestedExes.Add( pCrtAppData->m_strExeFileName );
|
||
|
}
|
||
|
|
||
|
goto Done;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//
|
||
|
// This app didn't have the app verifier enabled until now
|
||
|
//
|
||
|
|
||
|
if( NULL == pCrtAppData ||
|
||
|
( AVSettingsTypeCustom == g_NewSettings.m_SettingsType &&
|
||
|
0 == pCrtAppData->m_uCustomFlags ) )
|
||
|
{
|
||
|
//
|
||
|
// This app will NOT have the verifier enabled from now on.
|
||
|
// Nothing to change.
|
||
|
//
|
||
|
|
||
|
goto Done;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//
|
||
|
// This app will have the verifier enabled from now on.
|
||
|
//
|
||
|
|
||
|
dwNewGlobalFlags = dwOldGlobalFlags | FLG_APPLICATION_VERIFIER;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ASSERT( dwNewGlobalFlags != dwOldGlobalFlags );
|
||
|
|
||
|
//
|
||
|
// Write the new global flags for this app
|
||
|
//
|
||
|
|
||
|
bSuccess = AVWriteStringHexValueToRegistry( hKey,
|
||
|
g_szGlobalFlagValueName,
|
||
|
dwNewGlobalFlags );
|
||
|
if( FALSE != bSuccess )
|
||
|
{
|
||
|
*pbValuesChanged = TRUE;
|
||
|
|
||
|
//
|
||
|
// Set the new verifier flags
|
||
|
//
|
||
|
|
||
|
if( AVSettingsTypeStandard == g_NewSettings.m_SettingsType )
|
||
|
{
|
||
|
dwNewVerifierFlags = AV_ALL_STANDARD_VERIFIER_FLAGS;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if( NULL != pCrtAppData )
|
||
|
{
|
||
|
dwNewVerifierFlags = pCrtAppData->m_uCustomFlags;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
dwNewVerifierFlags = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bSuccess = AVSetVerifierFlags( hKey,
|
||
|
dwNewVerifierFlags,
|
||
|
bTryReadingOldValues,
|
||
|
pbValuesChanged,
|
||
|
bDeleteOtherSettings );
|
||
|
|
||
|
if( FALSE != bSuccess &&
|
||
|
NULL != pCrtAppData &&
|
||
|
( dwNewVerifierFlags & RTL_VRF_FLG_APPCOMPAT_CHECKS ) != 0 )
|
||
|
{
|
||
|
//
|
||
|
// This app has app compat checks enabled
|
||
|
//
|
||
|
|
||
|
astrAppCompatTestedExes.Add( pCrtAppData->m_strExeFileName );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
Done:
|
||
|
|
||
|
return bSuccess;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Save the new app verifier settings for one image
|
||
|
//
|
||
|
|
||
|
BOOL AVSaveAppNewSettings( HKEY hKey,
|
||
|
BOOL bTryReadingOldValues,
|
||
|
LPCTSTR szAppName,
|
||
|
PBOOL pbAnythingChanged,
|
||
|
CStringArray &astrAppCompatTestedExes,
|
||
|
BOOL bDeleteOtherSettings )
|
||
|
{
|
||
|
BOOL bSuccess;
|
||
|
BOOL bValuesChanged;
|
||
|
INT_PTR nIndexInArray;
|
||
|
LONG lResult;
|
||
|
DWORD dwGlobalFlagValueBufferSize;
|
||
|
DWORD dwValueType;
|
||
|
CApplicationData *pCrtAppData;
|
||
|
TCHAR szOldGlobalFlagValue[ 32 ];
|
||
|
|
||
|
bSuccess = TRUE;
|
||
|
|
||
|
if( FALSE != bTryReadingOldValues )
|
||
|
{
|
||
|
//
|
||
|
// See if the app verifier flag is currently enabled for this app
|
||
|
//
|
||
|
|
||
|
dwGlobalFlagValueBufferSize = sizeof( szOldGlobalFlagValue );
|
||
|
|
||
|
lResult = RegQueryValueEx( hKey,
|
||
|
g_szGlobalFlagValueName,
|
||
|
NULL,
|
||
|
&dwValueType,
|
||
|
(LPBYTE) &szOldGlobalFlagValue[ 0 ],
|
||
|
&dwGlobalFlagValueBufferSize );
|
||
|
|
||
|
if( lResult != ERROR_SUCCESS )
|
||
|
{
|
||
|
switch( lResult )
|
||
|
{
|
||
|
case ERROR_FILE_NOT_FOUND:
|
||
|
//
|
||
|
// No GlobalFlag for this image currently
|
||
|
//
|
||
|
|
||
|
szOldGlobalFlagValue[ 0 ] = (TCHAR)0;
|
||
|
break;
|
||
|
|
||
|
case ERROR_ACCESS_DENIED:
|
||
|
AVErrorResourceFormat( IDS_ACCESS_IS_DENIED );
|
||
|
|
||
|
bSuccess = FALSE;
|
||
|
|
||
|
goto Done;
|
||
|
|
||
|
default:
|
||
|
AVErrorResourceFormat( IDS_REGQUERYVALUEEX_FAILED,
|
||
|
g_szGlobalFlagValueName,
|
||
|
(DWORD)lResult);
|
||
|
|
||
|
bSuccess = FALSE;
|
||
|
|
||
|
goto Done;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if( REG_SZ != dwValueType )
|
||
|
{
|
||
|
AVErrorResourceFormat( IDS_INCORRECT_VALUE_TYPE,
|
||
|
g_szGlobalFlagValueName,
|
||
|
dwValueType );
|
||
|
|
||
|
bSuccess = FALSE;
|
||
|
|
||
|
goto Done;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//
|
||
|
// This is a new subkey so we don't have any GlobalFlag yet
|
||
|
//
|
||
|
|
||
|
szOldGlobalFlagValue[ 0 ] = (TCHAR)0;
|
||
|
}
|
||
|
|
||
|
nIndexInArray = g_NewSettings.m_aApplicationData.FileNameIndex( szAppName );
|
||
|
|
||
|
if( nIndexInArray >= 0 )
|
||
|
{
|
||
|
//
|
||
|
// This app will be verified from now on.
|
||
|
//
|
||
|
|
||
|
pCrtAppData = g_NewSettings.m_aApplicationData.GetAt( nIndexInArray );
|
||
|
|
||
|
ASSERT_VALID( pCrtAppData );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//
|
||
|
// This app will not be verified from now on.
|
||
|
//
|
||
|
|
||
|
pCrtAppData = NULL;
|
||
|
}
|
||
|
|
||
|
bSuccess = AVCreateAppSettings( hKey,
|
||
|
bTryReadingOldValues,
|
||
|
szOldGlobalFlagValue,
|
||
|
pCrtAppData,
|
||
|
&bValuesChanged,
|
||
|
astrAppCompatTestedExes,
|
||
|
bDeleteOtherSettings );
|
||
|
|
||
|
if( FALSE != bSuccess )
|
||
|
{
|
||
|
if( NULL != pCrtAppData )
|
||
|
{
|
||
|
pCrtAppData->m_bSaved = TRUE;
|
||
|
}
|
||
|
|
||
|
*pbAnythingChanged = *pbAnythingChanged || bValuesChanged;
|
||
|
}
|
||
|
|
||
|
Done:
|
||
|
|
||
|
return bSuccess;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Save the new app verifier settings for all images
|
||
|
//
|
||
|
|
||
|
BOOL AVSaveNewSettings( BOOL bDeleteOtherSettings /*= TRUE*/ )
|
||
|
{
|
||
|
BOOL bSuccess;
|
||
|
LONG lResult;
|
||
|
DWORD dwSubkeyIndex;
|
||
|
DWORD dwKeyNameBufferLen;
|
||
|
HKEY hImageOptionsKey;
|
||
|
HKEY hSubKey;
|
||
|
INT_PTR nAppsToVerify;
|
||
|
INT_PTR nCrtAppToVerify;
|
||
|
FILETIME LastWriteTime;
|
||
|
CApplicationData *pCrtAppData;
|
||
|
CStringArray astrAppCompatTestedExes;
|
||
|
TCHAR szKeyNameBuffer[ 256 ];
|
||
|
|
||
|
g_bChangedSettings = FALSE;
|
||
|
|
||
|
bSuccess = FALSE;
|
||
|
|
||
|
g_NewSettings.m_aApplicationData.SetAllSaved( FALSE );
|
||
|
|
||
|
//
|
||
|
// Open the Image File Execution Options regkey
|
||
|
//
|
||
|
|
||
|
lResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
|
||
|
g_szImageOptionsKeyName,
|
||
|
0,
|
||
|
KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS,
|
||
|
&hImageOptionsKey );
|
||
|
|
||
|
if( lResult != ERROR_SUCCESS )
|
||
|
{
|
||
|
if( lResult == ERROR_ACCESS_DENIED )
|
||
|
{
|
||
|
AVErrorResourceFormat(
|
||
|
IDS_ACCESS_IS_DENIED );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
AVErrorResourceFormat(
|
||
|
IDS_REGOPENKEYEX_FAILED,
|
||
|
g_szImageOptionsKeyName,
|
||
|
(DWORD)lResult);
|
||
|
}
|
||
|
|
||
|
goto Done;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Enumerate all the existing subkeys for app execution options
|
||
|
//
|
||
|
|
||
|
for( dwSubkeyIndex = 0; TRUE; dwSubkeyIndex += 1 )
|
||
|
{
|
||
|
dwKeyNameBufferLen = ARRAY_LENGTH( szKeyNameBuffer );
|
||
|
|
||
|
lResult = RegEnumKeyEx( hImageOptionsKey,
|
||
|
dwSubkeyIndex,
|
||
|
szKeyNameBuffer,
|
||
|
&dwKeyNameBufferLen,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
&LastWriteTime );
|
||
|
|
||
|
if( lResult != ERROR_SUCCESS )
|
||
|
{
|
||
|
if( lResult == ERROR_NO_MORE_ITEMS )
|
||
|
{
|
||
|
//
|
||
|
// We finished looking at all the existing subkeys
|
||
|
//
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if( lResult == ERROR_ACCESS_DENIED )
|
||
|
{
|
||
|
AVErrorResourceFormat(
|
||
|
IDS_ACCESS_IS_DENIED );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
AVErrorResourceFormat(
|
||
|
IDS_REGENUMKEYEX_FAILED,
|
||
|
g_szImageOptionsKeyName,
|
||
|
(DWORD)lResult);
|
||
|
}
|
||
|
|
||
|
goto CleanUpAndDone;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Open the subkey
|
||
|
//
|
||
|
|
||
|
lResult = RegOpenKeyEx( hImageOptionsKey,
|
||
|
szKeyNameBuffer,
|
||
|
0,
|
||
|
KEY_QUERY_VALUE | KEY_SET_VALUE,
|
||
|
&hSubKey );
|
||
|
|
||
|
if( lResult != ERROR_SUCCESS )
|
||
|
{
|
||
|
if( lResult == ERROR_ACCESS_DENIED )
|
||
|
{
|
||
|
AVErrorResourceFormat(
|
||
|
IDS_ACCESS_IS_DENIED );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
AVErrorResourceFormat(
|
||
|
IDS_REGOPENKEYEX_FAILED,
|
||
|
szKeyNameBuffer,
|
||
|
(DWORD)lResult);
|
||
|
}
|
||
|
|
||
|
goto CleanUpAndDone;
|
||
|
}
|
||
|
|
||
|
bSuccess = AVSaveAppNewSettings( hSubKey,
|
||
|
TRUE,
|
||
|
szKeyNameBuffer,
|
||
|
&g_bChangedSettings,
|
||
|
astrAppCompatTestedExes,
|
||
|
bDeleteOtherSettings ) ;
|
||
|
|
||
|
VERIFY( ERROR_SUCCESS == RegCloseKey( hSubKey ) );
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Add any new image execution options keys necessary
|
||
|
//
|
||
|
|
||
|
nAppsToVerify = g_NewSettings.m_aApplicationData.GetSize();
|
||
|
|
||
|
for( nCrtAppToVerify = 0; nCrtAppToVerify < nAppsToVerify; nCrtAppToVerify += 1 )
|
||
|
{
|
||
|
pCrtAppData = g_NewSettings.m_aApplicationData.GetAt( nCrtAppToVerify );
|
||
|
|
||
|
ASSERT_VALID( pCrtAppData );
|
||
|
|
||
|
if( FALSE == pCrtAppData->m_bSaved )
|
||
|
{
|
||
|
lResult = RegCreateKeyEx( hImageOptionsKey,
|
||
|
(LPCTSTR) pCrtAppData->m_strExeFileName,
|
||
|
0,
|
||
|
NULL,
|
||
|
REG_OPTION_NON_VOLATILE,
|
||
|
KEY_QUERY_VALUE | KEY_SET_VALUE,
|
||
|
NULL,
|
||
|
&hSubKey,
|
||
|
NULL );
|
||
|
|
||
|
if( STATUS_SUCCESS != lResult )
|
||
|
{
|
||
|
if( lResult == ERROR_ACCESS_DENIED )
|
||
|
{
|
||
|
AVErrorResourceFormat(
|
||
|
IDS_ACCESS_IS_DENIED );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
AVErrorResourceFormat(
|
||
|
IDS_REGCREATEKEYEX_FAILED,
|
||
|
(LPCTSTR) pCrtAppData->m_strExeFileName,
|
||
|
(DWORD)lResult);
|
||
|
}
|
||
|
|
||
|
goto CleanUpAndDone;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Create the app verifier settings for this app
|
||
|
//
|
||
|
|
||
|
bSuccess = AVSaveAppNewSettings( hSubKey,
|
||
|
FALSE,
|
||
|
(LPCTSTR) pCrtAppData->m_strExeFileName,
|
||
|
&g_bChangedSettings,
|
||
|
astrAppCompatTestedExes,
|
||
|
FALSE ) ;
|
||
|
|
||
|
VERIFY( ERROR_SUCCESS == RegCloseKey( hSubKey ) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Update the app compat settings
|
||
|
//
|
||
|
|
||
|
if( FALSE != bSuccess && FALSE != g_bChangedSettings )
|
||
|
{
|
||
|
AppCompatSaveSettings( astrAppCompatTestedExes );
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Let the user know if we have changed any settings
|
||
|
//
|
||
|
|
||
|
if( FALSE != g_bChangedSettings )
|
||
|
{
|
||
|
if( 0 < nAppsToVerify )
|
||
|
{
|
||
|
AVMesssageFromResource( IDS_SETTINGS_SAVED );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
AVMesssageFromResource( IDS_SETTINGS_DELETED );
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
AVMesssageFromResource( IDS_NO_SETTINGS_CHANGED );
|
||
|
}
|
||
|
|
||
|
CleanUpAndDone:
|
||
|
|
||
|
VERIFY( ERROR_SUCCESS == RegCloseKey( hImageOptionsKey ) );
|
||
|
|
||
|
Done:
|
||
|
|
||
|
return bSuccess;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Dump the current registry settings to the console
|
||
|
//
|
||
|
|
||
|
VOID AVDumpRegistrySettingsToConsole()
|
||
|
{
|
||
|
INT_PTR nCrtFlag;
|
||
|
INT_PTR nAppsNo;
|
||
|
INT_PTR nCrtApp;
|
||
|
BOOL bDisplayedThisApp;
|
||
|
CAppAndBits *pCrtElem;
|
||
|
TCHAR szBitName[ 64 ];
|
||
|
|
||
|
//
|
||
|
// Read the current registry settings
|
||
|
//
|
||
|
|
||
|
AVReadCrtRegistrySettings();
|
||
|
|
||
|
nAppsNo = g_aAppsAndBitsFromRegistry.GetSize();
|
||
|
|
||
|
if( nAppsNo > 0 )
|
||
|
{
|
||
|
AVPrintStringFromResources( IDS_VERIFIED_APPS );
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Parse all the elements and print out the enabled flags
|
||
|
//
|
||
|
|
||
|
for( nCrtApp = 0; nCrtApp < nAppsNo; nCrtApp += 1 )
|
||
|
{
|
||
|
pCrtElem = g_aAppsAndBitsFromRegistry.GetAt( nCrtApp );
|
||
|
|
||
|
ASSERT_VALID( pCrtElem );
|
||
|
ASSERT( 0 != pCrtElem->m_dwEnabledBits );
|
||
|
|
||
|
bDisplayedThisApp = FALSE;
|
||
|
|
||
|
for( nCrtFlag = 0; nCrtFlag < ARRAY_LENGTH( g_AllNamesAndBits ); nCrtFlag += 1 )
|
||
|
{
|
||
|
if( (pCrtElem->m_dwEnabledBits & g_AllNamesAndBits[ nCrtFlag ].m_dwBit) != 0 )
|
||
|
{
|
||
|
//
|
||
|
// This verifier bit is enabled.
|
||
|
// Display the app name, if not displayed already, then the bit name.
|
||
|
//
|
||
|
|
||
|
if( FALSE == bDisplayedThisApp )
|
||
|
{
|
||
|
_putts( _T( " " ) );
|
||
|
_putts( (LPCTSTR)pCrtElem->m_strAppName );
|
||
|
_putts( _T( " " ) );
|
||
|
AVPrintStringFromResources( IDS_TESTS );
|
||
|
_putts( _T( " " ) );
|
||
|
|
||
|
bDisplayedThisApp = TRUE;
|
||
|
}
|
||
|
|
||
|
VERIFY( AVLoadString( g_AllNamesAndBits[ nCrtFlag ].m_uNameStringId,
|
||
|
szBitName,
|
||
|
ARRAY_LENGTH( szBitName ) ) );
|
||
|
|
||
|
_putts( szBitName );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
_putts( _T( " " ) );
|
||
|
}
|
||
|
|
||
|
if( nAppsNo == 0 )
|
||
|
{
|
||
|
AVPrintStringFromResources( IDS_NO_APPS_VERIFIED );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Read the current registry settings
|
||
|
//
|
||
|
|
||
|
VOID AVReadCrtRegistrySettings()
|
||
|
{
|
||
|
HKEY hImageOptionsKey;
|
||
|
HKEY hSubKey;
|
||
|
DWORD dwSubkeyIndex;
|
||
|
DWORD dwDataSize;
|
||
|
DWORD dwValueType;
|
||
|
DWORD dwFlags;
|
||
|
LONG lResult;
|
||
|
BOOL bSuccesfullyConverted;
|
||
|
FILETIME LastWriteTime;
|
||
|
CAppAndBits *pNewElem;
|
||
|
TCHAR szOldGlobalFlagValue[ 32 ];
|
||
|
TCHAR szKeyNameBuffer[ 256 ];
|
||
|
|
||
|
g_aAppsAndBitsFromRegistry.DeleteAll();
|
||
|
|
||
|
//
|
||
|
// Open the Image File Execution Options regkey
|
||
|
//
|
||
|
|
||
|
lResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
|
||
|
g_szImageOptionsKeyName,
|
||
|
0,
|
||
|
KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS,
|
||
|
&hImageOptionsKey );
|
||
|
|
||
|
if( lResult != ERROR_SUCCESS )
|
||
|
{
|
||
|
if( lResult == ERROR_ACCESS_DENIED )
|
||
|
{
|
||
|
AVErrorResourceFormat(
|
||
|
IDS_ACCESS_IS_DENIED );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
AVErrorResourceFormat(
|
||
|
IDS_REGOPENKEYEX_FAILED,
|
||
|
g_szImageOptionsKeyName,
|
||
|
(DWORD)lResult);
|
||
|
}
|
||
|
|
||
|
goto Done;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Enumerate all the existing subkeys for app execution options
|
||
|
//
|
||
|
|
||
|
for( dwSubkeyIndex = 0; TRUE; dwSubkeyIndex += 1 )
|
||
|
{
|
||
|
dwDataSize = ARRAY_LENGTH( szKeyNameBuffer );
|
||
|
|
||
|
lResult = RegEnumKeyEx( hImageOptionsKey,
|
||
|
dwSubkeyIndex,
|
||
|
szKeyNameBuffer,
|
||
|
&dwDataSize,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
&LastWriteTime );
|
||
|
|
||
|
if( lResult != ERROR_SUCCESS )
|
||
|
{
|
||
|
if( lResult == ERROR_NO_MORE_ITEMS )
|
||
|
{
|
||
|
//
|
||
|
// We finished looking at all the existing subkeys
|
||
|
//
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if( lResult == ERROR_ACCESS_DENIED )
|
||
|
{
|
||
|
AVErrorResourceFormat(
|
||
|
IDS_ACCESS_IS_DENIED );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
AVErrorResourceFormat(
|
||
|
IDS_REGENUMKEYEX_FAILED,
|
||
|
g_szImageOptionsKeyName,
|
||
|
(DWORD)lResult);
|
||
|
}
|
||
|
|
||
|
goto CleanUpAndDone;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Open the subkey
|
||
|
//
|
||
|
|
||
|
lResult = RegOpenKeyEx( hImageOptionsKey,
|
||
|
szKeyNameBuffer,
|
||
|
0,
|
||
|
KEY_QUERY_VALUE | KEY_SET_VALUE,
|
||
|
&hSubKey );
|
||
|
|
||
|
if( lResult != ERROR_SUCCESS )
|
||
|
{
|
||
|
if( lResult == ERROR_ACCESS_DENIED )
|
||
|
{
|
||
|
AVErrorResourceFormat(
|
||
|
IDS_ACCESS_IS_DENIED );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
AVErrorResourceFormat(
|
||
|
IDS_REGOPENKEYEX_FAILED,
|
||
|
szKeyNameBuffer,
|
||
|
(DWORD)lResult);
|
||
|
}
|
||
|
|
||
|
goto CleanUpAndDone;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Read the GlobalFlag value
|
||
|
//
|
||
|
|
||
|
dwDataSize = sizeof( szOldGlobalFlagValue );
|
||
|
|
||
|
lResult = RegQueryValueEx( hSubKey,
|
||
|
g_szGlobalFlagValueName,
|
||
|
NULL,
|
||
|
&dwValueType,
|
||
|
(LPBYTE) &szOldGlobalFlagValue[ 0 ],
|
||
|
&dwDataSize );
|
||
|
|
||
|
if( ERROR_SUCCESS == lResult )
|
||
|
{
|
||
|
bSuccesfullyConverted = AVRtlCharToInteger( szOldGlobalFlagValue,
|
||
|
0,
|
||
|
&dwFlags );
|
||
|
|
||
|
if( ( FALSE != bSuccesfullyConverted ) &&
|
||
|
( ( dwFlags & FLG_APPLICATION_VERIFIER ) != 0 ) )
|
||
|
{
|
||
|
//
|
||
|
// App verifier is enabled for this app - read the verifier flags
|
||
|
//
|
||
|
|
||
|
dwDataSize = sizeof( dwFlags );
|
||
|
|
||
|
lResult = RegQueryValueEx( hSubKey,
|
||
|
g_szVerifierFlagsValueName,
|
||
|
NULL,
|
||
|
&dwValueType,
|
||
|
(LPBYTE) &dwFlags,
|
||
|
&dwDataSize );
|
||
|
|
||
|
if( ERROR_SUCCESS == lResult && REG_DWORD == dwValueType && 0 != dwFlags )
|
||
|
{
|
||
|
//
|
||
|
// Add this app top our global array
|
||
|
//
|
||
|
|
||
|
pNewElem = new CAppAndBits( szKeyNameBuffer,
|
||
|
dwFlags );
|
||
|
|
||
|
if( NULL != pNewElem )
|
||
|
{
|
||
|
g_aAppsAndBitsFromRegistry.Add( pNewElem );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
VERIFY( ERROR_SUCCESS == RegCloseKey( hSubKey ) );
|
||
|
}
|
||
|
|
||
|
CleanUpAndDone:
|
||
|
|
||
|
VERIFY( ERROR_SUCCESS == RegCloseKey( hImageOptionsKey ) );
|
||
|
|
||
|
Done:
|
||
|
|
||
|
NOTHING;
|
||
|
}
|