|
|
//
// Driver Verifier UI
// Copyright (c) Microsoft Corporation, 1999
//
//
//
// module: VrfUtil.cpp
// author: DMihai
// created: 11/1/00
//
// Description
//
#include "stdafx.h"
#include "verifier.h"
#include "vrfutil.h"
#include "vglobal.h"
#include "VSetting.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__; #endif
//
// Global data
//
const TCHAR RegMemoryManagementKeyName[] = _T( "System\\CurrentControlSet\\Control\\Session Manager\\Memory Management" );
const TCHAR RegVerifyDriverLevelValueName[] = _T( "VerifyDriverLevel" );
const TCHAR RegVerifyDriversValueName[] = _T( "VerifyDrivers" );
///////////////////////////////////////////////////////////////////////////
//
// Report an error using a dialog box or a console message.
// The message format string is loaded from the resources.
//
void __cdecl VrfErrorResourceFormat( UINT uIdResourceFormat, ... ) { TCHAR szMessage[ 256 ]; TCHAR strFormat[ 256 ]; BOOL bResult; va_list prms;
//
// Load the format string from the resources
//
bResult = VrfLoadString( uIdResourceFormat, strFormat, ARRAY_LENGTH( strFormat ) );
ASSERT( bResult );
if( bResult ) { va_start (prms, uIdResourceFormat);
//
// Format the message in our local buffer
//
_vsntprintf ( szMessage, ARRAY_LENGTH( szMessage ), strFormat, prms);
if( g_bCommandLineMode ) { //
// Command console mode
//
_putts( szMessage ); TRACE( _T( "%s\n" ), szMessage ); } else { //
// GUI mode
//
AfxMessageBox( szMessage, MB_OK | MB_ICONSTOP ); }
va_end (prms); } }
///////////////////////////////////////////////////////////////////////////
//
// Print out a message to the console
// The message string is loaded from the resources.
//
void __cdecl VrfTPrintfResourceFormat( UINT uIdResourceFormat, ... ) { TCHAR szMessage[ 256 ]; TCHAR strFormat[ 256 ]; BOOL bResult; va_list prms;
ASSERT( g_bCommandLineMode );
//
// Load the format string from the resources
//
bResult = VrfLoadString( uIdResourceFormat, strFormat, ARRAY_LENGTH( strFormat ) );
ASSERT( bResult );
if( bResult ) { va_start (prms, uIdResourceFormat);
//
// Format the message in our local buffer
//
_vsntprintf ( szMessage, ARRAY_LENGTH( szMessage ), strFormat, prms);
_putts( szMessage );
va_end (prms); } }
///////////////////////////////////////////////////////////////////////////
//
// Print out a simple (non-formatted) message to the console
// The message string is loaded from the resources.
//
void __cdecl VrfPrintStringFromResources( UINT uIdString ) { TCHAR szMessage[ 256 ];
ASSERT( g_bCommandLineMode );
VERIFY( VrfLoadString( uIdString, szMessage, ARRAY_LENGTH( szMessage ) ) );
_putts( szMessage ); }
///////////////////////////////////////////////////////////////////////////
//
// Report an error using a dialog box or a console message.
// The message string is loaded from the resources.
//
void __cdecl VrfMesssageFromResource( UINT uIdString ) { TCHAR szMessage[ 256 ];
VERIFY( VrfLoadString( uIdString, szMessage, ARRAY_LENGTH( szMessage ) ) );
if( g_bCommandLineMode ) { //
// Command console mode
//
_putts( szMessage ); } else { //
// GUI mode
//
AfxMessageBox( szMessage, MB_OK | MB_ICONINFORMATION ); } }
///////////////////////////////////////////////////////////////////////////
//
// Load a string from resources.
// Return TRUE if we successfully loaded and FALSE if not.
//
BOOL VrfLoadString( ULONG uIdResource, TCHAR *szBuffer, ULONG uBufferLength ) { ULONG uLoadStringResult;
if( uBufferLength < 1 ) { ASSERT( FALSE ); return FALSE; }
uLoadStringResult = LoadString ( g_hProgramModule, uIdResource, szBuffer, uBufferLength );
//
// We should never try to load non-existent strings.
//
ASSERT (uLoadStringResult > 0);
return (uLoadStringResult > 0); }
///////////////////////////////////////////////////////////////////////////
//
// Load a string from resources.
// Return TRUE if we successfully loaded and FALSE if not.
//
BOOL VrfLoadString( ULONG uIdResource, CString &strText ) { TCHAR szText[ 256 ]; BOOL bSuccess;
bSuccess = VrfLoadString( uIdResource, szText, ARRAY_LENGTH( szText ) );
if( TRUE == bSuccess ) { strText = szText; } else { strText = ""; }
return bSuccess; }
///////////////////////////////////////////////////////////////////////////
VOID CopyStringArray( const CStringArray &strArraySource, CStringArray &strArrayDest ) { INT_PTR nNewSize; INT_PTR nCrtElem;
strArrayDest.RemoveAll();
nNewSize = strArraySource.GetSize();
for( nCrtElem = 0; nCrtElem < nNewSize; nCrtElem += 1 ) { strArrayDest.Add( strArraySource.GetAt( nCrtElem ) ); } }
/////////////////////////////////////////////////////////////////////////////
//
// Copied from sdktools\bvtsigvf
//
BOOL VerifyIsFileSigned( LPCTSTR pcszMatchFile, PDRIVER_VER_INFO lpVerInfo) { HRESULT hRes; WINTRUST_DATA WinTrustData; WINTRUST_FILE_INFO WinTrustFile; GUID gOSVerCheck = DRIVER_ACTION_VERIFY; GUID gPublishedSoftware = WINTRUST_ACTION_GENERIC_VERIFY_V2; #ifndef UNICODE
INT iRet; WCHAR wszFileName[MAX_PATH]; #endif
ZeroMemory(&WinTrustData, sizeof(WINTRUST_DATA)); WinTrustData.cbStruct = sizeof(WINTRUST_DATA); WinTrustData.dwUIChoice = WTD_UI_NONE; WinTrustData.fdwRevocationChecks = WTD_REVOKE_NONE; WinTrustData.dwUnionChoice = WTD_CHOICE_FILE; WinTrustData.dwStateAction = WTD_STATEACTION_AUTO_CACHE; WinTrustData.pFile = &WinTrustFile; WinTrustData.pPolicyCallbackData = (LPVOID)lpVerInfo; ZeroMemory(lpVerInfo, sizeof(DRIVER_VER_INFO)); lpVerInfo->cbStruct = sizeof(DRIVER_VER_INFO);
ZeroMemory(&WinTrustFile, sizeof(WINTRUST_FILE_INFO)); WinTrustFile.cbStruct = sizeof(WINTRUST_FILE_INFO);
#ifndef UNICODE
iRet = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pcszMatchFile, -1, wszFileName, ARRAY_LENGTH(wszFileName)); WinTrustFile.pcwszFilePath = wszFileName; #else
WinTrustFile.pcwszFilePath = pcszMatchFile; #endif
hRes = WinVerifyTrust( AfxGetMainWnd()->m_hWnd, &gOSVerCheck, &WinTrustData); if (hRes != ERROR_SUCCESS) hRes = WinVerifyTrust( AfxGetMainWnd()->m_hWnd, &gPublishedSoftware, &WinTrustData);
//
// Free the pcSignerCertContext member of the DRIVER_VER_INFO struct
// that was allocated in our call to WinVerifyTrust.
//
if (lpVerInfo && lpVerInfo->pcSignerCertContext) {
CertFreeCertificateContext(lpVerInfo->pcSignerCertContext); lpVerInfo->pcSignerCertContext = NULL; }
return (hRes == ERROR_SUCCESS); }
#define HASH_SIZE 100
BOOL IsDriverSigned( LPCTSTR szDriverFileName ) { HANDLE hFile; BOOL bSigned; BOOL bSuccess; HRESULT hTrustResult; DWORD dwHashSize; GUID guidSubSystemDriver = DRIVER_ACTION_VERIFY; HCATINFO hCatInfo; HCATINFO hPrevCatInfo; BYTE Hash[ HASH_SIZE ]; WINTRUST_DATA WinTrustData; DRIVER_VER_INFO VerInfo; WINTRUST_CATALOG_INFO WinTrustCatalogInfo; CATALOG_INFO CatInfo;
#ifndef UNICODE
WCHAR szUnicodeFileName[MAX_PATH]; #endif
ASSERT( NULL != szDriverFileName );
bSigned = FALSE;
//
// Open the file
//
hFile = CreateFile( szDriverFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if( hFile == INVALID_HANDLE_VALUE ) { //
// ISSUE:
//
// If we cannot find the file we assume it's signed
//
bSigned = TRUE;
goto Done; }
//
// Generate the hash from the file handle and store it in Hash
//
dwHashSize = ARRAY_LENGTH( Hash );
ZeroMemory( Hash, sizeof( Hash ) );
bSuccess = CryptCATAdminCalcHashFromFileHandle( hFile, &dwHashSize, Hash, 0);
CloseHandle( hFile );
if( TRUE != bSuccess ) { //
// If we couldn't generate a hash assume the file is not signed
//
goto Done; }
//
// Now we have the file's hash. Initialize the structures that
// will be used later on in calls to WinVerifyTrust.
//
//
// Initialize the VerInfo structure
//
ZeroMemory( &VerInfo, sizeof( VerInfo ) );
VerInfo.cbStruct = sizeof( VerInfo );
//
// Initialize the WinTrustCatalogInfo structure
//
ZeroMemory( &WinTrustCatalogInfo, sizeof( WinTrustCatalogInfo ) );
WinTrustCatalogInfo.cbStruct = sizeof(WinTrustCatalogInfo); WinTrustCatalogInfo.pbCalculatedFileHash = Hash; WinTrustCatalogInfo.cbCalculatedFileHash = dwHashSize;
#ifdef UNICODE
WinTrustCatalogInfo.pcwszMemberTag = szDriverFileName;
#else
MultiByteToWideChar( CP_ACP, 0, szDriverFileName, -1, szUnicodeFileName, ARRAY_LENGTH( szUnicodeFileName ) );
WinTrustCatalogInfo.pcwszMemberTag = szUnicodeFileName;
#endif
//
// Initialize the WinTrustData structure
//
ZeroMemory( &WinTrustData, sizeof( WinTrustData ) ); WinTrustData.cbStruct = sizeof( WinTrustData ); WinTrustData.dwUIChoice = WTD_UI_NONE; WinTrustData.fdwRevocationChecks = WTD_REVOKE_NONE; WinTrustData.dwUnionChoice = WTD_CHOICE_CATALOG; WinTrustData.dwStateAction = WTD_STATEACTION_AUTO_CACHE; WinTrustData.pPolicyCallbackData = (LPVOID)&VerInfo; WinTrustData.pCatalog = &WinTrustCatalogInfo;
//
// If we don't have a g_hCatAdmin yet, acquire one
//
if( NULL == g_hCatAdmin ) { CryptCATAdminAcquireContext( &g_hCatAdmin, NULL, 0);
if( NULL == g_hCatAdmin ) { //
// Bad luck - consider that the file is not signed and bail out
//
goto Done; } } //
// Now we try to find the file hash in the catalog list, via CryptCATAdminEnumCatalogFromHash
//
hPrevCatInfo = NULL; hCatInfo = CryptCATAdminEnumCatalogFromHash( g_hCatAdmin, Hash, dwHashSize, 0, &hPrevCatInfo );
while( TRUE != bSigned && NULL != hCatInfo ) { ZeroMemory( &CatInfo, sizeof( CatInfo ) ); CatInfo.cbStruct = sizeof( CatInfo );
bSuccess = CryptCATCatalogInfoFromContext( hCatInfo, &CatInfo, 0);
if( FALSE != bSuccess ) { WinTrustCatalogInfo.pcwszCatalogFilePath = CatInfo.wszCatalogFile;
//
// Now verify that the file is an actual member of the catalog.
//
hTrustResult = WinVerifyTrust( AfxGetMainWnd()->m_hWnd, &guidSubSystemDriver, &WinTrustData );
bSigned = SUCCEEDED( hTrustResult );
//
// Free the pcSignerCertContext member of the DRIVER_VER_INFO struct
// that was allocated in our call to WinVerifyTrust.
//
if( VerInfo.pcSignerCertContext != NULL ) { CertFreeCertificateContext( VerInfo.pcSignerCertContext ); VerInfo.pcSignerCertContext = NULL; } }
if( TRUE != bSigned ) { //
// The hash was in this catalog, but the file wasn't a member... so off to the next catalog
//
hPrevCatInfo = hCatInfo;
hCatInfo = CryptCATAdminEnumCatalogFromHash( g_hCatAdmin, Hash, dwHashSize, 0, &hPrevCatInfo ); } }
if( NULL == hCatInfo ) { //
// If it wasn't found in the catalogs, check if the file is individually signed.
//
bSigned = VerifyIsFileSigned( szDriverFileName, &VerInfo ); }
Done:
return bSigned; }
/////////////////////////////////////////////////////////////////////////////
BOOL VrfSetWindowText( CWnd &Wnd, ULONG uIdResourceString ) { BOOL bLoaded; CString strText;
//
// It's safe to use CString::LoadString here because we are
// in GUI mode
//
ASSERT( FALSE == g_bCommandLineMode );
bLoaded = strText.LoadString( uIdResourceString );
ASSERT( TRUE == bLoaded );
Wnd.SetWindowText( strText );
return ( TRUE == bLoaded ); }
/////////////////////////////////////////////////////////////////////////////
BOOL VrfWriteVerifierSettings( BOOL bHaveNewDrivers, const CString &strDriversToVerify, BOOL bHaveNewFlags, DWORD dwVerifyFlags ) { HKEY hMmKey = NULL; LONG lResult; BOOL bSuccess;
ASSERT( bHaveNewDrivers || bHaveNewFlags );
bSuccess = FALSE;
if( bHaveNewDrivers && strDriversToVerify.GetLength() == 0 ) { //
// No drivers to verify
//
ASSERT( FALSE && "VrfDeleteAllVerifierSettings should have been called for this" );
return VrfDeleteAllVerifierSettings(); }
if( bHaveNewFlags ) { TRACE( _T( "VrfWriteVerifierSettings: New verifier flags = %#x\n" ), dwVerifyFlags ); } if( bHaveNewDrivers ) { TRACE( _T( "VrfWriteVerifierSettings: New drivers = %s\n" ), (LPCTSTR) strDriversToVerify ); }
//
// Open the Mm key
//
lResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE, RegMemoryManagementKeyName, 0, KEY_SET_VALUE, &hMmKey );
if( lResult != ERROR_SUCCESS ) { if( lResult == ERROR_ACCESS_DENIED ) { VrfErrorResourceFormat( IDS_ACCESS_IS_DENIED ); } else { VrfErrorResourceFormat( IDS_REGOPENKEYEX_FAILED, RegMemoryManagementKeyName, (DWORD)lResult); }
goto Done; }
if( bHaveNewFlags ) { //
// Write VerifyDriverLevel value
//
if( VrfWriteRegistryDwordValue( hMmKey, RegVerifyDriverLevelValueName, dwVerifyFlags ) == FALSE ) { RegCloseKey (hMmKey);
goto Done; } }
if( bHaveNewDrivers ) { //
// Write VerifyDrivers value
//
if( VrfWriteRegistryStringValue( hMmKey, RegVerifyDriversValueName, strDriversToVerify ) == FALSE ) { RegCloseKey (hMmKey); goto Done; } }
//
// Close the Mm key and return success
//
RegCloseKey( hMmKey );
bSuccess = TRUE;
if( bSuccess ) { if( g_bSettingsSaved ) { VrfMesssageFromResource( IDS_REBOOT ); } else { VrfMesssageFromResource( IDS_NO_SETTINGS_WERE_CHANGED ); } }
Done: return TRUE; }
/////////////////////////////////////////////////////////////////////////////
BOOL VrfWriteRegistryDwordValue( HKEY hKey, LPCTSTR szValueName, DWORD dwValue ) { LONG lResult; BOOL bSuccess;
lResult = RegSetValueEx( hKey, szValueName, 0, REG_DWORD, ( LPBYTE ) &dwValue, sizeof( dwValue ) );
bSuccess = ( lResult == ERROR_SUCCESS );
g_bSettingsSaved = g_bSettingsSaved | bSuccess;
if( TRUE != bSuccess ) { VrfErrorResourceFormat( IDS_REGSETVALUEEX_FAILED, szValueName, (DWORD) lResult ); }
return bSuccess; }
/////////////////////////////////////////////////////////////////////////////
BOOL VrfWriteRegistryStringValue( HKEY hKey, LPCTSTR szValueName, LPCTSTR szValue ) { BOOL bSuccess; LONG lResult;
lResult = RegSetValueEx ( hKey, szValueName, 0, REG_SZ, (LPBYTE) szValue, ( _tcslen( szValue ) + 1 ) * sizeof (TCHAR) );
bSuccess = ( lResult == ERROR_SUCCESS );
g_bSettingsSaved = g_bSettingsSaved | bSuccess;
if( TRUE != bSuccess ) { VrfErrorResourceFormat( IDS_REGSETVALUEEX_FAILED, szValueName, (DWORD) lResult); }
return bSuccess; }
/////////////////////////////////////////////////////////////////////////////
BOOL VrfReadVerifierSettings( CString &strDriversToVerify, DWORD &dwVerifyFlags ) { HKEY hMmKey = NULL; LONG lResult; BOOL bSuccess;
bSuccess = FALSE;
//
// Open the Mm key
//
lResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE, RegMemoryManagementKeyName, 0, KEY_QUERY_VALUE, &hMmKey );
if( lResult != ERROR_SUCCESS ) { if( lResult == ERROR_ACCESS_DENIED ) { VrfErrorResourceFormat( IDS_ACCESS_IS_DENIED ); } else { VrfErrorResourceFormat( IDS_REGOPENKEYEX_FAILED, RegMemoryManagementKeyName, (DWORD)lResult); }
goto Done; }
//
// Read VerifyDriverLevel value
//
if( VrfReadRegistryDwordValue( hMmKey, RegVerifyDriverLevelValueName, dwVerifyFlags ) == FALSE ) { RegCloseKey (hMmKey);
goto Done; }
//
// Read VerifyDrivers value
//
if( VrfReadRegistryStringValue( hMmKey, RegVerifyDriversValueName, strDriversToVerify ) == FALSE ) { RegCloseKey (hMmKey); goto Done; }
//
// Close the Mm key and return success
//
RegCloseKey( hMmKey );
bSuccess = TRUE;
Done: return TRUE; }
/////////////////////////////////////////////////////////////////////////////
BOOL VrtLoadCurrentRegistrySettings( BOOL &bAllDriversVerified, CStringArray &astrDriversToVerify, DWORD &dwVerifyFlags ) { BOOL bResult; CString strDriversToVerify;
astrDriversToVerify.RemoveAll(); dwVerifyFlags = 0; bAllDriversVerified = FALSE;
bResult = VrfReadVerifierSettings( strDriversToVerify, dwVerifyFlags );
strDriversToVerify.TrimLeft(); strDriversToVerify.TrimRight();
if( strDriversToVerify.CompareNoCase( _T( "*" ) ) == 0 ) { bAllDriversVerified = TRUE; } else { VrfSplitDriverNamesSpaceSeparated( strDriversToVerify, astrDriversToVerify ); }
return bResult; }
/////////////////////////////////////////////////////////////////////////////
VOID VrfSplitDriverNamesSpaceSeparated( CString strAllDrivers, CStringArray &astrVerifyDriverNames ) { INT nCharIndex; CString strCrtDriverName;
astrVerifyDriverNames.RemoveAll();
//
// Split the space separated driver names in astrDriversToVerify
//
strAllDrivers.TrimRight();
while( TRUE ) { strAllDrivers.TrimLeft();
if( strAllDrivers.GetLength() == 0 ) { //
// We are done parsing the whole string
//
break; }
//
// Look for a space or a tab
//
nCharIndex = strAllDrivers.Find( _T( ' ' ) );
if( nCharIndex < 0 ) { nCharIndex = strAllDrivers.Find( _T( '\t' ) ); }
if( nCharIndex >= 0 ) { //
// Found a separator character
//
strCrtDriverName = strAllDrivers.Left( nCharIndex );
if( strCrtDriverName.GetLength() > 0 && FALSE == VrfIsStringInArray( strCrtDriverName, astrVerifyDriverNames ) ) { astrVerifyDriverNames.Add( strCrtDriverName ); }
strAllDrivers = strAllDrivers.Right( strAllDrivers.GetLength() - nCharIndex - 1 ); } else { //
// This is the last driver name
//
if( FALSE == VrfIsStringInArray( strAllDrivers, astrVerifyDriverNames ) ) { astrVerifyDriverNames.Add( strAllDrivers ); }
break; } } }
/////////////////////////////////////////////////////////////////////////////
BOOL VrfIsDriversSetDifferent( CString strAllDrivers1, const CStringArray &astrVerifyDriverNames2 ) { BOOL bDifferent; INT_PTR nDriverNames1; INT_PTR nDriverNames2; INT_PTR nCrtDriver1; INT_PTR nCrtDriver2; CString strDriver1; CString strDriver2; CStringArray astrVerifyDriverNames1;
bDifferent = TRUE;
VrfSplitDriverNamesSpaceSeparated( strAllDrivers1, astrVerifyDriverNames1 );
nDriverNames1 = astrVerifyDriverNames1.GetSize(); nDriverNames2 = astrVerifyDriverNames2.GetSize();
if( nDriverNames1 == nDriverNames2 ) { //
// Same number of drivers
//
bDifferent = FALSE;
for( nCrtDriver1 = 0; nCrtDriver1 < nDriverNames1; nCrtDriver1 += 1 ) { strDriver1 = astrVerifyDriverNames1.GetAt( nCrtDriver1 );
bDifferent = TRUE;
//
// Look for strDriver1 in astrVerifyDriverNames2
//
for( nCrtDriver2 = 0; nCrtDriver2 < nDriverNames2; nCrtDriver2 += 1 ) { strDriver2 = astrVerifyDriverNames2.GetAt( nCrtDriver2 );
if( strDriver1.CompareNoCase( strDriver2 ) == 0 ) { bDifferent = FALSE;
break; } }
if( TRUE == bDifferent ) { //
// Did not find strDriver1 in astrVerifyDriverNames2
//
break; } } }
return bDifferent; }
/////////////////////////////////////////////////////////////////////////////
BOOL VrfReadRegistryDwordValue( HKEY hKey, LPCTSTR szValueName, DWORD &dwValue ) { LONG lResult; BOOL bSuccess; DWORD dwType; DWORD dwDataSize;
dwDataSize = sizeof( dwValue );
lResult = RegQueryValueEx( hKey, szValueName, 0, &dwType, ( LPBYTE ) &dwValue, &dwDataSize );
if( lResult == ERROR_FILE_NOT_FOUND ) { //
// The value doesn't currently exist
//
dwValue = 0; bSuccess = TRUE; } else { bSuccess = ( ERROR_SUCCESS == lResult && REG_DWORD == dwType && dwDataSize == sizeof( dwValue ) ); }
if( TRUE != bSuccess ) { VrfErrorResourceFormat( IDS_REGQUERYVALUEEX_FAILED, szValueName, (DWORD) lResult ); }
return bSuccess; }
/////////////////////////////////////////////////////////////////////////////
BOOL VrfReadRegistryStringValue( HKEY hKey, LPCTSTR szValueName, CString &strDriversToVerify ) { BOOL bSuccess; LONG lResult; LPTSTR szDriversToVerify; ULONG uRegKeyLength; DWORD dwType; DWORD dwDataSize;
bSuccess = FALSE; lResult = ERROR_NOT_ENOUGH_MEMORY; szDriversToVerify = NULL;
for( uRegKeyLength = 128; uRegKeyLength < 4096; uRegKeyLength += 128 ) { //
// Try allocate a local buffer and use it to query
//
szDriversToVerify = new TCHAR[ uRegKeyLength ];
if( NULL != szDriversToVerify ) { dwDataSize = uRegKeyLength * sizeof (TCHAR);
lResult = RegQueryValueEx( hKey, szValueName, 0, &dwType, (LPBYTE) szDriversToVerify, &dwDataSize );
switch( lResult ) { case ERROR_FILE_NOT_FOUND: //
// Return an empty string
//
szDriversToVerify[ 0 ] = (TCHAR)0;
bSuccess = TRUE; break;
case ERROR_SUCCESS: //
// Got the driver names from the registry
//
bSuccess = ( REG_SZ == dwType );
break;
default: //
// Try with a bigger buffer
//
break; }
}
if( FALSE != bSuccess ) { //
// Got what we needed
//
break; } else { //
// Delete the current buffer and try with a bigger one
//
ASSERT( NULL != szDriversToVerify );
strDriversToVerify = szDriversToVerify;
delete [] szDriversToVerify; szDriversToVerify = NULL; } }
if( TRUE != bSuccess ) { VrfErrorResourceFormat( IDS_REGSETVALUEEX_FAILED, szValueName, (DWORD) lResult); } else { ASSERT( NULL != szDriversToVerify );
strDriversToVerify = szDriversToVerify;
delete [] szDriversToVerify; szDriversToVerify = NULL; }
return bSuccess; }
/////////////////////////////////////////////////////////////////////////////
BOOL VrfDeleteAllVerifierSettings() { HKEY hMmKey = NULL; LONG lResult; BOOL bSuccess;
bSuccess = FALSE;
//
// Open the Mm key
//
lResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE, RegMemoryManagementKeyName, 0, KEY_SET_VALUE, &hMmKey );
if( lResult != ERROR_SUCCESS ) { if( lResult == ERROR_ACCESS_DENIED ) { VrfErrorResourceFormat( IDS_ACCESS_IS_DENIED ); } else { VrfErrorResourceFormat( IDS_REGOPENKEYEX_FAILED, RegMemoryManagementKeyName, (DWORD)lResult); }
goto Done; }
//
// Delete VerifyDriverLevel value
//
lResult = RegDeleteValue( hMmKey, RegVerifyDriverLevelValueName );
if( lResult != ERROR_SUCCESS && lResult != ERROR_FILE_NOT_FOUND ) { VrfErrorResourceFormat( IDS_REGDELETEVALUE_FAILED, RegVerifyDriverLevelValueName, (DWORD) lResult );
goto Done; }
g_bSettingsSaved = g_bSettingsSaved | ( lResult != ERROR_FILE_NOT_FOUND );
//
// Delete VerifyDrivers value
//
lResult = RegDeleteValue( hMmKey, RegVerifyDriversValueName ); if( lResult != ERROR_SUCCESS && lResult != ERROR_FILE_NOT_FOUND ) { VrfErrorResourceFormat( IDS_REGDELETEVALUE_FAILED, RegVerifyDriversValueName, (DWORD) lResult );
RegCloseKey (hMmKey); goto Done; }
g_bSettingsSaved = g_bSettingsSaved | ( lResult != ERROR_FILE_NOT_FOUND );
//
// Close the Mm key and return success
//
RegCloseKey( hMmKey );
bSuccess = TRUE;
if( bSuccess && g_bSettingsSaved ) { VrfMesssageFromResource( IDS_REBOOT ); } else { VrfMesssageFromResource( IDS_NO_SETTINGS_WERE_CHANGED ); }
Done: return bSuccess; }
/////////////////////////////////////////////////////////////////////////////
BOOL VrfGetRuntimeVerifierData( CRuntimeVerifierData *pRuntimeVerifierData ) { NTSTATUS Status; ULONG Length = 0; ULONG buffersize; BOOL bSuccess; PSYSTEM_VERIFIER_INFORMATION VerifierInfo; PSYSTEM_VERIFIER_INFORMATION VerifierInfoBase; CRuntimeDriverData *pCrtDriverData; LPTSTR szName;
ASSERT_VALID( pRuntimeVerifierData );
pRuntimeVerifierData->FillWithDefaults();
pRuntimeVerifierData->m_RuntimeDriverDataArray.DeleteAll();
bSuccess = FALSE;
//
// Try to get the right size for the NtQuery buffer
//
buffersize = 1024;
do { VerifierInfo = (PSYSTEM_VERIFIER_INFORMATION)malloc (buffersize); if (VerifierInfo == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; break; }
Status = NtQuerySystemInformation (SystemVerifierInformation, VerifierInfo, buffersize, &Length);
if (Status != STATUS_INFO_LENGTH_MISMATCH) { break; }
free (VerifierInfo); buffersize += 1024;
} while (1);
if (! NT_SUCCESS(Status)) { VrfErrorResourceFormat( IDS_QUERY_SYSINFO_FAILED, Status);
goto Done; }
//
// If no info fill out return success but no info.
//
if (Length == 0) { free (VerifierInfo); bSuccess = TRUE;
goto Done; }
//
// Fill out the cumulative-driver stuff.
//
VerifierInfoBase = VerifierInfo;
pRuntimeVerifierData->m_bSpecialPool = (VerifierInfo->Level & DRIVER_VERIFIER_SPECIAL_POOLING) ? TRUE : FALSE; pRuntimeVerifierData->m_bForceIrql = (VerifierInfo->Level & DRIVER_VERIFIER_FORCE_IRQL_CHECKING) ? TRUE : FALSE; pRuntimeVerifierData->m_bLowRes = (VerifierInfo->Level & DRIVER_VERIFIER_INJECT_ALLOCATION_FAILURES) ? TRUE : FALSE; pRuntimeVerifierData->m_bPoolTracking = (VerifierInfo->Level & DRIVER_VERIFIER_TRACK_POOL_ALLOCATIONS) ? TRUE : FALSE; pRuntimeVerifierData->m_bIo = (VerifierInfo->Level & DRIVER_VERIFIER_IO_CHECKING) ? TRUE : FALSE; pRuntimeVerifierData->m_bDeadlockDetect = (VerifierInfo->Level & DRIVER_VERIFIER_DEADLOCK_DETECTION) ? TRUE : FALSE; pRuntimeVerifierData->m_bDMAVerif = (VerifierInfo->Level & DRIVER_VERIFIER_DMA_VERIFIER) ? TRUE : FALSE; pRuntimeVerifierData->m_bEnhIo = (VerifierInfo->Level & DRIVER_VERIFIER_ENHANCED_IO_CHECKING) ? TRUE : FALSE;
pRuntimeVerifierData->RaiseIrqls = VerifierInfo->RaiseIrqls; pRuntimeVerifierData->AcquireSpinLocks = VerifierInfo->AcquireSpinLocks; pRuntimeVerifierData->SynchronizeExecutions = VerifierInfo->SynchronizeExecutions; pRuntimeVerifierData->AllocationsAttempted = VerifierInfo->AllocationsAttempted; pRuntimeVerifierData->AllocationsSucceeded = VerifierInfo->AllocationsSucceeded; pRuntimeVerifierData->AllocationsSucceededSpecialPool = VerifierInfo->AllocationsSucceededSpecialPool; pRuntimeVerifierData->AllocationsWithNoTag = VerifierInfo->AllocationsWithNoTag;
pRuntimeVerifierData->Trims = VerifierInfo->Trims; pRuntimeVerifierData->AllocationsFailed = VerifierInfo->AllocationsFailed; pRuntimeVerifierData->AllocationsFailedDeliberately = VerifierInfo->AllocationsFailedDeliberately;
pRuntimeVerifierData->UnTrackedPool = VerifierInfo->UnTrackedPool; pRuntimeVerifierData->Level = VerifierInfo->Level;
//
// Fill out the per-driver stuff.
//
VerifierInfo = VerifierInfoBase;
do { //
// Allocate a new driver data structure
//
pCrtDriverData = new CRuntimeDriverData; if( NULL == pCrtDriverData ) { VrfErrorResourceFormat( IDS_NOT_ENOUGH_MEMORY );
break; }
#ifndef UNICODE
ANSI_STRING Name; NTSTATUS Status;
Status = RtlUnicodeStringToAnsiString ( & Name, & VerifierInfo->DriverName, TRUE);
if (! (NT_SUCCESS(Status) ) ) { VrfErrorResourceFormat( IDS_NOT_ENOUGH_MEMORY );
break; }
szName = pCrtDriverData->m_strName.GetBuffer( Name.Length + 1 );
if( NULL != szName ) { CopyMemory( szName, Name.Buffer, ( Name.Length + 1 ) * sizeof( Name.Buffer[ 0 ] ) );
szName[ Name.Length ] = 0;
pCrtDriverData->m_strName.ReleaseBuffer(); }
RtlFreeAnsiString (& Name);
#else
szName = pCrtDriverData->m_strName.GetBuffer( VerifierInfo->DriverName.Length + 1 );
if( NULL != szName ) { CopyMemory( szName, VerifierInfo->DriverName.Buffer, ( VerifierInfo->DriverName.Length + 1 ) * sizeof( VerifierInfo->DriverName.Buffer[ 0 ] ) );
szName[ VerifierInfo->DriverName.Length ] = 0; pCrtDriverData->m_strName.ReleaseBuffer(); }
#endif //#ifndef UNICODE
if( FALSE != pRuntimeVerifierData->IsDriverVerified( pCrtDriverData->m_strName ) ) { //
// This is a duplicate entry - ignore it.
//
delete pCrtDriverData; } else { pCrtDriverData->Loads = VerifierInfo->Loads; pCrtDriverData->Unloads = VerifierInfo->Unloads;
pCrtDriverData->CurrentPagedPoolAllocations = VerifierInfo->CurrentPagedPoolAllocations; pCrtDriverData->CurrentNonPagedPoolAllocations = VerifierInfo->CurrentNonPagedPoolAllocations; pCrtDriverData->PeakPagedPoolAllocations = VerifierInfo->PeakPagedPoolAllocations; pCrtDriverData->PeakNonPagedPoolAllocations = VerifierInfo->PeakNonPagedPoolAllocations;
pCrtDriverData->PagedPoolUsageInBytes = VerifierInfo->PagedPoolUsageInBytes; pCrtDriverData->NonPagedPoolUsageInBytes = VerifierInfo->NonPagedPoolUsageInBytes; pCrtDriverData->PeakPagedPoolUsageInBytes = VerifierInfo->PeakPagedPoolUsageInBytes; pCrtDriverData->PeakNonPagedPoolUsageInBytes = VerifierInfo->PeakNonPagedPoolUsageInBytes;
pRuntimeVerifierData->m_RuntimeDriverDataArray.Add( pCrtDriverData ); }
if (VerifierInfo->NextEntryOffset == 0) { break; }
VerifierInfo = (PSYSTEM_VERIFIER_INFORMATION)((PCHAR)VerifierInfo + VerifierInfo->NextEntryOffset);
} while (1);
free (VerifierInfoBase);
Done: return TRUE;
}
/////////////////////////////////////////////////////////////////////
PLOADED_IMAGE VrfImageLoad( LPTSTR szBinaryName, LPTSTR szDirectory ) { #ifdef UNICODE
char *szOemImageName; char *szOemDirectory; int nStringLength; PLOADED_IMAGE pLoadedImage;
pLoadedImage = NULL; nStringLength = wcslen( szBinaryName );
szOemImageName = new char [ nStringLength + 1 ]; if( NULL != szOemImageName ) { CharToOem( szBinaryName, szOemImageName );
if( NULL == szDirectory ) { szOemDirectory = NULL; } else { nStringLength = wcslen( szDirectory ); szOemDirectory = new char [ nStringLength + 1 ];
CharToOem( szDirectory, szOemDirectory ); }
pLoadedImage = ImageLoad( szOemImageName, szOemDirectory );
if( NULL != szOemDirectory ) { delete [] szOemDirectory; }
delete [] szOemImageName; }
return pLoadedImage;
#else
//
// Already have ANSI strings
//
return ImageLoad( szBinaryName, szDirectory );
#endif //#ifdef UNICODE
}
/////////////////////////////////////////////////////////////////////////////
BOOL VrfDumpStateToFile( FILE *file ) { BOOL bSuccess; INT_PTR nDriversNo; INT_PTR nCrtDriver; SYSTEMTIME SystemTime; TCHAR strLocalTime[ 64 ]; TCHAR strLocalDate[ 64 ]; CRuntimeDriverData *pRunDriverData; CRuntimeVerifierData RunTimeVerifierData;
//
// Output the date&time in the current user format
//
GetLocalTime( &SystemTime );
if( GetDateFormat( LOCALE_USER_DEFAULT, 0, &SystemTime, NULL, strLocalDate, ARRAY_LENGTH( strLocalDate ) ) ) { VrfFTPrintf( file, _T( "%s, " ), strLocalDate ); } else { ASSERT( FALSE ); }
if( GetTimeFormat( LOCALE_USER_DEFAULT, 0, &SystemTime, NULL, strLocalTime, ARRAY_LENGTH( strLocalTime ) ) ) { VrfFTPrintf( file, _T( "%s\n" ), strLocalTime); } else { ASSERT( FALSE );
VrfFTPrintf( file, _T( "\n" ) ); }
//
// Get the current verifier statistics
//
if( VrfGetRuntimeVerifierData( &RunTimeVerifierData ) == FALSE) {
VrfOuputStringFromResources( IDS_CANTGET_VERIF_STATE, file );
bSuccess = FALSE; goto Done; }
nDriversNo = RunTimeVerifierData.m_RuntimeDriverDataArray.GetSize();
if( 0 == nDriversNo ) { //
// no statistics to dump
//
bSuccess = VrfOuputStringFromResources( IDS_NO_DRIVER_VERIFIED, file ); } else { //
// dump the counters
//
//
// global counters
//
if( ( ! VrfFTPrintfResourceFormat( file, IDS_LEVEL, RunTimeVerifierData.Level ) ) || ( ! VrfFTPrintfResourceFormat( file, IDS_RAISEIRQLS, RunTimeVerifierData.RaiseIrqls ) ) || ( ! VrfFTPrintfResourceFormat( file, IDS_ACQUIRESPINLOCKS, RunTimeVerifierData.AcquireSpinLocks ) ) || ( ! VrfFTPrintfResourceFormat( file, IDS_SYNCHRONIZEEXECUTIONS, RunTimeVerifierData.SynchronizeExecutions) ) ||
( ! VrfFTPrintfResourceFormat( file, IDS_ALLOCATIONSATTEMPTED, RunTimeVerifierData.AllocationsAttempted) ) || ( ! VrfFTPrintfResourceFormat( file, IDS_ALLOCATIONSSUCCEEDED, RunTimeVerifierData.AllocationsSucceeded) ) || ( ! VrfFTPrintfResourceFormat( file, IDS_ALLOCATIONSSUCCEEDEDSPECIALPOOL, RunTimeVerifierData.AllocationsSucceededSpecialPool) ) || ( ! VrfFTPrintfResourceFormat( file, IDS_ALLOCATIONSWITHNOTAG, RunTimeVerifierData.AllocationsWithNoTag) ) ||
( ! VrfFTPrintfResourceFormat( file, IDS_ALLOCATIONSFAILED, RunTimeVerifierData.AllocationsFailed) ) || ( ! VrfFTPrintfResourceFormat( file, IDS_ALLOCATIONSFAILEDDELIBERATELY, RunTimeVerifierData.AllocationsFailedDeliberately) ) ||
( ! VrfFTPrintfResourceFormat( file, IDS_TRIMS, RunTimeVerifierData.Trims) ) ||
( ! VrfFTPrintfResourceFormat( file, IDS_UNTRACKEDPOOL, RunTimeVerifierData.UnTrackedPool) ) ) {
bSuccess = FALSE;
goto Done; }
//
// per driver counters
//
if( ! VrfOuputStringFromResources( IDS_THE_VERIFIED_DRIVERS, file ) ) { bSuccess = FALSE;
goto Done; }
for( nCrtDriver = 0; nCrtDriver < nDriversNo; nCrtDriver += 1 ) { VrfFTPrintf( file, _T( "\n" ) );
pRunDriverData = RunTimeVerifierData.m_RuntimeDriverDataArray.GetAt( nCrtDriver ) ;
ASSERT_VALID( pRunDriverData );
if( VrfFTPrintfResourceFormat( file, IDS_NAME_LOADS_UNLOADS, (LPCTSTR)pRunDriverData->m_strName, pRunDriverData->Loads, pRunDriverData->Unloads) == FALSE ) { bSuccess = FALSE;
goto Done; }
//
// pool statistics
//
if( ( ! VrfFTPrintfResourceFormat( file, IDS_CURRENTPAGEDPOOLALLOCATIONS, pRunDriverData->CurrentPagedPoolAllocations) ) || ( ! VrfFTPrintfResourceFormat( file, IDS_CURRENTNONPAGEDPOOLALLOCATIONS, pRunDriverData->CurrentNonPagedPoolAllocations) ) || ( ! VrfFTPrintfResourceFormat( file, IDS_PEAKPAGEDPOOLALLOCATIONS, pRunDriverData->PeakPagedPoolAllocations) ) || ( ! VrfFTPrintfResourceFormat( file, IDS_PEAKNONPAGEDPOOLALLOCATIONS, pRunDriverData->PeakNonPagedPoolAllocations) ) ||
( ! VrfFTPrintfResourceFormat( file, IDS_PAGEDPOOLUSAGEINBYTES, (ULONG) pRunDriverData->PagedPoolUsageInBytes) ) || ( ! VrfFTPrintfResourceFormat( file, IDS_NONPAGEDPOOLUSAGEINBYTES, (ULONG) pRunDriverData->NonPagedPoolUsageInBytes) ) || ( ! VrfFTPrintfResourceFormat( file, IDS_PEAKPAGEDPOOLUSAGEINBYTES, (ULONG) pRunDriverData->PeakPagedPoolUsageInBytes) ) || ( ! VrfFTPrintfResourceFormat( file, IDS_PEAKNONPAGEDPOOLUSAGEINBYTES, (ULONG) pRunDriverData->PeakNonPagedPoolUsageInBytes) ) ) { bSuccess = FALSE;
goto Done; } } }
Done:
return bSuccess; }
/////////////////////////////////////////////////////////////////////////////
BOOL __cdecl VrfFTPrintf( FILE *file, LPCTSTR szFormat, ... ) { TCHAR szMessage[ 256 ]; BOOL bResult; va_list prms;
ASSERT( NULL != file ); ASSERT( g_bCommandLineMode );
va_start (prms, szFormat);
//
// Format the message in our local buffer
//
_vsntprintf ( szMessage, ARRAY_LENGTH( szMessage ), szFormat, prms );
bResult = ( _fputts( szMessage, file ) >= 0 );
va_end (prms);
return bResult; }
/////////////////////////////////////////////////////////////////////////////
BOOL __cdecl VrfFTPrintfResourceFormat( FILE *file, UINT uIdResourceFormat, ... ) { TCHAR szMessage[ 256 ]; TCHAR strFormat[ 256 ]; BOOL bResult; va_list prms; ASSERT( NULL != file );
//
// Load the format string from the resources
//
bResult = VrfLoadString( uIdResourceFormat, strFormat, ARRAY_LENGTH( strFormat ) );
ASSERT( bResult );
if( bResult ) { va_start (prms, uIdResourceFormat);
//
// Format the message in our local buffer
//
_vsntprintf ( szMessage, ARRAY_LENGTH( szMessage ), strFormat, prms);
bResult = ( _fputts( szMessage, file ) >= 0 );
va_end (prms); }
return bResult; }
/////////////////////////////////////////////////////////////////////////////
BOOL VrfOuputStringFromResources( UINT uIdString, FILE *file ) { TCHAR szText[ 256 ]; BOOL bResult;
ASSERT( NULL != file );
bResult = VrfLoadString( uIdString, szText, ARRAY_LENGTH( szText ) );
if( FALSE == bResult ) { goto Done; }
bResult = ( _fputts( szText, file ) >= 0 );
Done:
return bResult; }
/////////////////////////////////////////////////////////////////////////////
BOOL VrfSetNewFlagsVolatile( DWORD dwNewFlags ) { BOOL bResult; NTSTATUS Status; INT_PTR nCurrentlyVerifiedDrivers; CRuntimeVerifierData RunTimeVerifierData;
bResult = TRUE;
nCurrentlyVerifiedDrivers = 0;
if( VrfGetRuntimeVerifierData( &RunTimeVerifierData ) == FALSE ) { //
// Cannot get current verifier settings
//
VrfErrorResourceFormat( IDS_CANTGET_VERIF_STATE );
bResult = FALSE;
goto Done; }
nCurrentlyVerifiedDrivers = RunTimeVerifierData.m_RuntimeDriverDataArray.GetSize();
if( nCurrentlyVerifiedDrivers > 0 ) { //
// There are some drivers currently verified
//
if( RunTimeVerifierData.Level != dwNewFlags ) { //
// Just use NtSetSystemInformation to set the flags
// that can be modified on the fly. Don't write anything to the registry.
//
//
// Enable debug privilege
//
if( g_bPrivegeEnabled != TRUE ) { g_bPrivegeEnabled = VrfEnableDebugPrivilege();
if( g_bPrivegeEnabled != TRUE ) { bResult = FALSE;
goto Done; } }
//
// Set the new flags
//
Status = NtSetSystemInformation( SystemVerifierInformation, &dwNewFlags, sizeof( dwNewFlags ) );
if( ! NT_SUCCESS( Status ) ) { if( Status == STATUS_ACCESS_DENIED ) { //
// Access denied
//
VrfErrorResourceFormat( IDS_ACCESS_IS_DENIED ); } else { //
// Some other error
//
VrfErrorResourceFormat( IDS_CANNOT_CHANGE_SETTING_ON_FLY ); }
bResult = FALSE;
goto Done; } } } Done:
if( g_bCommandLineMode ) { VrfDumpChangedSettings( RunTimeVerifierData.Level, dwNewFlags, nCurrentlyVerifiedDrivers ); }
return bResult; }
/////////////////////////////////////////////////////////////////////////////
BOOL VrfAddDriversVolatile( const CStringArray &astrNewDrivers ) { BOOL bSuccess; INT_PTR nDrivers; INT_PTR nCrtDriver; CString strCrtDriver;
bSuccess = TRUE;
nDrivers = astrNewDrivers.GetSize();
for( nCrtDriver = 0; nCrtDriver < nDrivers; nCrtDriver += 1 ) { strCrtDriver = astrNewDrivers.GetAt( nCrtDriver );
if( TRUE != VrfAddDriverVolatile( strCrtDriver ) ) { bSuccess = FALSE; } }
return bSuccess; }
/////////////////////////////////////////////////////////////////////////////
BOOL VrfAddDriverVolatile( const CString &strCrtDriver ) { NTSTATUS Status; UINT uIdErrorString; BOOL bSuccess; UNICODE_STRING usDriverName; #ifndef UNICODE
WCHAR *szUnicodeName = NULL; INT_PTR nNameLength;
#endif //#ifndef UNICODE
bSuccess = TRUE;
//
// Enable debug privilege
//
if( g_bPrivegeEnabled != TRUE ) { g_bPrivegeEnabled = VrfEnableDebugPrivilege();
if( g_bPrivegeEnabled != TRUE ) { bSuccess = FALSE;
goto Done; } }
//
// Must have driver name as a UNICODE_STRING
//
#ifdef UNICODE
//
// UNICODE
//
RtlInitUnicodeString( &usDriverName, (LPCTSTR) strCrtDriver );
#else
//
// ANSI
//
nNameLength = strCrtDriver.GetLength();
szUnicodeName = new WCHAR[ nNameLength + 1 ];
if( NULL == szUnicodeName ) { VrfErrorResourceFormat( IDS_NOT_ENOUGH_MEMORY );
bSuccess = FALSE;
goto Done; }
MultiByteToWideChar( CP_ACP, 0, (LPCSTR) strCrtDriver, -1, szUnicodeName, nNameLength + 1 );
RtlInitUnicodeString( &usDriverName, szUnicodeName );
#endif //#ifdef UNICODE
Status = NtSetSystemInformation( SystemVerifierAddDriverInformation, &usDriverName, sizeof( UNICODE_STRING ) );
if( ! NT_SUCCESS( Status ) ) { switch( Status ) { case STATUS_INVALID_INFO_CLASS: uIdErrorString = IDS_VERIFIER_ADD_NOT_SUPPORTED; break;
case STATUS_NOT_SUPPORTED: uIdErrorString = IDS_DYN_ADD_NOT_SUPPORTED; break;
case STATUS_IMAGE_ALREADY_LOADED: uIdErrorString = IDS_DYN_ADD_ALREADY_LOADED; break;
case STATUS_INSUFFICIENT_RESOURCES: case STATUS_NO_MEMORY: uIdErrorString = IDS_DYN_ADD_INSUF_RESOURCES; break;
case STATUS_PRIVILEGE_NOT_HELD: uIdErrorString = IDS_DYN_ADD_ACCESS_DENIED; break;
default: VrfErrorResourceFormat( IDS_DYN_ADD_MISC_ERROR, (LPCTSTR) strCrtDriver, Status );
bSuccess = FALSE; }
VrfErrorResourceFormat( uIdErrorString, (LPCTSTR) strCrtDriver );
bSuccess = FALSE; }
#ifndef UNICODE
if( NULL != szUnicodeName ) { delete [] szUnicodeName; }
#endif //#ifndef UNICODE
Done:
return bSuccess; }
/////////////////////////////////////////////////////////////////////////////
BOOL VrfRemoveDriversVolatile( const CStringArray &astrNewDrivers ) { INT_PTR nDrivers; INT_PTR nCrtDriver; BOOL bSuccess; CString strCrtDriver;
bSuccess = TRUE;
nDrivers = astrNewDrivers.GetSize();
for( nCrtDriver = 0; nCrtDriver < nDrivers; nCrtDriver += 1 ) { strCrtDriver = astrNewDrivers.GetAt( nCrtDriver );
if( TRUE != VrfRemoveDriverVolatile( strCrtDriver ) ) { bSuccess = FALSE; } }
return bSuccess; }
/////////////////////////////////////////////////////////////////////////////
BOOL VrfRemoveDriverVolatile( const CString &strDriverName ) { NTSTATUS Status; UINT uIdErrorString; BOOL bSuccess; UNICODE_STRING usDriverName; #ifndef UNICODE
WCHAR *szUnicodeName = NULL; INT_PTR nNameLength;
#endif //#ifndef UNICODE
bSuccess = TRUE;
//
// Enable debug privilege
//
if( g_bPrivegeEnabled != TRUE ) { g_bPrivegeEnabled = VrfEnableDebugPrivilege();
if( g_bPrivegeEnabled != TRUE ) { bSuccess = FALSE;
goto Done; } }
//
// Must have driver name as a UNICODE_STRING
//
#ifdef UNICODE
//
// UNICODE
//
RtlInitUnicodeString( &usDriverName, (LPCTSTR) strDriverName );
#else
//
// ANSI
//
nNameLength = strDriverName.GetLength();
szUnicodeName = new WCHAR[ nNameLength + 1 ];
if( NULL == szUnicodeName ) { VrfErrorResourceFormat( IDS_NOT_ENOUGH_MEMORY );
bSuccess = FALSE;
goto Done; }
MultiByteToWideChar( CP_ACP, 0, (LPCSTR) strDriverName, -1, szUnicodeName, nNameLength + 1 );
RtlInitUnicodeString( &usDriverName, szUnicodeName );
#endif //#ifdef UNICODE
Status = NtSetSystemInformation( SystemVerifierRemoveDriverInformation, &usDriverName, sizeof( UNICODE_STRING ) );
if( ! NT_SUCCESS( Status ) ) { switch( Status ) { case STATUS_INVALID_INFO_CLASS: uIdErrorString = IDS_VERIFIER_REMOVE_NOT_SUPPORTED; break;
case STATUS_NOT_SUPPORTED: //
// the driver verifier is not currently active at all -> success
//
case STATUS_NOT_FOUND: //
// the driver is not currently verified -> success
//
return TRUE;
case STATUS_IMAGE_ALREADY_LOADED: uIdErrorString = IDS_DYN_REMOVE_ALREADY_LOADED; break;
case STATUS_INSUFFICIENT_RESOURCES: case STATUS_NO_MEMORY: uIdErrorString = IDS_DYN_REMOVE_INSUF_RESOURCES; break;
case STATUS_PRIVILEGE_NOT_HELD: uIdErrorString = IDS_DYN_REMOVE_ACCESS_DENIED; break;
default: VrfErrorResourceFormat( IDS_DYN_REMOVE_MISC_ERROR, (LPCTSTR) strDriverName, Status );
bSuccess = FALSE; }
VrfErrorResourceFormat( uIdErrorString, (LPCTSTR) strDriverName );
bSuccess = FALSE; }
Done:
#ifndef UNICODE
if( NULL != szUnicodeName ) { delete [] szUnicodeName; }
#endif //#ifndef UNICODE
return bSuccess; }
//////////////////////////////////////////////////////////////////////
BOOL VrfEnableDebugPrivilege( ) { struct { DWORD Count; LUID_AND_ATTRIBUTES Privilege [1];
} Info;
HANDLE Token; BOOL Result;
//
// Open the process token
//
Result = OpenProcessToken ( GetCurrentProcess (), TOKEN_ADJUST_PRIVILEGES, & Token);
if( Result != TRUE ) { VrfErrorResourceFormat( IDS_ACCESS_IS_DENIED );
return FALSE; }
//
// Prepare the info structure
//
Info.Count = 1; Info.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED;
Result = LookupPrivilegeValue ( NULL, SE_DEBUG_NAME, &(Info.Privilege[0].Luid));
if( Result != TRUE ) { VrfErrorResourceFormat( IDS_ACCESS_IS_DENIED );
CloseHandle( Token );
return FALSE; }
//
// Adjust the privileges
//
Result = AdjustTokenPrivileges ( Token, FALSE, (PTOKEN_PRIVILEGES) &Info, NULL, NULL, NULL);
if( Result != TRUE || GetLastError() != ERROR_SUCCESS ) { VrfErrorResourceFormat( IDS_ACCESS_IS_DENIED );
CloseHandle( Token );
return FALSE; }
CloseHandle( Token );
return TRUE; }
//////////////////////////////////////////////////////////////////////
VOID VrfDumpChangedSettings( UINT OldFlags, UINT NewFlags, INT_PTR nDriversVerified ) { UINT uDifferentFlags;
if( nDriversVerified == 0 ) { VrfPrintStringFromResources( IDS_NO_DRIVER_VERIFIED );
goto Done; }
if( OldFlags == NewFlags ) { //
// no settings were changed
//
VrfPrintStringFromResources( IDS_NO_SETTINGS_WERE_CHANGED ); } else { VrfPrintStringFromResources( IDS_CHANGED_SETTINGS_ARE );
uDifferentFlags = OldFlags ^ NewFlags;
//
// changed DRIVER_VERIFIER_SPECIAL_POOLING ?
//
if( uDifferentFlags & DRIVER_VERIFIER_SPECIAL_POOLING ) { if( NewFlags & DRIVER_VERIFIER_SPECIAL_POOLING ) { VrfPrintStringFromResources( IDS_SPECIAL_POOL_ENABLED_NOW ); } else { VrfPrintStringFromResources( IDS_SPECIAL_POOL_DISABLED_NOW ); } }
//
// changed DRIVER_VERIFIER_FORCE_IRQL_CHECKING ?
//
if( uDifferentFlags & DRIVER_VERIFIER_FORCE_IRQL_CHECKING ) { if( NewFlags & DRIVER_VERIFIER_FORCE_IRQL_CHECKING ) { VrfPrintStringFromResources( IDS_FORCE_IRQLCHECK_ENABLED_NOW ); } else { VrfPrintStringFromResources( IDS_FORCE_IRQLCHECK_DISABLED_NOW ); } }
//
// changed DRIVER_VERIFIER_INJECT_ALLOCATION_FAILURES ?
//
if( uDifferentFlags & DRIVER_VERIFIER_INJECT_ALLOCATION_FAILURES ) { if( NewFlags & DRIVER_VERIFIER_INJECT_ALLOCATION_FAILURES ) { VrfPrintStringFromResources( IDS_FAULT_INJECTION_ENABLED_NOW ); } else { VrfPrintStringFromResources( IDS_FAULT_INJECTION_DISABLED_NOW ); } }
//
// changed DRIVER_VERIFIER_TRACK_POOL_ALLOCATIONS ?
//
if( uDifferentFlags & DRIVER_VERIFIER_TRACK_POOL_ALLOCATIONS ) { if( NewFlags & DRIVER_VERIFIER_TRACK_POOL_ALLOCATIONS ) { VrfPrintStringFromResources( IDS_POOL_TRACK_ENABLED_NOW ); } else { VrfPrintStringFromResources( IDS_POOL_TRACK_DISABLED_NOW ); } }
//
// changed DRIVER_VERIFIER_IO_CHECKING ?
//
if( uDifferentFlags & DRIVER_VERIFIER_IO_CHECKING ) { if( NewFlags & DRIVER_VERIFIER_IO_CHECKING ) { VrfPrintStringFromResources( IDS_IO_CHECKING_ENABLED_NOW ); } else { VrfPrintStringFromResources( IDS_IO_CHECKING_DISABLED_NOW ); } }
//
// the changes are not saved to the registry
//
VrfPrintStringFromResources( IDS_CHANGES_ACTIVE_ONLY_BEFORE_REBOOT ); }
Done:
NOTHING; }
/////////////////////////////////////////////////////////////////////////////
DWORD VrfGetStandardFlags() { DWORD dwStandardFlags;
dwStandardFlags = DRIVER_VERIFIER_SPECIAL_POOLING | DRIVER_VERIFIER_FORCE_IRQL_CHECKING | DRIVER_VERIFIER_TRACK_POOL_ALLOCATIONS | DRIVER_VERIFIER_IO_CHECKING | DRIVER_VERIFIER_DEADLOCK_DETECTION | DRIVER_VERIFIER_DMA_VERIFIER;
return dwStandardFlags; }
/////////////////////////////////////////////////////////////////////////////
VOID VrfAddMiniports( CStringArray &astrVerifiedDrivers ) { CStringArray astrToAdd; CString strCrtDriver; CString strCrtDriverToAdd; CString strLinkedDriver; INT_PTR nVerifiedDrivers; INT_PTR nCrtDriver; INT_PTR nDriversToAdd; INT_PTR nCrtDriverToAdd;
nVerifiedDrivers = astrVerifiedDrivers.GetSize();
for( nCrtDriver = 0; nCrtDriver < nVerifiedDrivers; nCrtDriver += 1 ) { //
// This will be a verified driver
//
strCrtDriver = astrVerifiedDrivers.GetAt( nCrtDriver );
//
// Check if it is a miniport driver
//
if( VrfIsDriverMiniport( strCrtDriver, strLinkedDriver ) ) { //
// Check if we didn't add already strLinkedDriver
//
nDriversToAdd = astrToAdd.GetSize();
for( nCrtDriverToAdd = 0; nCrtDriverToAdd < nDriversToAdd; nCrtDriverToAdd += 1 ) { strCrtDriverToAdd = astrToAdd.GetAt( nCrtDriverToAdd );
if( strCrtDriverToAdd.CompareNoCase( strLinkedDriver ) == 0 ) { //
// We already wanted to add this driver
//
break; } }
if( nCrtDriverToAdd >= nDriversToAdd ) { //
// Add this new driver (strLinkedDriver)
//
astrToAdd.Add( strLinkedDriver ); } } }
//
// Flush astrToAdd into astrVerifiedDrivers
//
nDriversToAdd = astrToAdd.GetSize();
for( nCrtDriverToAdd = 0; nCrtDriverToAdd < nDriversToAdd; nCrtDriverToAdd += 1 ) { strCrtDriverToAdd = astrToAdd.GetAt( nCrtDriverToAdd );
astrVerifiedDrivers.Add( strCrtDriverToAdd ); } }
/////////////////////////////////////////////////////////////////////////////
BOOL VrfIsDriverMiniport( CString &strCrtDriver, CString &strLinkedDriver ) { //
// N.B.
//
// The imagehlp functions are not multithreading safe
// (see Whistler bug #88373) so if we want to use them from more than
// one thread we will have to aquire some critical section before.
//
// Currently only one thread is using the imagehlp APIs in this app
// (CSlowProgressDlg::LoadDriverDataWorkerThread) so we don't need
// our synchronization.
//
LPTSTR szDriverName; LPTSTR szDriversDir; PLOADED_IMAGE pLoadedImage; BOOL bIsMiniport; BOOL bUnloaded;
bIsMiniport = FALSE;
ASSERT( strCrtDriver.GetLength() > 0 );
//
// ImageLoad doesn't know about const pointers so
// we have to GetBuffer here :-(
//
szDriverName = strCrtDriver.GetBuffer( strCrtDriver.GetLength() + 1 );
if( NULL == szDriverName ) { goto Done; }
szDriversDir = g_strDriversDir.GetBuffer( g_strDriversDir.GetLength() + 1 );
if( NULL == szDriversDir ) { strCrtDriver.ReleaseBuffer();
goto Done; }
//
// Load the image
//
pLoadedImage = VrfImageLoad( szDriverName, szDriversDir );
if( NULL == pLoadedImage ) { //
// Could not load the image from %windir%\system32\drivers
// Try again from the PATH
//
pLoadedImage = VrfImageLoad( szDriverName, NULL ); }
//
// Give our string buffers back to MFC
//
strCrtDriver.ReleaseBuffer(); g_strDriversDir.ReleaseBuffer();
if( NULL == pLoadedImage ) { //
// We couldn't load this image - bad luck
//
TRACE( _T( "ImageLoad failed for %s, error %u\n" ), (LPCTSTR) strCrtDriver, GetLastError() );
goto Done; }
//
// Check if the current driver is a miniport
//
bIsMiniport = VrfIsDriverMiniport( pLoadedImage, strLinkedDriver );
//
// Clean-up
//
bUnloaded = ImageUnload( pLoadedImage );
//
// If ImageUnload fails we cannot do much about it...
//
ASSERT( bUnloaded );
Done:
return bIsMiniport; }
/////////////////////////////////////////////////////////////////////////////
LPSTR g_szSpecialDrivers[] = { "videoprt.sys", "scsiport.sys" };
BOOL VrfpLookForAllImportDescriptors( PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor, ULONG_PTR uVACorrection, CString &strLinkedAgainst ) { PIMAGE_IMPORT_DESCRIPTOR pCurrentDescriptor; PCHAR pCrtName; ULONG uCrtSpecialDriver; BOOL bIsMiniport; #ifdef UNICODE
//
// UNICODE
//
INT nCrtStringLength; PWSTR szMiniportName;
#endif //#ifdef UNICODE
bIsMiniport = FALSE;
for( uCrtSpecialDriver = 0; ! bIsMiniport && uCrtSpecialDriver < ARRAY_LENGTH( g_szSpecialDrivers ); uCrtSpecialDriver += 1 ) { pCurrentDescriptor = pImportDescriptor;
while( pCurrentDescriptor->Characteristics != NULL ) { pCrtName = (PCHAR)UlongToPtr( pCurrentDescriptor->Name ) + uVACorrection;
if( lstrcmpiA( g_szSpecialDrivers[ uCrtSpecialDriver ] , pCrtName ) == 0 ) { //
// This is a miniport
//
#ifndef UNICODE
//
// ANSI
//
strLinkedAgainst = g_szSpecialDrivers[ uCrtSpecialDriver ];
#else
//
// UNICODE
//
nCrtStringLength = strlen( g_szSpecialDrivers[ uCrtSpecialDriver ] );
szMiniportName = strLinkedAgainst.GetBuffer( nCrtStringLength + 1 );
if( NULL != szMiniportName ) { MultiByteToWideChar( CP_ACP, 0, g_szSpecialDrivers[ uCrtSpecialDriver ], -1, szMiniportName, ( nCrtStringLength + 1 ) * sizeof( TCHAR ) );
strLinkedAgainst.ReleaseBuffer(); } #endif
bIsMiniport = TRUE;
break; }
pCurrentDescriptor += 1; } }
return bIsMiniport; }
/////////////////////////////////////////////////////////////////////////////
BOOL VrfIsDriverMiniport( PLOADED_IMAGE pLoadedImage, CString &strLinkedDriver ) { PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor; PIMAGE_SECTION_HEADER pSectionHeader; ULONG_PTR uVACorrection; ULONG uDataSize; BOOL bIsMiniport;
bIsMiniport = FALSE;
//
// We are protecting ourselves against corrupted binaries
// with this exception handler
//
try { pSectionHeader = NULL;
pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToDataEx( pLoadedImage->MappedAddress, FALSE, IMAGE_DIRECTORY_ENTRY_IMPORT, &uDataSize, &pSectionHeader );
if( NULL == pSectionHeader ) { goto Done; }
uVACorrection = (ULONG_PTR) pLoadedImage->MappedAddress + pSectionHeader->PointerToRawData - pSectionHeader->VirtualAddress;
bIsMiniport = VrfpLookForAllImportDescriptors( pImportDescriptor, uVACorrection, strLinkedDriver ); #ifdef _DEBUG
if( bIsMiniport ) { TRACE( _T( "%s will be auto-enabled\n" ), (LPCTSTR) strLinkedDriver ); } #endif //#ifdef DEBUG
} catch( ... ) { TRACE( _T( "VrfIsDriverMiniport: Caught exception\n" ) ); }
Done:
return bIsMiniport; }
/////////////////////////////////////////////////////////////////////////////
VOID VrfpDumpSettingToConsole( ULONG uIdResourceString, BOOL bEnabled ) { CString strTitle; CString strEnabled; ULONG uIdEnabledString; TCHAR szBigBuffer[ 128 ];
VERIFY( VrfLoadString( uIdResourceString, strTitle ) );
if( FALSE == bEnabled ) { uIdEnabledString = IDS_DISABLED; } else { uIdEnabledString = IDS_ENABLED; }
VERIFY( VrfLoadString( uIdEnabledString, strEnabled ) );
_sntprintf( szBigBuffer, ARRAY_LENGTH( szBigBuffer ), _T( "%s: %s" ), (LPCTSTR) strTitle, (LPCTSTR) strEnabled );
szBigBuffer[ ARRAY_LENGTH( szBigBuffer ) - 1 ] = 0;
_putts( szBigBuffer ); }
/////////////////////////////////////////////////////////////////////////////
VOID VrfDumpRegistrySettingsToConsole() { BOOL bLoaded; BOOL bAllDriversVerified; DWORD dwVerifyFlags; INT_PTR nDrivers; INT_PTR nCrtDriver; CString strCrtDriver; CStringArray astrDriversToVerify; bLoaded = VrtLoadCurrentRegistrySettings( bAllDriversVerified, astrDriversToVerify, dwVerifyFlags );
if( FALSE != bLoaded ) { VrfpDumpSettingToConsole( IDS_SPECIAL_POOL, ( dwVerifyFlags & DRIVER_VERIFIER_SPECIAL_POOLING ) != 0 ); VrfpDumpSettingToConsole( IDS_FORCE_IRQL_CHECKING, ( dwVerifyFlags & DRIVER_VERIFIER_FORCE_IRQL_CHECKING ) != 0 ); VrfpDumpSettingToConsole( IDS_LOW_RESOURCE_SIMULATION, ( dwVerifyFlags & DRIVER_VERIFIER_INJECT_ALLOCATION_FAILURES ) != 0 ); VrfpDumpSettingToConsole( IDS_POOL_TRACKING, ( dwVerifyFlags & DRIVER_VERIFIER_TRACK_POOL_ALLOCATIONS ) != 0 ); VrfpDumpSettingToConsole( IDS_IO_VERIFICATION, ( dwVerifyFlags & DRIVER_VERIFIER_IO_CHECKING ) != 0 ); VrfpDumpSettingToConsole( IDS_DEADLOCK_DETECTION, ( dwVerifyFlags & DRIVER_VERIFIER_DEADLOCK_DETECTION ) != 0 ); VrfpDumpSettingToConsole( IDS_ENH_IO_VERIFICATION, ( dwVerifyFlags & DRIVER_VERIFIER_ENHANCED_IO_CHECKING ) != 0 ); VrfpDumpSettingToConsole( IDS_DMA_CHECHKING, ( dwVerifyFlags & DRIVER_VERIFIER_DMA_VERIFIER ) != 0 );
VrfPrintStringFromResources( IDS_VERIFIED_DRIVERS ); if( bAllDriversVerified ) { VrfPrintStringFromResources( IDS_ALL ); } else { nDrivers = astrDriversToVerify.GetSize();
if( nDrivers > 0 ) { for( nCrtDriver = 0; nCrtDriver < nDrivers; nCrtDriver += 1 ) { strCrtDriver = astrDriversToVerify.GetAt( nCrtDriver );
_putts( (LPCTSTR) strCrtDriver ); } } else { VrfPrintStringFromResources( IDS_NONE ); } } } }
/////////////////////////////////////////////////////////////////////////////
BOOL VrfIsNameAlreadyInList( LPCTSTR szDriver, LPCTSTR szAllDrivers ) { INT nNameLength; INT nLastIndex; INT nIndex; BOOL bFoundIt; CString strDriver( szDriver ); CString strAllDrivers( szAllDrivers );
bFoundIt = FALSE;
strDriver.MakeLower(); strAllDrivers.MakeLower();
nNameLength = strDriver.GetLength();
nLastIndex = 0; do { nIndex = strAllDrivers.Find( (LPCTSTR)strDriver, nLastIndex );
if( nIndex >= 0 ) { //
// Found the substring. Verify it is separated of spaces, etc.
//
if( (nIndex == 0 || _T( ' ' ) == strAllDrivers[ nIndex - 1 ]) && ( (TCHAR)0 == strAllDrivers[ nNameLength + nIndex ] || _T( ' ' ) == strAllDrivers[ nNameLength + nIndex ]) ) { //
// This is our driver.
//
bFoundIt = TRUE;
break; } else { //
// Continue searching.
//
nLastIndex = nIndex + 1; } } } while( nIndex >= 0 );
return bFoundIt; }
/////////////////////////////////////////////////////////////////////////////
VOID VrfAddDriverNameNoDuplicates( LPCTSTR szDriver, CString &strAllDrivers ) { if( FALSE == VrfIsNameAlreadyInList( szDriver, strAllDrivers ) ) { if( strAllDrivers.GetLength() > 0 ) { strAllDrivers += _T( ' ' ); }
strAllDrivers += szDriver; } }
/////////////////////////////////////////////////////////////////////////////
BOOL VrfIsStringInArray( LPCTSTR szText, const CStringArray &astrAllTexts ) { INT_PTR nTexts; BOOL bFound;
bFound = FALSE;
nTexts = astrAllTexts.GetSize();
while( nTexts > 0 ) { nTexts -= 1;
if( 0 == astrAllTexts.GetAt( nTexts ).CompareNoCase( szText ) ) { bFound = TRUE; break; } }
return bFound; }
|