|
|
//
// Driver Verifier Control Applet
// Copyright (c) Microsoft Corporation, 1999
//
//
// module: verify.cxx
// author: silviuc
// created: Mon Jan 04 12:40:57 1999
//
extern "C" { #include "nt.h"
#include "ntrtl.h"
#include "nturtl.h"
}
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <tchar.h>
#include <windows.h>
#include <time.h>
#include <ntverp.h>
#include <common.ver>
#include "verify.hxx"
#include "image.hxx"
#include "resource.h"
//
// IO verification levels
//
#define IO_VERIFICATION_LEVEL_MAX 3
//
// all the possible verification flags
//
const UINT VerifierAllOptions = (DRIVER_VERIFIER_SPECIAL_POOLING | DRIVER_VERIFIER_FORCE_IRQL_CHECKING | DRIVER_VERIFIER_INJECT_ALLOCATION_FAILURES | DRIVER_VERIFIER_TRACK_POOL_ALLOCATIONS | DRIVER_VERIFIER_IO_CHECKING | DRIVER_VERIFIER_DEADLOCK_DETECTION );
//
// the options that can be modified on the fly
//
const UINT VerifierModifyableOptions = (DRIVER_VERIFIER_SPECIAL_POOLING | DRIVER_VERIFIER_FORCE_IRQL_CHECKING | DRIVER_VERIFIER_INJECT_ALLOCATION_FAILURES);
//
// system IO verifier values
//
#define SYS_IO_VERIFIER_DISABLED_VALUE 0
#define SYS_IO_VERIFIER_BASE_VALUE 1
//////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////// Global Data
//////////////////////////////////////////////////////////////////////
//
// Command line / GUI
//
BOOL g_bCommandLineMode = FALSE;
//
// OS version and build number information
//
OSVERSIONINFO g_OsVersion;
//
// Was the debug privilege already enabled?
// We need this privilege to set volatile options.
//
BOOL g_bPrivegeEnabled = FALSE;
//////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////// Registry Strings
//////////////////////////////////////////////////////////////////////
LPCTSTR RegMemoryManagementKeyName = TEXT ("System\\CurrentControlSet\\Control\\Session Manager\\Memory Management");
LPCTSTR RegVerifyDriversValueName = TEXT ("VerifyDrivers");
LPCTSTR RegVerifyDriverLevelValueName = TEXT ("VerifyDriverLevel");
LPCTSTR RegSessionManagerKeyName = TEXT ("System\\CurrentControlSet\\Control\\Session Manager");
LPCTSTR RegIOVerifyKeyName = TEXT ("System\\CurrentControlSet\\Control\\Session Manager\\I/O System");
LPCTSTR RegIOVerifySubKeyName = TEXT ("I/O System");
LPCTSTR RegIOVerifyLevelValueName = TEXT ("IoVerifierLevel");
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////// command line support
//////////////////////////////////////////////////////////////////////
void VrfDumpChangedSettings(
UINT OldFlags, UINT NewFlags );
BOOL VrfEnableDebugPrivilege ( );
//////////////////////////////////////////////////////////////////////
/////////////// Forward decl for local registry manipulation functions
//////////////////////////////////////////////////////////////////////
BOOL ReadRegistryValue (
HKEY HKey, LPCTSTR Name, DWORD * Value, DWORD DefaultValue);
BOOL WriteRegistryValue (
HKEY HKey, LPCTSTR Name, DWORD Value);
BOOL ReadMmString (
HKEY MmKey, LPCTSTR Name, LPTSTR Buffer, DWORD BufferSize);
BOOL WriteMmString (
HKEY MmKey, LPCTSTR Name, LPTSTR Value);
//////////////////////////////////////////////////////////////////////
/////////////// Forward decl for local sys level IO verifier functions
//////////////////////////////////////////////////////////////////////
BOOL SetSysIoVerifierSettings( ULONG SysIoVerifierLevel );
//////////////////////////////////////////////////////////////////////
/////////////////////// Forward decl for driver manipulation functions
//////////////////////////////////////////////////////////////////////
typedef enum {
VRF_DRIVER_LOAD_SUCCESS, VRF_DRIVER_LOAD_CANNOT_FIND_IMAGE, VRF_DRIVER_LOAD_INVALID_IMAGE
} VRF_DRIVER_LOAD_STATUS;
ULONG GetActiveDriversList (
PVRF_DRIVER_STATE DriverInfo, ULONG MaxNumberOfDrivers);
BOOL SetVerifiedDriversFromNamesString (
PVRF_VERIFIER_STATE VrfState );
BOOL GetVerifiedDriversToString (
PVRF_VERIFIER_STATE VrfState );
BOOL SetAllDriversStatus (
PVRF_VERIFIER_STATE VrfState, BOOL Verified);
BOOL VrfSearchVerifierDriver (
PVRF_VERIFIER_STATE VrfState, LPCTSTR DriverName, ULONG & HitIndex);
BOOL KrnSearchVerifierDriver (
LPCTSTR DriverName, ULONG & HitIndex);
LPCTSTR IsMiniportDriver (
LPCTSTR DriverName, VRF_DRIVER_LOAD_STATUS &ErrorCode);
BOOL VrfGetVersionInfo( LPTSTR lptstrFileName, LPTSTR lptstrCompany, int nCompanyBufferLength, LPTSTR lptstrVersion, int nVersionBufferLength );
BOOL ConvertAnsiStringToTcharString (
LPBYTE Source, ULONG SourceLength, LPTSTR Destination, ULONG DestinationLength);
//
// Support for dynamic set of verified drivers
//
BOOL VrfVolatileAddOrRemoveDriversCmdLine(
int nArgsNo, LPTSTR szCmdLineArgs[] );
//////////////////////////////////////////////////////////////////////
////////////////////////////////////////// Exported Verifier Functions
//////////////////////////////////////////////////////////////////////
//
// Function:
//
// VrfGetVerifierState
//
// Description:
//
// Reads all Mm related registry settings and fills the structure
// with the appropriate BOOLean values.
//
BOOL VrfGetVerifierState (
PVRF_VERIFIER_STATE VrfState) { static KRN_VERIFIER_STATE KrnState;
HKEY MmKey = NULL; HKEY IoKey = NULL; LONG Result; DWORD Value; DWORD IoValue; ULONG Index; ULONG FoundIndex;
if (VrfState == NULL) {
return FALSE; }
//
// Open the Mm key
//
Result = RegOpenKeyEx (
HKEY_LOCAL_MACHINE, RegMemoryManagementKeyName, 0, KEY_QUERY_VALUE, &MmKey);
if (Result != ERROR_SUCCESS) {
if( Result == ERROR_ACCESS_DENIED ) {
VrfErrorResourceFormat ( IDS_ACCESS_IS_DENIED ); } else {
VrfErrorResourceFormat ( IDS_REGOPENKEYEX_FAILED, RegMemoryManagementKeyName, (DWORD)Result); }
return FALSE; }
//
// Set the driver specific information.
//
VrfState->DriverNames[ 0 ] = 0; VrfState->AdditionalDriverNames[ 0 ] = 0;
VrfState->DriverCount = GetActiveDriversList ( VrfState->DriverInfo, ARRAY_LENGTH( VrfState->DriverInfo ) );
//
// Read VerifyDriverLevel value
//
if (ReadRegistryValue (MmKey, RegVerifyDriverLevelValueName, &Value, 0) == FALSE) {
RegCloseKey (MmKey); return FALSE; }
VrfState->SpecialPoolVerification = (Value & DRIVER_VERIFIER_SPECIAL_POOLING) ? TRUE : FALSE; VrfState->PagedCodeVerification = (Value & DRIVER_VERIFIER_FORCE_IRQL_CHECKING) ? TRUE : FALSE; VrfState->AllocationFaultInjection = (Value & DRIVER_VERIFIER_INJECT_ALLOCATION_FAILURES) ? TRUE : FALSE; VrfState->PoolTracking = (Value & DRIVER_VERIFIER_TRACK_POOL_ALLOCATIONS) ? TRUE : FALSE; VrfState->IoVerifier = (Value & DRIVER_VERIFIER_IO_CHECKING) ? TRUE : FALSE;
//
// the sys level IO verifier can be enabled only if VrfState->IoVerifier == TRUE
//
if( VrfState->IoVerifier == TRUE ) { //
// don't know yet if the sys level IO verifier is enabled
//
IoValue = SYS_IO_VERIFIER_DISABLED_VALUE;
//
// Open the IO key
//
Result = RegOpenKeyEx (
HKEY_LOCAL_MACHINE, RegIOVerifyKeyName, 0, KEY_QUERY_VALUE, &IoKey);
if (Result != ERROR_SUCCESS ) {
//
// if Result == ERROR_FILE_NOT_FOUND just use out default value for IoValue
//
if( Result != ERROR_FILE_NOT_FOUND ) {
//
// the key is there but we cannot read it, fatal error
//
if( Result == ERROR_ACCESS_DENIED ) {
VrfErrorResourceFormat( IDS_ACCESS_IS_DENIED ); } else {
VrfErrorResourceFormat( IDS_REGOPENKEYEX_FAILED, RegIOVerifyKeyName, (DWORD)Result); }
RegCloseKey (MmKey); return FALSE; } } else {
//
// IO key opened, read the IoVerifierLevel value
//
if ( ReadRegistryValue ( IoKey, RegIOVerifyLevelValueName, &IoValue, SYS_IO_VERIFIER_DISABLED_VALUE ) == FALSE) {
RegCloseKey (IoKey); RegCloseKey (MmKey); return FALSE; }
//
// done with the IO key
//
RegCloseKey (IoKey); } if (IoValue) { VrfState->SysIoVerifierLevel = IoValue - SYS_IO_VERIFIER_BASE_VALUE; } }
//
// Read VerifyDrivers value
//
VrfState->AllDriversVerified = FALSE;
if (ReadMmString (MmKey, RegVerifyDriversValueName, VrfState->DriverNames, sizeof( VrfState->DriverNames ) ) == FALSE) {
RegCloseKey (MmKey); return FALSE; }
if ( VrfState->DriverNames[ 0 ] == TEXT('*') ) {
VrfState->AllDriversVerified = TRUE; SetAllDriversStatus (VrfState, TRUE); } else {
SetVerifiedDriversFromNamesString ( VrfState ); }
//
// Get the kernel verifier state and mark any active drivers
// as already verified.
//
if (KrnGetSystemVerifierState ( &KrnState ) == TRUE) {
for (Index = 0; Index < KrnState.DriverCount; Index++) {
if (VrfSearchVerifierDriver ( VrfState, KrnState.DriverInfo[Index].Name, FoundIndex) == TRUE) {
VrfState->DriverInfo[FoundIndex].CurrentlyVerified = TRUE; } } }
//
// Close the Mm key and return success
//
RegCloseKey (MmKey); return TRUE; }
//
// Function:
//
// VrfSetVerifierState
//
// Description:
//
// Writes all Mm related registry settings according with
// the structure.
//
BOOL VrfSetVerifierState (
PVRF_VERIFIER_STATE VrfState) { HKEY MmKey = NULL; LONG Result; DWORD Value; size_t StringLength; size_t CrtCharIndex;
//
// Open the Mm key
//
Result = RegOpenKeyEx (
HKEY_LOCAL_MACHINE, RegMemoryManagementKeyName, 0, KEY_SET_VALUE, &MmKey);
if (Result != ERROR_SUCCESS) {
if( Result == ERROR_ACCESS_DENIED ) {
VrfErrorResourceFormat( IDS_ACCESS_IS_DENIED ); } else {
VrfErrorResourceFormat( IDS_REGOPENKEYEX_FAILED, RegMemoryManagementKeyName, (DWORD)Result); }
return FALSE; }
//
// Write VerifyDriverLevel value
//
Value = (VrfState->SpecialPoolVerification ? DRIVER_VERIFIER_SPECIAL_POOLING : 0); Value |= (VrfState->PagedCodeVerification ? DRIVER_VERIFIER_FORCE_IRQL_CHECKING : 0); Value |= (VrfState->AllocationFaultInjection ? DRIVER_VERIFIER_INJECT_ALLOCATION_FAILURES : 0); Value |= (VrfState->PoolTracking ? DRIVER_VERIFIER_TRACK_POOL_ALLOCATIONS : 0); Value |= (VrfState->IoVerifier ? DRIVER_VERIFIER_IO_CHECKING : 0);
if (WriteRegistryValue (MmKey, RegVerifyDriverLevelValueName, Value) == FALSE) {
RegCloseKey (MmKey); return FALSE; }
//
// enable/disable system level IO verifier
//
if ( VrfState->IoVerifier == FALSE ) { VrfState->SysIoVerifierLevel = 0; }
if( ! SetSysIoVerifierSettings( VrfState->SysIoVerifierLevel ) ) { RegCloseKey (MmKey); return FALSE; }
//
// Write VerifyDrivers value
//
if (VrfState->AllDriversVerified) {
if (WriteMmString (MmKey, RegVerifyDriversValueName, TEXT("*")) == FALSE) {
RegCloseKey (MmKey); return FALSE; } } else {
GetVerifiedDriversToString ( VrfState );
//
// do we have any significant characters in VrfState->DriverNames?
//
StringLength = _tcslen( VrfState->DriverNames );
for( CrtCharIndex = 0; CrtCharIndex < StringLength; CrtCharIndex++ ) {
if( VrfState->DriverNames[ CrtCharIndex ] != _T( ' ' ) && VrfState->DriverNames[ CrtCharIndex ] != _T( '\t' ) ) {
break; }
}
if( CrtCharIndex < StringLength ) { //
// we have at least one significant character in the string
//
if (WriteMmString (MmKey, RegVerifyDriversValueName, VrfState->DriverNames) == FALSE) {
RegCloseKey (MmKey); return FALSE; } } else {
//
// no drivers will be verified, erase the driver list from the registry
//
Result = RegDeleteValue (MmKey, RegVerifyDriversValueName);
if (Result != ERROR_SUCCESS && Result != ERROR_FILE_NOT_FOUND) {
VrfErrorResourceFormat( IDS_REGDELETEVALUE_FAILED, RegVerifyDriversValueName, (DWORD)Result);
RegCloseKey (MmKey); return FALSE; }
} }
//
// Close the Mm key and return success
//
RegCloseKey (MmKey); return TRUE; }
//
// Function:
//
// VrfSetVolatileFlags
//
// Description:
//
// This functions modifies verifier options on the fly.
//
BOOL VrfSetVolatileFlags (
UINT uNewFlags) { NTSTATUS Status;
//
// 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 ) { return FALSE; } }
//
// set the new flags
//
Status = NtSetSystemInformation( SystemVerifierInformation, &uNewFlags, sizeof( uNewFlags ) );
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 ); }
return FALSE; }
return TRUE; }
//
// Function:
//
// VrfSetVolatileOptions
//
// Description:
//
// This functions modifies verifier options on the fly.
//
BOOL VrfSetVolatileOptions(
BOOL bSpecialPool, BOOL bIrqlChecking, BOOL bFaultInjection ) { ULONG uNewFlags;
uNewFlags = 0;
if( bSpecialPool ) { uNewFlags |= DRIVER_VERIFIER_SPECIAL_POOLING; }
if( bIrqlChecking ) { uNewFlags |= DRIVER_VERIFIER_FORCE_IRQL_CHECKING; }
if( bFaultInjection ) { uNewFlags |= DRIVER_VERIFIER_INJECT_ALLOCATION_FAILURES; }
return VrfSetVolatileFlags( uNewFlags ); }
//
// Function:
//
// VrfClearAllVerifierSettings
//
// Description:
//
// This functions deletes all registry values that control in one
// way or another the Driver Verifier.
//
BOOL VrfClearAllVerifierSettings (
) { HKEY MmKey = NULL; HKEY IoKey = NULL; LONG Result; LPTSTR ValueName;
//
// Open the Mm key
//
Result = RegOpenKeyEx (
HKEY_LOCAL_MACHINE, RegMemoryManagementKeyName, 0, KEY_SET_VALUE, &MmKey);
if (Result != ERROR_SUCCESS) {
if( Result == ERROR_ACCESS_DENIED ) {
VrfErrorResourceFormat( IDS_ACCESS_IS_DENIED ); } else {
VrfErrorResourceFormat( IDS_REGOPENKEYEX_FAILED, RegMemoryManagementKeyName, (DWORD)Result); }
return FALSE; }
//
// Delete VerifyDriverLevel value
//
ValueName = (LPTSTR)RegVerifyDriverLevelValueName; Result = RegDeleteValue (MmKey, ValueName);
if (Result != ERROR_SUCCESS && Result != ERROR_FILE_NOT_FOUND) {
VrfErrorResourceFormat( IDS_REGDELETEVALUE_FAILED, ValueName, (DWORD)Result);
RegCloseKey (MmKey); return FALSE; }
//
// Delete VerifyDrivers value
//
ValueName = (LPTSTR)RegVerifyDriversValueName; Result = RegDeleteValue (MmKey, ValueName);
if (Result != ERROR_SUCCESS && Result != ERROR_FILE_NOT_FOUND) {
VrfErrorResourceFormat( IDS_REGDELETEVALUE_FAILED, ValueName, (DWORD)Result);
RegCloseKey (MmKey); return FALSE; }
//
// Close the Mm key
//
RegCloseKey (MmKey);
//
// delete the sys level IO verifier value
//
return SetSysIoVerifierSettings( 0 ); }
//
// Function:
//
// VrfSearchVerifiedDriver
//
// Description:
//
// This function searches the VerifierState->DriverInfo database for the specified
// driver. It sets the index if something has been found.
//
BOOL VrfSearchVerifierDriver (
PVRF_VERIFIER_STATE VrfState, LPCTSTR DriverName, ULONG & HitIndex) { ULONG Index;
ASSERT (DriverName != NULL);
for (Index = 0; Index < VrfState->DriverCount; Index++) {
if (_tcsicmp (DriverName, VrfState->DriverInfo[Index].Name) == 0) {
HitIndex = Index; return TRUE; } }
return FALSE; }
//////////////////////////////////////////////////////////////////////
////////////////////////////////////////// System verifier information
//////////////////////////////////////////////////////////////////////
//
// Function:
//
// KrnGetSystemVerifierState
//
// Description:
//
// This function queries the system verifier state using
// NtQuerysystemInformation().
//
BOOL KrnGetSystemVerifierState (
PKRN_VERIFIER_STATE KrnState) { ULONG Index; NTSTATUS Status; ULONG Length = 0; ULONG buffersize; PSYSTEM_VERIFIER_INFORMATION VerifierInfo; PSYSTEM_VERIFIER_INFORMATION VerifierInfoBase;
//
// Sanity checks
//
if (KrnState == NULL) {
return FALSE; }
//
// Initalize the returned structure and global vars
// before the search.
//
VerifierInfo = NULL;
KrnState->DriverCount = 0;
//
// 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);
return FALSE; }
//
// If no info fill out return success but no info.
//
if (Length == 0) {
free (VerifierInfo); return TRUE; }
//
// Fill out the cumulative-driver stuff.
//
VerifierInfoBase = VerifierInfo;
KrnState->Level = VerifierInfo->Level; KrnState->SpecialPool = (VerifierInfo->Level & DRIVER_VERIFIER_SPECIAL_POOLING) ? TRUE : FALSE; KrnState->IrqlChecking = (VerifierInfo->Level & DRIVER_VERIFIER_FORCE_IRQL_CHECKING) ? TRUE : FALSE; KrnState->FaultInjection = (VerifierInfo->Level & DRIVER_VERIFIER_INJECT_ALLOCATION_FAILURES) ? TRUE : FALSE; KrnState->PoolTrack = (VerifierInfo->Level & DRIVER_VERIFIER_TRACK_POOL_ALLOCATIONS) ? TRUE : FALSE; KrnState->IoVerif = (VerifierInfo->Level & DRIVER_VERIFIER_IO_CHECKING) ? TRUE : FALSE;
KrnState->RaiseIrqls = VerifierInfo->RaiseIrqls; KrnState->AcquireSpinLocks = VerifierInfo->AcquireSpinLocks; KrnState->SynchronizeExecutions = VerifierInfo->SynchronizeExecutions; KrnState->AllocationsAttempted = VerifierInfo->AllocationsAttempted; KrnState->AllocationsSucceeded = VerifierInfo->AllocationsSucceeded; KrnState->AllocationsSucceededSpecialPool = VerifierInfo->AllocationsSucceededSpecialPool; KrnState->AllocationsWithNoTag = VerifierInfo->AllocationsWithNoTag;
KrnState->Trims = VerifierInfo->Trims; KrnState->AllocationsFailed = VerifierInfo->AllocationsFailed; KrnState->AllocationsFailedDeliberately = VerifierInfo->AllocationsFailedDeliberately;
KrnState->UnTrackedPool = VerifierInfo->UnTrackedPool;
//
// Fill out the per-driver stuff.
//
VerifierInfo = VerifierInfoBase; Index = 0;
do {
ANSI_STRING Name; NTSTATUS Status;
Status = RtlUnicodeStringToAnsiString ( & Name, & VerifierInfo->DriverName, TRUE);
if (! (NT_SUCCESS(Status))) {
free (VerifierInfoBase); return FALSE; }
ConvertAnsiStringToTcharString (
(LPBYTE)(Name.Buffer), Name.Length, KrnState->DriverInfo[Index].Name, ARRAY_LENGTH( KrnState->DriverInfo[Index].Name ) - 1 );
RtlFreeAnsiString (& Name);
KrnState->DriverInfo[Index].Loads = VerifierInfo->Loads; KrnState->DriverInfo[Index].Unloads = VerifierInfo->Unloads;
KrnState->DriverInfo[Index].CurrentPagedPoolAllocations = VerifierInfo->CurrentPagedPoolAllocations; KrnState->DriverInfo[Index].CurrentNonPagedPoolAllocations = VerifierInfo->CurrentNonPagedPoolAllocations; KrnState->DriverInfo[Index].PeakPagedPoolAllocations = VerifierInfo->PeakPagedPoolAllocations; KrnState->DriverInfo[Index].PeakNonPagedPoolAllocations = VerifierInfo->PeakNonPagedPoolAllocations;
KrnState->DriverInfo[Index].PagedPoolUsageInBytes = VerifierInfo->PagedPoolUsageInBytes; KrnState->DriverInfo[Index].NonPagedPoolUsageInBytes = VerifierInfo->NonPagedPoolUsageInBytes; KrnState->DriverInfo[Index].PeakPagedPoolUsageInBytes = VerifierInfo->PeakPagedPoolUsageInBytes; KrnState->DriverInfo[Index].PeakNonPagedPoolUsageInBytes = VerifierInfo->PeakNonPagedPoolUsageInBytes;
KrnState->DriverCount++; Index++;
if (VerifierInfo->NextEntryOffset == 0) { break; }
VerifierInfo = (PSYSTEM_VERIFIER_INFORMATION)((PCHAR)VerifierInfo + VerifierInfo->NextEntryOffset);
} while (1);
free (VerifierInfoBase); return TRUE; }
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////// Read/write Mm Registry Values
//////////////////////////////////////////////////////////////////////
BOOL ReadRegistryValue (
HKEY HKey, LPCTSTR Name, DWORD * Value, DWORD DefaultValue) { LONG Result; DWORD Reserved; DWORD Type; DWORD Size;
//
// default value
//
*Value = DefaultValue; Size = sizeof *Value;
Result = RegQueryValueEx (
HKey, Name, 0, &Type, (LPBYTE)(Value), &Size);
//
// Deal with a value that is not defined.
//
if (Result == ERROR_FILE_NOT_FOUND) { *Value = 0; return TRUE; }
if (Result != ERROR_SUCCESS) {
VrfErrorResourceFormat( IDS_REGQUERYVALUEEX_FAILED, Name, (DWORD)Result);
return FALSE; }
if (Type != REG_DWORD) {
VrfErrorResourceFormat( IDS_REGQUERYVALUEEX_UNEXP_TYPE, Name);
return FALSE; }
if (Size != sizeof *Value) {
VrfErrorResourceFormat( IDS_REGQUERYVALUEEX_UNEXP_SIZE, Name);
return FALSE; }
return TRUE; }
BOOL WriteRegistryValue (
HKEY HKey, LPCTSTR Name, DWORD Value) { LONG Result;
Result = RegSetValueEx (
HKey, Name, 0, REG_DWORD, (LPBYTE)(&Value), sizeof Value);
if (Result != ERROR_SUCCESS) {
VrfErrorResourceFormat( IDS_REGSETVALUEEX_FAILED, Name, (DWORD)Result);
return FALSE; }
return TRUE; }
BOOL ReadMmString (
HKEY MmKey, LPCTSTR Name, LPTSTR Buffer, DWORD BufferSize) { LONG Result; DWORD Reserved; DWORD Type; DWORD Size;
//
// default value
//
*Buffer = 0; Size = BufferSize;
Result = RegQueryValueEx (
MmKey, Name, 0, &Type, (LPBYTE)(Buffer), &Size);
//
// Deal with a value that is not defined.
//
if (Result == ERROR_FILE_NOT_FOUND) { *Buffer = 0; return TRUE; }
if (Result != ERROR_SUCCESS) {
VrfErrorResourceFormat( IDS_REGQUERYVALUEEX_FAILED, Name, (DWORD)Result);
return FALSE; }
if (Type != REG_SZ) {
VrfErrorResourceFormat( IDS_REGQUERYVALUEEX_UNEXP_TYPE, Name);
return FALSE; }
return TRUE; }
BOOL WriteMmString (
HKEY MmKey, LPCTSTR Name, LPTSTR Value) { LONG Result; DWORD Reserved; DWORD Type; DWORD Size;
Result = RegSetValueEx (
MmKey, Name, 0, REG_SZ, (LPBYTE)(Value), (_tcslen (Value) + 1) * sizeof (TCHAR));
if (Result != ERROR_SUCCESS) {
VrfErrorResourceFormat( IDS_REGSETVALUEEX_FAILED, Name, (DWORD)Result);
return FALSE; }
return TRUE; }
//////////////////////////////////////////////////////////////////////
BOOL SetSysIoVerifierSettings( ULONG SysIoVerifierLevel ) { HKEY IoKey = NULL; HKEY SmKey = NULL; BOOL IoKeyOpened; LONG Result; BOOL bSuccess;
bSuccess = TRUE;
//
// Open the "I/O System" key
//
IoKeyOpened = FALSE;
Result = RegOpenKeyEx ( HKEY_LOCAL_MACHINE, RegIOVerifyKeyName, 0, KEY_QUERY_VALUE | KEY_WRITE, &IoKey);
if( Result != ERROR_SUCCESS ) {
if( Result == ERROR_FILE_NOT_FOUND ) {
if( SysIoVerifierLevel != 0 ) {
//
// the IO key doesn't exist, try to create it
//
//
// open the "Session Manager" key
//
Result = RegOpenKeyEx ( HKEY_LOCAL_MACHINE, RegSessionManagerKeyName, 0, KEY_QUERY_VALUE | KEY_WRITE, &SmKey);
if( Result != ERROR_SUCCESS ) {
VrfErrorResourceFormat( IDS_REGOPENKEYEX_FAILED, RegSessionManagerKeyName, (DWORD)Result);
return FALSE; }
//
// create the IO key
//
Result = RegCreateKeyEx( SmKey, RegIOVerifySubKeyName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE | KEY_QUERY_VALUE, NULL, &IoKey, NULL );
if( Result != ERROR_SUCCESS ) {
VrfErrorResourceFormat( IDS_REGCREATEKEYEX_FAILED, RegIOVerifyKeyName, (DWORD)Result);
RegCloseKey (SmKey); return FALSE; }
//
// IO key creation successful
//
RegCloseKey (SmKey);
IoKeyOpened = TRUE; }
//
// else ( SysIoVerifierLevel == 0 )
// don't need to create the IO key
//
} else {
if( Result == ERROR_ACCESS_DENIED ) {
//
// access is denied
//
VrfErrorResourceFormat( IDS_ACCESS_IS_DENIED ); } else {
//
// other error opening the IO key
//
VrfErrorResourceFormat( IDS_REGOPENKEYEX_FAILED, RegIOVerifyKeyName, (DWORD)Result); }
return FALSE; } } else {
IoKeyOpened = TRUE; }
if( SysIoVerifierLevel != 0 ) {
ASSERT( IoKeyOpened == TRUE );
//
// set the key
//
bSuccess = WriteRegistryValue( IoKey, RegIOVerifyLevelValueName, SYS_IO_VERIFIER_BASE_VALUE + SysIoVerifierLevel );
RegCloseKey (IoKey); } else {
if( IoKeyOpened == TRUE ) {
//
// the IO key exists, delete the value
//
Result = RegDeleteValue (IoKey, RegIOVerifyLevelValueName);
if (Result != ERROR_SUCCESS && Result != ERROR_FILE_NOT_FOUND) {
VrfErrorResourceFormat( IDS_REGDELETEVALUE_FAILED, RegIOVerifyLevelValueName, (DWORD)Result);
bSuccess = FALSE; }
RegCloseKey (IoKey); } }
return bSuccess; }
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////// Driver Management
//////////////////////////////////////////////////////////////////////
//
// Function:
//
// GetActiveDriversList
//
// Description:
//
// This function determines all the drivers that are currently
// loaded in the system. It will fill the 'DriverInfo' vector
// with the drivers' names.
//
// Return:
//
// The number of drivers detected whose names are written in
// the 'DriverInfo' vector.
//
ULONG GetActiveDriversList (
PVRF_DRIVER_STATE DriverInfo, ULONG MaxNumberOfDrivers) { LPTSTR Buffer; ULONG BufferSize; NTSTATUS Status; PRTL_PROCESS_MODULES Modules; ULONG Index; ULONG DriverIndex; BOOL bResult; TCHAR TcharBuffer [MAX_PATH];
for (BufferSize = 0x10000; TRUE; BufferSize += 0x1000) {
Buffer = (LPTSTR) malloc (BufferSize);
if (Buffer == NULL) { return 0; }
Status = NtQuerySystemInformation (
SystemModuleInformation, (PVOID)Buffer, BufferSize, NULL);
if (! NT_SUCCESS(Status)) {
if (Status == STATUS_INFO_LENGTH_MISMATCH) {
free( Buffer );
continue; } else {
VrfErrorResourceFormat( IDS_CANT_GET_ACTIVE_DRVLIST, Status);
free (Buffer); return 0; } } else { break; } }
Modules = (PRTL_PROCESS_MODULES)Buffer;
for ( Index = 0, DriverIndex = 0; Index < Modules->NumberOfModules && DriverIndex < MaxNumberOfDrivers; Index++ ) {
TCHAR *First, *Last, *Current;
//
// Get to work in processing the full path driver.
//
ConvertAnsiStringToTcharString (
Modules->Modules[Index].FullPathName, strlen( (const char *)(Modules->Modules[Index].FullPathName) ), TcharBuffer, ARRAY_LENGTH( TcharBuffer ) - 1 );
First = TcharBuffer; Last = First + _tcslen (TcharBuffer);
//
// Filter modules not ending in ".sys"
//
if (Last - 4 <= First || _tcsicmp (Last - 4, TEXT(".sys")) != 0) continue;
//
// Extract the file name from the full path name
//
for (Current = Last; Current >= First; Current--) {
if (*Current == TEXT('\\')) { break; } }
ZeroMemory (&(DriverInfo[DriverIndex]), sizeof (DriverInfo[DriverIndex])); _tcsncpy ((DriverInfo[DriverIndex].Name), Current + 1, 30);
bResult = VrfGetVersionInfo( DriverInfo[DriverIndex].Name, DriverInfo[DriverIndex].Provider, ARRAY_LENGTH( DriverInfo[DriverIndex].Provider ), DriverInfo[DriverIndex].Version, ARRAY_LENGTH( DriverInfo[DriverIndex].Version ) );
if( bResult != TRUE ) { //
// defaults
//
bResult = GetStringFromResources( IDS_NOT_AVAILABLE, DriverInfo[DriverIndex].Provider, ARRAY_LENGTH( DriverInfo[DriverIndex].Provider ) );
if( bResult != TRUE ) { ASSERT( FALSE ); DriverInfo[DriverIndex].Provider[ 0 ] = 0; }
bResult = GetStringFromResources( IDS_NOT_AVAILABLE, DriverInfo[DriverIndex].Version, ARRAY_LENGTH( DriverInfo[DriverIndex].Version ) );
if( bResult != TRUE ) { ASSERT( FALSE ); DriverInfo[DriverIndex].Version[ 0 ] = 0; } }
DriverIndex++; }
free (Buffer); return DriverIndex; }
//
// Function:
//
// SetVerifiedDriversFromNamesString
//
// Description:
//
// This function parses the string containing all the
// verified drivers as it was read from the registry,
// marks corresponding entries in the DriverInfo array
// as verified and adds the rest of the driver names to
// AdditionalDriverNames.
//
BOOL SetVerifiedDriversFromNamesString (
PVRF_VERIFIER_STATE VrfState ) { ULONG Index; LPTSTR First, Last, Current, End; TCHAR Save;
//
// Sanity checks
//
if ( VrfState == NULL ) {
return FALSE; }
VrfState->AdditionalDriverNames[0] = 0; First = VrfState->DriverNames; Last = First + _tcslen (VrfState->DriverNames);
for (Current = First; Current < Last; Current++) {
if (*Current == TEXT(' ') || *Current == TEXT('\t') || *Current == TEXT('\n')) {
continue; }
//
// Search for a driver name.
//
for (End = Current; *End != 0 && *End != TEXT(' ') && *End != TEXT('\n') && *End != TEXT('\t'); End++) {
// nothing
}
Save = *End; *End = 0;
//
// Search for the found driver in the VrfState->DriverInfo vector.
//
for (Index = 0; Index < VrfState->DriverCount; Index++) {
if (_tcsicmp (VrfState->DriverInfo[Index].Name, Current) == 0) {
VrfState->DriverInfo[Index].Verified = TRUE; break; } }
//
// Add the driver to the string with unloaded drivers if this is
// not in the list.
//
if (Index == VrfState->DriverCount) {
if( _tcslen( VrfState->AdditionalDriverNames ) + _tcslen( Current ) >= ARRAY_LENGTH( VrfState->AdditionalDriverNames ) ) { //
// Cannot strcat to AdditionalDriverNames, overflow
//
return FALSE; }
_tcscat (VrfState->AdditionalDriverNames, Current); _tcscat (VrfState->AdditionalDriverNames, TEXT(" ")); }
//
// Restore written character and resume search for the next driver.
//
*End = Save; Current = End; }
//
// Now we have to mark miniports as checked in case we get something
// from the registry string that links against a miniport.
//
for (Index = 0; Index < VrfState->DriverCount; Index++) {
if (VrfState->DriverInfo[Index].Verified == TRUE) {
VrfNotifyDriverSelection (VrfState, Index); } }
//
// The same check should happen for drivers that appear
// in the AdditionalDriverNames buffer. These are drivers
// that are not loaded right now but they still need the miniport
// check.
//
First = VrfState->AdditionalDriverNames; Last = First + _tcslen (VrfState->AdditionalDriverNames);
for (Current = First; Current < Last; Current++) {
if (*Current == TEXT(' ') || *Current == TEXT('\t') || *Current == TEXT('\n')) {
continue; }
//
// Search for a driver name.
//
for (End = Current; *End != 0 && *End != TEXT(' ') && *End != TEXT('\n') && *End != TEXT('\t'); End++) {
// nothing
}
Save = *End; *End = 0;
//
// Find out if there is a miniport linked against this driver.
//
{ LPCTSTR Miniport; ULONG FoundIndex; VRF_DRIVER_LOAD_STATUS LoadStatus;
Miniport = IsMiniportDriver (Current, LoadStatus);
if (Miniport != NULL) {
if (VrfSearchVerifierDriver (VrfState, Miniport, FoundIndex)) {
VrfState->DriverInfo[FoundIndex].Verified = TRUE; } } }
//
// Restore written character and resume search for the next driver.
//
*End = Save; Current = End; }
//
// Finally return
//
return TRUE; }
//
// Function:
//
// GetVerifiedDriversToString
//
// Description:
//
// This function gets the state of settings as they are kept
// in VrfState->DriverInfo and VrfState->AdditionalDriverNames and
// fills VrfState->DriverNames with driver names without duplicates.
//
BOOL GetVerifiedDriversToString (
PVRF_VERIFIER_STATE VrfState ) { ULONG Index; LPTSTR First, Last, Current; ULONG NameLength; TCHAR *Buffer;
//
// Sanity checks
//
if (VrfState == NULL) {
return FALSE; }
Buffer = VrfState->DriverNames;
First = Buffer; Last = First + ARRAY_LENGTH( VrfState->DriverNames ); Current = First; *Current = 0;
for (Index = 0; Index < VrfState->DriverCount; Index++) {
if ( VrfState->DriverInfo[Index].Verified ) {
NameLength = _tcslen (VrfState->DriverInfo[Index].Name);
if (Current + NameLength + 2 >= Last) {
//
// Buffer overflow
//
return FALSE; }
_tcscpy (Current, VrfState->DriverInfo[Index].Name); Current += NameLength; *Current++ = TEXT(' '); *Current = 0; } }
//
// Copy the additional drivers at the end of the driver string
// and avoid duplicates.
//
{ LPTSTR FirstAddtl, CurrentAddtl, LastAddtl, EndAddtl; TCHAR SaveAddtl;
_tcslwr (Buffer); _tcslwr (VrfState->AdditionalDriverNames);
FirstAddtl = VrfState->AdditionalDriverNames; LastAddtl = FirstAddtl + _tcslen (VrfState->AdditionalDriverNames);
for (CurrentAddtl = FirstAddtl; CurrentAddtl < LastAddtl; CurrentAddtl++) {
if (*CurrentAddtl == TEXT(' ') || *CurrentAddtl == TEXT('\t') || *CurrentAddtl == TEXT('\n')) {
continue; }
//
// Search for a driver name.
//
for (EndAddtl = CurrentAddtl; *EndAddtl != TEXT('\0') && *EndAddtl != TEXT(' ') && *EndAddtl != TEXT('\n') && *EndAddtl != TEXT('\t'); EndAddtl++) {
// nothing
}
SaveAddtl = *EndAddtl; *EndAddtl = 0;
if (_tcsstr (Buffer, CurrentAddtl) == NULL) {
_tcscat (Buffer, TEXT(" ")); _tcscat (Buffer, CurrentAddtl);
//
// Figure out if we need to add a miniport to the checked
// drivers string.
//
{ LPCTSTR MiniportName; VRF_DRIVER_LOAD_STATUS LoadStatus;
MiniportName = IsMiniportDriver (CurrentAddtl, LoadStatus);
if (MiniportName == NULL && LoadStatus != VRF_DRIVER_LOAD_SUCCESS) {
switch (LoadStatus) {
case VRF_DRIVER_LOAD_SUCCESS: break;
case VRF_DRIVER_LOAD_CANNOT_FIND_IMAGE:
VrfErrorResourceFormat( IDS_CANT_FIND_IMAGE, CurrentAddtl);
break;
case VRF_DRIVER_LOAD_INVALID_IMAGE:
VrfErrorResourceFormat( IDS_INVALID_IMAGE, CurrentAddtl);
break;
default: ASSERT ( FALSE ); break; }
} else if (MiniportName != NULL && _tcsstr (Buffer, MiniportName) == NULL) {
_tcscat (Buffer, TEXT(" ")); _tcscat (Buffer, MiniportName); } } }
//
// Restore written character and resume search for the next driver.
//
*EndAddtl = SaveAddtl; CurrentAddtl = EndAddtl; }
}
//
// Finish
//
return TRUE; }
BOOL SetAllDriversStatus (
PVRF_VERIFIER_STATE VrfState, BOOL Verified) { ULONG Index;
for (Index = 0; Index < VrfState->DriverCount; Index++) {
VrfState->DriverInfo[Index].Verified = Verified; }
return TRUE; }
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////// Driver selection notification
//////////////////////////////////////////////////////////////////////
LPTSTR Miniport [] = {
TEXT ("videoprt.sys"), TEXT ("scsiport.sys"), NULL };
LPCTSTR IsMiniportDriver (
LPCTSTR DriverName, VRF_DRIVER_LOAD_STATUS &ErrorCode) { IMAGE_BROWSE_INFO Info; TCHAR DriverPath [MAX_PATH]; ULONG Index; BOOL TryAgain = FALSE;
ErrorCode = VRF_DRIVER_LOAD_SUCCESS;
//
// Search for the driver image.
//
if (ImgSearchDriverImage (DriverName, DriverPath, ARRAY_LENGTH( DriverPath ) ) == FALSE) {
ErrorCode = VRF_DRIVER_LOAD_CANNOT_FIND_IMAGE; return NULL; }
//
// Parse the image
//
if (ImgInitializeBrowseInfo (DriverPath, &Info) == FALSE) {
ImgDeleteBrowseInfo (& Info); ErrorCode = VRF_DRIVER_LOAD_INVALID_IMAGE; return NULL; }
//
// Iterate import modules
//
{ PIMAGE_IMPORT_DESCRIPTOR CurrentDescriptor;
CurrentDescriptor = Info.ImportDescriptor;
while (CurrentDescriptor->Characteristics) {
for (Index = 0; Miniport[Index]; Index++) {
//
// We need to apply an address correction to the descriptor name
// because the address in an RVA for the loaded image not for the
// file layout.
//
{ TCHAR NameBuffer [MAX_PATH];
ConvertAnsiStringToTcharString ( (LPBYTE)(CurrentDescriptor->Name + Info.AddressCorrection), strlen( (const char *)( CurrentDescriptor->Name + Info.AddressCorrection ) ), NameBuffer, ARRAY_LENGTH( NameBuffer ) - 1 );
if (_tcsicmp (NameBuffer, Miniport[Index]) == 0) {
ImgDeleteBrowseInfo (& Info); return Miniport[Index]; } } }
CurrentDescriptor++; } }
ImgDeleteBrowseInfo (& Info); return NULL; }
//
// Function:
//
// VrfNotifyDriverSelection
//
// Description:
//
// This function is called from GUI part when a driver is
// selected. In case the driver is linked against a miniport
// driver we have to automatically add to the verified
// drivers list the specific miniport.
//
// Return:
//
// TRUE if an additional driver has been marked selected
// due to indirect linking. FALSE if no change has been
// made.
//
BOOL VrfNotifyDriverSelection (
PVRF_VERIFIER_STATE VerifierState, ULONG Index) { LPCTSTR MiniportName; ULONG FoundIndex; VRF_DRIVER_LOAD_STATUS LoadStatus;
//
// Sanity checks
//
if ( Index >= VerifierState->DriverCount ) {
return FALSE; }
//
// If this is a driver that links against a miniport as
// opposed to ntoskrnl we should add the miniport to the
// verified list.
//
try {
MiniportName = IsMiniportDriver (
VerifierState->DriverInfo[Index].Name, LoadStatus);
switch (LoadStatus) {
case VRF_DRIVER_LOAD_SUCCESS: break;
case VRF_DRIVER_LOAD_CANNOT_FIND_IMAGE:
VrfErrorResourceFormat( IDS_CANT_FIND_IMAGE, VerifierState->DriverInfo[Index].Name);
break;
case VRF_DRIVER_LOAD_INVALID_IMAGE:
VrfErrorResourceFormat( IDS_INVALID_IMAGE, VerifierState->DriverInfo[Index].Name);
break;
default: ASSERT ( FALSE ); break; }
} catch (...) {
//
// Protect against a blunder in the image parsing code
//
VrfErrorResourceFormat( IDS_INVALID_IMAGE, VerifierState->DriverInfo[Index].Name);
return FALSE; }
if (MiniportName != NULL) {
if (VrfSearchVerifierDriver (VerifierState, MiniportName, FoundIndex) == FALSE) {
return FALSE; }
VerifierState->DriverInfo[FoundIndex].Verified = TRUE; return TRUE; }
return FALSE; }
//////////////////////////////////////////////////////////////////////
BOOL VrfGetVersionInfo( LPTSTR lptstrFileName, LPTSTR lptstrCompany, int nCompanyBufferLength, LPTSTR lptstrVersion, int nVersionBufferLength ) { DWORD dwWholeBlockSize; DWORD dwDummyHandle; UINT uInfoLengthInTChars; LPVOID lpWholeVerBlock; LPVOID lpTranslationInfoBuffer; LPVOID lpVersionString; LPVOID lpCompanyString; BOOL bResult; TCHAR strLocale[ 32 ]; TCHAR strBlockName[ 64 ]; TCHAR strDriverPath[ MAX_PATH ];
//
// sanity checks
//
if( lptstrFileName == NULL || lptstrCompany == NULL || nCompanyBufferLength <= 0 || lptstrVersion == NULL || nVersionBufferLength <= 0 ) { ASSERT( FALSE ); return FALSE; }
//
// get the full driver path
//
bResult = ImgSearchDriverImage( lptstrFileName, strDriverPath, ARRAY_LENGTH( strDriverPath ) );
if( bResult != TRUE ) { return FALSE; }
//
// get the size of the file info block
//
dwWholeBlockSize = GetFileVersionInfoSize( strDriverPath, &dwDummyHandle );
if( dwWholeBlockSize == 0 ) { return FALSE; }
//
// allocate the buffer for the version information
//
lpWholeVerBlock = malloc( dwWholeBlockSize );
if( lpWholeVerBlock == NULL ) { return FALSE; }
//
// get the version information
//
bResult = GetFileVersionInfo( strDriverPath, dwDummyHandle, dwWholeBlockSize, lpWholeVerBlock );
if( bResult != TRUE ) { free( lpWholeVerBlock );
return FALSE; }
//
// get the locale info
//
bResult = VerQueryValue( lpWholeVerBlock, _T( "\\VarFileInfo\\Translation" ), &lpTranslationInfoBuffer, &uInfoLengthInTChars );
if( bResult != TRUE || lpTranslationInfoBuffer == NULL ) { free( lpWholeVerBlock );
return FALSE; }
//
// Locale info comes back as two little endian words.
// Flip 'em, 'cause we need them big endian for our calls.
//
_stprintf( strLocale, _T( "%02X%02X%02X%02X" ), HIBYTE( LOWORD ( * (LPDWORD) lpTranslationInfoBuffer) ), LOBYTE( LOWORD ( * (LPDWORD) lpTranslationInfoBuffer) ), HIBYTE( HIWORD ( * (LPDWORD) lpTranslationInfoBuffer) ), LOBYTE( HIWORD ( * (LPDWORD) lpTranslationInfoBuffer) ) );
//
// get the file version
//
_stprintf( strBlockName, _T( "\\StringFileInfo\\%s\\FileVersion" ), strLocale );
bResult = VerQueryValue( lpWholeVerBlock, strBlockName, &lpVersionString, &uInfoLengthInTChars );
if( bResult != TRUE ) { free( lpWholeVerBlock );
return FALSE; }
if( uInfoLengthInTChars > (UINT)nVersionBufferLength ) { uInfoLengthInTChars = (UINT)nVersionBufferLength; }
if( uInfoLengthInTChars == 0 ) { *lptstrVersion = 0; } else { MoveMemory( lptstrVersion, lpVersionString, uInfoLengthInTChars * sizeof( TCHAR ) );
//
// we need to zero terminate the string for above case
// uInfoLengthInTChars > (UINT)nVersionBufferLength
//
lptstrVersion[ uInfoLengthInTChars - 1 ] = 0; }
//
// get the company name
//
_stprintf( strBlockName, _T( "\\StringFileInfo\\%s\\CompanyName" ), strLocale );
bResult = VerQueryValue( lpWholeVerBlock, strBlockName, &lpCompanyString, &uInfoLengthInTChars );
if( bResult != TRUE ) { free( lpWholeVerBlock );
return FALSE; }
if( uInfoLengthInTChars > (UINT)nCompanyBufferLength ) { uInfoLengthInTChars = (UINT)nCompanyBufferLength; }
if( uInfoLengthInTChars == 0 ) { *lptstrCompany = 0; } else { MoveMemory( lptstrCompany, lpCompanyString, uInfoLengthInTChars * sizeof( TCHAR ) );
//
// we need to zero terminate the string for above case
// uInfoLengthInTChars > (UINT)nCompanyBufferLength
//
lptstrCompany[ uInfoLengthInTChars - 1 ] = 0; }
//
// clean-up
//
free( lpWholeVerBlock );
return TRUE; }
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////// String conversion
//////////////////////////////////////////////////////////////////////
//
// Function:
//
// ConvertAnsiStringToTcharString
//
// Description:
//
// This function converts an ANSI string to a TCHAR string,
// that is ANSO or UNICODE.
//
// The function is needed because the system returns the active
// modules as ANSI strings.
//
BOOL ConvertAnsiStringToTcharString (
LPBYTE Source, ULONG SourceLength, LPTSTR Destination, ULONG DestinationLength) { int nCharsConverted; int nBytesToTranslate;
nBytesToTranslate = (int)( (SourceLength < DestinationLength) ? SourceLength : DestinationLength ) * sizeof( char );
nCharsConverted = MultiByteToWideChar( CP_ACP, MB_ERR_INVALID_CHARS, (LPCSTR)Source, nBytesToTranslate, Destination, DestinationLength );
ASSERT( nBytesToTranslate == nCharsConverted );
if( nCharsConverted > 0 ) { Destination[ nCharsConverted ] = 0;
CharLower( Destination ); }
return TRUE; }
//////////////////////////////////////////////////////////////////////
////////////////////////////////////////////// Command-line processing
//////////////////////////////////////////////////////////////////////
BOOL VrfDumpStateToFile( FILE *file, BOOL bConvertToOEM ) { static KRN_VERIFIER_STATE KrnState;
UINT Index; SYSTEMTIME SystemTime; TCHAR strLocalTime[ 64 ]; TCHAR strLocalDate[ 64 ];
if( file == NULL ) return FALSE;
//
// output the date&time in the current user format
//
GetLocalTime( &SystemTime );
if( GetDateFormat( LOCALE_USER_DEFAULT, 0, &SystemTime, NULL, strLocalDate, ARRAY_LENGTH( strLocalDate ) ) ) { VrfFTPrintf( bConvertToOEM, file, _T( "%s, " ), strLocalDate ); } else { ASSERT( FALSE ); }
if( GetTimeFormat( LOCALE_USER_DEFAULT, 0, &SystemTime, NULL, strLocalTime, ARRAY_LENGTH( strLocalTime ) ) ) { VrfFTPrintf( bConvertToOEM, file, _T( "%s\n" ), strLocalTime); } else { ASSERT( FALSE );
VrfFTPrintf( bConvertToOEM, file, _T( "\n" ) ); }
//
// get the current verifier statistics
//
if (KrnGetSystemVerifierState (& KrnState) == FALSE) {
VrfOuputStringFromResources( IDS_CANTGET_VERIF_STATE, bConvertToOEM, file );
return FALSE; }
if (KrnState.DriverCount == 0) {
//
// no statistics to dump
//
return VrfOuputStringFromResources( IDS_NO_DRIVER_VERIFIED, bConvertToOEM, file ); } else {
//
// dump the counters
//
//
// global counters
//
if( ( ! VrfFTPrintfResourceFormat( bConvertToOEM, file, IDS_LEVEL, KrnState.Level ) ) || ( ! VrfFTPrintfResourceFormat( bConvertToOEM, file, IDS_RAISEIRQLS, KrnState.RaiseIrqls ) ) || ( ! VrfFTPrintfResourceFormat( bConvertToOEM, file, IDS_ACQUIRESPINLOCKS, KrnState.AcquireSpinLocks ) ) || ( ! VrfFTPrintfResourceFormat( bConvertToOEM, file, IDS_SYNCHRONIZEEXECUTIONS, KrnState.SynchronizeExecutions) ) ||
( ! VrfFTPrintfResourceFormat( bConvertToOEM, file, IDS_ALLOCATIONSATTEMPTED, KrnState.AllocationsAttempted) ) || ( ! VrfFTPrintfResourceFormat( bConvertToOEM, file, IDS_ALLOCATIONSSUCCEEDED, KrnState.AllocationsSucceeded) ) || ( ! VrfFTPrintfResourceFormat( bConvertToOEM, file, IDS_ALLOCATIONSSUCCEEDEDSPECIALPOOL, KrnState.AllocationsSucceededSpecialPool) ) || ( ! VrfFTPrintfResourceFormat( bConvertToOEM, file, IDS_ALLOCATIONSWITHNOTAG, KrnState.AllocationsWithNoTag) ) ||
( ! VrfFTPrintfResourceFormat( bConvertToOEM, file, IDS_ALLOCATIONSFAILED, KrnState.AllocationsFailed) ) || ( ! VrfFTPrintfResourceFormat( bConvertToOEM, file, IDS_ALLOCATIONSFAILEDDELIBERATELY, KrnState.AllocationsFailedDeliberately) ) ||
( ! VrfFTPrintfResourceFormat( bConvertToOEM, file, IDS_TRIMS, KrnState.Trims) ) ||
( ! VrfFTPrintfResourceFormat( bConvertToOEM, file, IDS_UNTRACKEDPOOL, KrnState.UnTrackedPool) ) ) {
return FALSE; }
//
// per driver counters
//
if( ! VrfOuputStringFromResources( IDS_THE_VERIFIED_DRIVERS, bConvertToOEM, file ) ) { return FALSE; }
for ( Index = 0; Index < KrnState.DriverCount; Index++) {
VrfFTPrintf( bConvertToOEM, file, _T( "\n" ) );
if( VrfFTPrintfResourceFormat( bConvertToOEM, file, IDS_NAME_LOADS_UNLOADS, KrnState.DriverInfo[Index].Name, KrnState.DriverInfo[Index].Loads, KrnState.DriverInfo[Index].Unloads) == FALSE ) { return FALSE; }
//
// pool statistics
//
if( ( ! VrfFTPrintfResourceFormat( bConvertToOEM, file, IDS_CURRENTPAGEDPOOLALLOCATIONS, KrnState.DriverInfo[Index].CurrentPagedPoolAllocations) ) || ( ! VrfFTPrintfResourceFormat( bConvertToOEM, file, IDS_CURRENTNONPAGEDPOOLALLOCATIONS, KrnState.DriverInfo[Index].CurrentNonPagedPoolAllocations) ) || ( ! VrfFTPrintfResourceFormat( bConvertToOEM, file, IDS_PEAKPAGEDPOOLALLOCATIONS, KrnState.DriverInfo[Index].PeakPagedPoolAllocations) ) || ( ! VrfFTPrintfResourceFormat( bConvertToOEM, file, IDS_PEAKNONPAGEDPOOLALLOCATIONS, KrnState.DriverInfo[Index].PeakNonPagedPoolAllocations) ) ||
( ! VrfFTPrintfResourceFormat( bConvertToOEM, file, IDS_PAGEDPOOLUSAGEINBYTES, (ULONG) KrnState.DriverInfo[Index].PagedPoolUsageInBytes) ) || ( ! VrfFTPrintfResourceFormat( bConvertToOEM, file, IDS_NONPAGEDPOOLUSAGEINBYTES, (ULONG) KrnState.DriverInfo[Index].NonPagedPoolUsageInBytes) ) || ( ! VrfFTPrintfResourceFormat( bConvertToOEM, file, IDS_PEAKPAGEDPOOLUSAGEINBYTES, (ULONG) KrnState.DriverInfo[Index].PeakPagedPoolUsageInBytes) ) || ( ! VrfFTPrintfResourceFormat( bConvertToOEM, file, IDS_PEAKNONPAGEDPOOLUSAGEINBYTES, (ULONG) KrnState.DriverInfo[Index].PeakNonPagedPoolUsageInBytes) ) ) { return FALSE; } } }
return TRUE; }
//////////////////////////////////////////////////////////////////////
void PrintHelpInformation() { VrfTPrintfResourceFormat( IDS_HELP_LINE1, VER_PRODUCTVERSION_STR );
VrfPrintNarrowStringOEMFormat( VER_LEGALCOPYRIGHT_STR );
VrfPrintStringFromResources( IDS_HELP_LINE3 ); VrfPrintStringFromResources( IDS_HELP_LINE4 ); VrfPrintStringFromResources( IDS_HELP_LINE5 ); VrfPrintStringFromResources( IDS_HELP_LINE6 ); VrfPrintStringFromResources( IDS_HELP_LINE7 ); VrfPrintStringFromResources( IDS_HELP_LINE8 ); VrfPrintStringFromResources( IDS_HELP_LINE9 ); VrfPrintStringFromResources( IDS_HELP_LINE10 ); VrfPrintStringFromResources( IDS_HELP_LINE11 ); VrfPrintStringFromResources( IDS_HELP_LINE12 ); VrfPrintStringFromResources( IDS_HELP_LINE13 ); VrfPrintStringFromResources( IDS_HELP_LINE14 ); VrfPrintStringFromResources( IDS_HELP_LINE15 ); VrfPrintStringFromResources( IDS_HELP_LINE16 ); VrfPrintStringFromResources( IDS_HELP_LINE17 ); VrfPrintStringFromResources( IDS_HELP_LINE18 ); VrfPrintStringFromResources( IDS_HELP_LINE19 ); VrfPrintStringFromResources( IDS_HELP_LINE20 ); VrfPrintStringFromResources( IDS_HELP_LINE21 ); VrfPrintStringFromResources( IDS_HELP_LINE22 ); VrfPrintStringFromResources( IDS_HELP_LINE23 ); VrfPrintStringFromResources( IDS_HELP_LINE24 ); VrfPrintStringFromResources( IDS_HELP_LINE25 ); VrfPrintStringFromResources( IDS_HELP_LINE26 ); VrfPrintStringFromResources( IDS_HELP_LINE27 ); VrfPrintStringFromResources( IDS_HELP_LINE28 ); VrfPrintStringFromResources( IDS_HELP_LINE29 ); VrfPrintStringFromResources( IDS_HELP_LINE30 ); VrfPrintStringFromResources( IDS_HELP_LINE31 ); }
//////////////////////////////////////////////////////////////////////
DWORD VrfExecuteCommandLine (
int Count, LPTSTR Args[]) { static KRN_VERIFIER_STATE KrnState;
ULONG Flags; ULONG IoLevel; int Index; UINT LoadStringResult; VRF_DRIVER_LOAD_STATUS LoadStatus; BOOL CreateLog; LPTSTR LogFileName; DWORD LogInterval; FILE *file; BOOL bFlagsSpecified = FALSE; BOOL bIoLevelSpecified = FALSE; BOOL bNamesSpecified = FALSE; BOOL bVolatileSpecified = FALSE; TCHAR strDriver[ 64 ]; DWORD nReturnValue; NTSTATUS Status; BOOL bResult; BOOL bIoVerifierEnabled; ULONG SysIoVerifierLevel; TCHAR Names [4196]; TCHAR OldNames [4196]; TCHAR strCmdLineOption[ 128 ]; TCHAR WarningBuffer [256];
g_bCommandLineMode = TRUE; nReturnValue = EXIT_CODE_SUCCESS;
ASSERT (Count != 0);
Flags = 1; Names[0] = 0;
//
// Search for help
//
if( GetStringFromResources( IDS_HELP_CMDLINE_SWITCH, strCmdLineOption, ARRAY_LENGTH( strCmdLineOption ) ) ) { if (Count == 2 && _tcsicmp (Args[1], strCmdLineOption) == 0) { PrintHelpInformation();
return nReturnValue; } }
//
// Figure out if we are on a valid build for the
// driver verifier functionality.
//
if (g_OsVersion.dwMajorVersion < 5 || g_OsVersion.dwBuildNumber < 1954) {
//
// Right now we do not do anything if we do not have the right build.
//
VrfPrintStringFromResources( IDS_BUILD_WARN );
return nReturnValue; }
//
// Search for /reset
//
if( GetStringFromResources( IDS_RESET_CMDLINE_SWITCH, strCmdLineOption, ARRAY_LENGTH( strCmdLineOption ) ) ) { if (Count == 2 && _tcsicmp (Args[1], strCmdLineOption) == 0) { if( VrfClearAllVerifierSettings() ) { return EXIT_CODE_REBOOT_NEEDED; } else { return EXIT_CODE_ERROR; } } }
//
// Search for /log
//
CreateLog = FALSE;
if( GetStringFromResources( IDS_LOG_CMDLINE_SWITCH, strCmdLineOption, ARRAY_LENGTH( strCmdLineOption ) ) ) {
for (Index = 1; Index < Count - 1; Index++) { if (_tcsicmp (Args[Index], strCmdLineOption ) == 0) { CreateLog = TRUE;
LogFileName = Args[Index + 1];
break; } } }
if( CreateLog ) { //
// Default Value
//
LogInterval = 30000; // 30 sec
//
// Search for /interval
//
if( GetStringFromResources( IDS_INTERVAL_CMDLINE_SWITCH, strCmdLineOption, ARRAY_LENGTH( strCmdLineOption ) ) ) { for (Index = 1; Index < Count - 1; Index++) { if (_tcsicmp (Args[Index], strCmdLineOption) == 0) { LogInterval = _ttoi (Args[Index + 1]) * 1000;
if( LogInterval == 0 ) { LogInterval = 30000; // 30 sec
} } } }
//
// Infinite loop
//
while( TRUE ) { //
// Open the file
//
file = _tfopen( LogFileName, TEXT("a+") );
if( file == NULL ) { //
// print a error message
//
VrfTPrintfResourceFormat( IDS_CANT_APPEND_FILE, LogFileName );
break; }
//
// Dump current information
//
if( ! VrfDumpStateToFile ( file, FALSE ) ) {
//
// Insufficient disk space ?
//
VrfTPrintfResourceFormat( IDS_CANT_WRITE_FILE, LogFileName ); }
fflush( file );
VrfFTPrintf( FALSE, file, TEXT("\n\n") );
//
// Close the file
//
fclose( file );
//
// Sleep
//
Sleep( LogInterval ); }
return nReturnValue; }
//
// Search for /query
//
if( GetStringFromResources( IDS_QUERY_CMDLINE_SWITCH, strCmdLineOption, ARRAY_LENGTH( strCmdLineOption ) ) ) { if (Count == 2 && _tcsicmp (Args[1], strCmdLineOption) == 0) { VrfDumpStateToFile ( stdout, TRUE ); fflush( stdout );
return nReturnValue; } }
//
// Search for /flags
//
if( GetStringFromResources( IDS_FLAGS_CMDLINE_SWITCH, strCmdLineOption, ARRAY_LENGTH( strCmdLineOption ) ) ) { for (Index = 1; Index < Count - 1; Index++) { if (_tcsicmp (Args[Index], strCmdLineOption) == 0) { Flags = _ttoi (Args[Index + 1]);
Flags &= VerifierAllOptions;
bFlagsSpecified = TRUE; } } }
//
// Search for /iolevel
//
if( GetStringFromResources( IDS_IOLEVEL_CMDLINE_SWITCH, strCmdLineOption, ARRAY_LENGTH( strCmdLineOption ) ) ) { for (Index = 1; Index < Count - 1; Index++) { if (_tcsicmp (Args[Index], strCmdLineOption) == 0) { IoLevel = _ttoi (Args[Index + 1]);
if( ( IoLevel != 0 ) && ( IoLevel <= IO_VERIFICATION_LEVEL_MAX ) ) { bIoLevelSpecified = TRUE; } } } }
//
// Search for /all
//
if( GetStringFromResources( IDS_ALL_CMDLINE_SWITCH, strCmdLineOption, ARRAY_LENGTH( strCmdLineOption ) ) ) { for (Index = 1; Index < Count; Index++) { if (_tcsicmp (Args[Index], strCmdLineOption) == 0) { _tcscat (Names, TEXT("*"));
bNamesSpecified = TRUE; } } }
//
// Search for /driver
//
LoadStringResult = LoadString ( // cannot reuse the static string buffer
GetModuleHandle (NULL), IDS_DRIVER_CMDLINE_SWITCH, strDriver, sizeof strDriver / sizeof (TCHAR));
ASSERT (LoadStringResult > 0);
if (LoadStringResult > 0) {
for (Index = 1; Index < Count - 1; Index++) {
if (_tcsicmp (Args[Index], strDriver) == 0) {
int NameIndex; LPCTSTR MiniportName;
bNamesSpecified = ( Index < ( Count - 1 ) ); // have some driver names?
for (NameIndex = Index + 1; NameIndex < Count; NameIndex++) {
_tcscat (Names, Args[NameIndex]); _tcscat (Names, TEXT(" "));
MiniportName = IsMiniportDriver (Args[NameIndex], LoadStatus);
if (MiniportName == NULL && LoadStatus != VRF_DRIVER_LOAD_SUCCESS) {
switch (LoadStatus) { case VRF_DRIVER_LOAD_SUCCESS: break;
case VRF_DRIVER_LOAD_CANNOT_FIND_IMAGE:
VrfTPrintfResourceFormat( IDS_CANT_FIND_IMAGE, Args[NameIndex] );
//
// newline
//
VrfPutTS( _TEXT( "" ) );
break;
case VRF_DRIVER_LOAD_INVALID_IMAGE:
VrfTPrintfResourceFormat( IDS_INVALID_IMAGE, Args[NameIndex] );
//
// newline
//
VrfPutTS( _TEXT( "" ) );
break;
default: ASSERT ( FALSE ); break; } } else if (MiniportName != NULL && _tcsstr (Names, MiniportName) == NULL) {
_tcscat (Names, MiniportName); _tcscat (Names, TEXT(" ")); } }
break; } } }
//
// Search for /volatile
//
if( GetStringFromResources( IDS_DONTREBOOT_CMDLINE_SWITCH, strCmdLineOption, ARRAY_LENGTH( strCmdLineOption ) ) ) { for (Index = 1; Index < Count; Index++) {
if (_tcsicmp (Args[Index], strCmdLineOption) == 0) { bVolatileSpecified = TRUE;
//
// found /volatile in the command line
//
if( bFlagsSpecified && ! bNamesSpecified ) { if( g_OsVersion.dwBuildNumber >= 2055 ) { //
// see if there are any verifier flags active
//
if (KrnGetSystemVerifierState (& KrnState) == FALSE) { //
// cannot get current verifier settings
//
VrfPrintStringFromResources( IDS_CANTGET_VERIF_STATE );
return EXIT_CODE_ERROR; } else { //
// compare the active flags with the new ones
//
if( KrnState.DriverCount != 0 ) { //
// there are some drivers currently verified
//
if( KrnState.Level != Flags ) { //
// try to change something on the fly
//
bResult = VrfSetVolatileFlags( Flags );
if( bResult ) { //
// success - tell the user what flags have changed
//
VrfDumpChangedSettings( KrnState.Level, Flags );
return EXIT_CODE_SUCCESS; } else { //
// cannot change settings
//
return EXIT_CODE_ERROR; } } else { //
// the specified flags are the same as the active ones
//
VrfPrintStringFromResources( IDS_SAME_FLAGS_AS_ACTIVE );
return EXIT_CODE_SUCCESS; } } else { VrfPrintStringFromResources( IDS_NO_DRIVER_VERIFIED );
return EXIT_CODE_SUCCESS; } } } else { //
// the build is too old - we cannot change options on the fly
//
VrfPrintStringFromResources( IDS_CANT_CHANGE_SETTINGS_BUILD_OLD );
return EXIT_CODE_ERROR; } } else { //
// the flags were not specified - look for /adddriver, /removedriver
//
if( VrfVolatileAddOrRemoveDriversCmdLine( Count, Args ) == TRUE ) { //
// changed the verified drivers list
//
return EXIT_CODE_SUCCESS; } else { //
// nothing to change
//
VrfPrintStringFromResources( IDS_NO_SETTINGS_WERE_CHANGED );
return EXIT_CODE_ERROR; } }
//
// Unreached - the code above will always return from the function.
//
ASSERT( FALSE );
return EXIT_CODE_ERROR; } } } else { ASSERT( FALSE ); }
//
// Write everything to the registry
//
if( !bVolatileSpecified && ( bFlagsSpecified || bNamesSpecified ) ) { HKEY MmKey = NULL; LONG Result; DWORD Value; DWORD OldValue;
Result = RegOpenKeyEx (
HKEY_LOCAL_MACHINE, RegMemoryManagementKeyName, 0, KEY_SET_VALUE | KEY_QUERY_VALUE, &MmKey);
if (Result != ERROR_SUCCESS) {
if( Result == ERROR_ACCESS_DENIED ) {
VrfPrintStringFromResources( IDS_ACCESS_IS_DENIED );
return EXIT_CODE_ERROR; } else {
VrfTPrintfResourceFormat( IDS_REGOPENKEYEX_FAILED, RegMemoryManagementKeyName, (DWORD)Result);
//
// newline
//
VrfPutTS( _TEXT( "" ) );
return EXIT_CODE_ERROR; } }
if( bFlagsSpecified ) { Value = Flags;
if( ReadRegistryValue ( MmKey, RegVerifyDriverLevelValueName, &OldValue, 0) == FALSE) { RegCloseKey (MmKey); return EXIT_CODE_ERROR; }
if (WriteRegistryValue (MmKey, RegVerifyDriverLevelValueName, Value) == FALSE) { RegCloseKey (MmKey); return EXIT_CODE_ERROR; }
bIoVerifierEnabled = ( (Flags & DRIVER_VERIFIER_IO_CHECKING) != 0 );
if( bIoVerifierEnabled && bIoLevelSpecified == TRUE ) { SysIoVerifierLevel = IoLevel; } else { SysIoVerifierLevel = 0; }
if ( ! SetSysIoVerifierSettings ( SysIoVerifierLevel ) ) { RegCloseKey (MmKey); return EXIT_CODE_ERROR; }
if( OldValue != Value ) {
nReturnValue = EXIT_CODE_REBOOT_NEEDED; } }
if( bNamesSpecified ) { if (ReadMmString (MmKey, RegVerifyDriversValueName, OldNames, sizeof( OldNames ) ) == FALSE) { RegCloseKey (MmKey); return EXIT_CODE_ERROR; }
if (WriteMmString (MmKey, RegVerifyDriversValueName, Names) == FALSE) { RegCloseKey (MmKey); return EXIT_CODE_ERROR; }
if( _tcsicmp (OldNames, Names) ){
nReturnValue = EXIT_CODE_REBOOT_NEEDED; } }
RegCloseKey (MmKey);
} else { PrintHelpInformation(); }
return nReturnValue; }
//////////////////////////////////////////////////////////////////////
BOOL GetStringFromResources(
UINT uIdResource, TCHAR *strBuffer, int nBufferLength ) { UINT LoadStringResult;
if( strBuffer == NULL || nBufferLength < 1 ) { ASSERT( FALSE ); return FALSE; }
LoadStringResult = LoadString (
GetModuleHandle (NULL), uIdResource, strBuffer, nBufferLength );
ASSERT (LoadStringResult > 0);
return (LoadStringResult > 0); }
//////////////////////////////////////////////////////////////////////
void VrfPrintStringFromResources(
UINT uIdResource) { TCHAR strText[ 256 ];
if( GetStringFromResources( uIdResource, strText, ARRAY_LENGTH( strText ) ) ) { VrfOutputWideStringOEMFormat( strText, TRUE, stdout ); } }
//////////////////////////////////////////////////////////////////////
BOOL VrfOuputStringFromResources(
UINT uIdResource, BOOL bConvertToOEM, FILE *file ) { TCHAR strText[ 256 ];
BOOL bResult;
bResult = TRUE;
if( GetStringFromResources( uIdResource, strText, ARRAY_LENGTH( strText ) ) ) { if( bConvertToOEM ) { VrfOutputWideStringOEMFormat( strText, TRUE, file ); } else { bResult = ( _fputts( strText, file ) >= 0 ); } }
return bResult; }
//////////////////////////////////////////////////////////////////////
void VrfDumpChangedSettings(
UINT OldFlags, UINT NewFlags ) { UINT uDifferentFlags;
OldFlags &= VerifierModifyableOptions; NewFlags &= VerifierModifyableOptions;
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 ); } }
//////////////////////////////////////////////////////////////////////
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 VrfPrintNarrowStringOEMFormat(
char *szText ) { char szTextOEM[ 512 ];
ASSERT( szText != NULL );
//
// make a copy of the string
//
strncpy( szTextOEM, szText, ARRAY_LENGTH( szTextOEM ) - 1 );
szTextOEM[ ARRAY_LENGTH( szTextOEM ) - 1 ] = (char)0;
//
// convert the string to OEM
//
if( CharToOemA( szTextOEM, szTextOEM ) ) { puts( szTextOEM ); } else { ASSERT( FALSE ); } }
//////////////////////////////////////////////////////////////////////
BOOL VrfOutputWideStringOEMFormat(
LPTSTR strText, BOOL bAppendNewLine, FILE *file ) { TCHAR strTextCopy[ 512 ]; BOOL bResult; char szTextOEM[ 512 ];
if( strText == NULL || file == NULL ) { ASSERT( FALSE ); return FALSE; }
//
// make a copy of the string
//
_tcsncpy( strTextCopy, strText, ARRAY_LENGTH( strTextCopy ) - 1 );
strTextCopy[ ARRAY_LENGTH( strTextCopy ) - 1 ] = (TCHAR)0;
//
// convert the string to OEM
//
if( CharToOem( strTextCopy, szTextOEM ) ) { bResult = ( fputs( szTextOEM, file ) >= 0 );
if( bResult && bAppendNewLine ) { bResult = ( fputs( "\n", file ) >= 0 ); } } else { ASSERT( FALSE ); bResult = FALSE; }
return bResult; }
//////////////////////////////////////////////////////////////////////
BOOL __cdecl VrfFTPrintf( BOOL bConvertToOEM, FILE *file, LPTSTR fmt, ...) { BOOL bResult; TCHAR strMessage[ 256 ]; va_list prms;
if( fmt == NULL || file == NULL ) { ASSERT( FALSE ); return FALSE; }
va_start (prms, fmt);
_vsntprintf ( strMessage, ARRAY_LENGTH( strMessage ), fmt, prms);
if( bConvertToOEM ) { bResult = VrfOutputWideStringOEMFormat( strMessage, FALSE, file ); } else { bResult = ( _ftprintf( file, _T( "%s" ), strMessage ) >= 0 ); }
va_end (prms);
return bResult; }
//////////////////////////////////////////////////////////////////////
BOOL __cdecl VrfFTPrintfResourceFormat( BOOL bConvertToOEM, FILE *file, UINT uIdResFmtString, ...) { TCHAR strFormat[ 256 ]; TCHAR strMessage[ 256 ]; va_list prms; BOOL bResult;
bResult = TRUE;
if( GetStringFromResources( uIdResFmtString, strFormat, ARRAY_LENGTH( strFormat ) ) ) { va_start (prms, uIdResFmtString);
_vsntprintf ( strMessage, ARRAY_LENGTH( strMessage ), strFormat, prms);
if( bConvertToOEM ) { bResult = VrfOutputWideStringOEMFormat( strMessage, FALSE, file ); } else { bResult = ( _ftprintf( file, _T( "%s" ), strMessage ) >= 0 ); }
va_end (prms); } else { ASSERT( FALSE ); bResult = FALSE; }
return bResult; }
//////////////////////////////////////////////////////////////////////
void __cdecl VrfTPrintfResourceFormat( UINT uIdResFmtString, ...) { TCHAR strMessage[ 256 ]; TCHAR strFormat[ 256 ]; va_list prms;
//
// get the format string
//
if( GetStringFromResources( uIdResFmtString, strFormat, ARRAY_LENGTH( strFormat ) ) ) { va_start (prms, uIdResFmtString);
//
// get the message string as UNICODE
//
_vsntprintf ( strMessage, ARRAY_LENGTH( strMessage ), strFormat, prms);
//
// output it as OEM
//
VrfOutputWideStringOEMFormat( strMessage, FALSE, stdout );
va_end (prms); }
return; }
//////////////////////////////////////////////////////////////////////
void VrfPutTS( LPTSTR strText ) { if( strText == NULL ) { ASSERT( FALSE ); return; }
VrfOutputWideStringOEMFormat( strText, TRUE, stdout ); }
//////////////////////////////////////////////////////////////////////
//
// Support for dynamic set of verified drivers
//
BOOL VrfVolatileAddDriver(
const WCHAR *szDriverName ) { UNICODE_STRING usDriverName; NTSTATUS Status; UINT uIdErrorString;
//
// enable debug privilege
//
if( g_bPrivegeEnabled != TRUE ) { g_bPrivegeEnabled = VrfEnableDebugPrivilege();
if( g_bPrivegeEnabled != TRUE ) { return FALSE; } }
//
// Must driver name as a UNICODE_STRING
//
ASSERT( szDriverName != NULL ); RtlInitUnicodeString( &usDriverName, szDriverName );
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, szDriverName, Status );
return FALSE; }
VrfErrorResourceFormat( uIdErrorString, szDriverName );
return FALSE; }
return TRUE; }
//////////////////////////////////////////////////////////////////////
BOOL VrfVolatileRemoveDriver(
const WCHAR *szDriverName ) { UNICODE_STRING usDriverName; NTSTATUS Status; UINT uIdErrorString;
//
// enable debug privilege
//
if( g_bPrivegeEnabled != TRUE ) { g_bPrivegeEnabled = VrfEnableDebugPrivilege();
if( g_bPrivegeEnabled != TRUE ) { return FALSE; } }
//
// Must driver name as a UNICODE_STRING
//
ASSERT( szDriverName != NULL ); RtlInitUnicodeString( &usDriverName, szDriverName );
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, szDriverName, Status );
return FALSE; }
VrfErrorResourceFormat( uIdErrorString, szDriverName );
return FALSE; }
return TRUE; }
//////////////////////////////////////////////////////////////////////
BOOL VrfVolatileAddOrRemoveDriversCmdLine(
int nArgsNo, LPTSTR szCmdLineArgs[] ) { int nCrtArg; BOOL bChangedSomething; BOOL bResult; BOOL bAddDriverSpecified = FALSE; BOOL bRemoveDriverSpecified = FALSE; TCHAR szAddDriverOption[ 128 ]; TCHAR szRemoveDriverOption[ 128 ];
//
// /loaddriver and /removedriver command line options
//
bResult = GetStringFromResources( IDS_ADDDRIVER_CMDLINE_SWITCH, szAddDriverOption, ARRAY_LENGTH( szAddDriverOption ) );
if( bResult != TRUE ) { return FALSE; }
bResult = GetStringFromResources( IDS_REMOVEDRIVER_CMDLINE_SWITCH, szRemoveDriverOption, ARRAY_LENGTH( szRemoveDriverOption ) );
if( bResult != TRUE ) { return FALSE; }
//
// parse all the cmd line args
//
for( nCrtArg = 0; nCrtArg < nArgsNo; nCrtArg++ ) { if( _tcsicmp( szCmdLineArgs[ nCrtArg ], szAddDriverOption ) == 0 ) { //
// /adddriver
//
bAddDriverSpecified = TRUE; bRemoveDriverSpecified = FALSE; } else { if( _tcsicmp( szCmdLineArgs[ nCrtArg ], szRemoveDriverOption ) == 0 ) { //
// /removedriver
//
bRemoveDriverSpecified = TRUE; bAddDriverSpecified = FALSE; } else { if( bAddDriverSpecified ) { //
// this must be a driver name to be added
//
if( VrfVolatileAddDriver( szCmdLineArgs[ nCrtArg ] ) ) { bChangedSomething = TRUE;
VrfTPrintfResourceFormat( IDS_DYN_ADD_VERIFIED_NOW, szCmdLineArgs[ nCrtArg ] ); } } else { if( bRemoveDriverSpecified ) { //
// this must be a driver name to be added
//
if( VrfVolatileRemoveDriver( szCmdLineArgs[ nCrtArg ] ) ) { bChangedSomething = TRUE;
VrfTPrintfResourceFormat( IDS_DYN_ADD_NOT_VERIFIED_NOW, szCmdLineArgs[ nCrtArg ] ); } } } } } }
return bChangedSomething; }
//
// end of module: verify.cxx
//
|