windows-nt/Source/XPSP1/NT/sdktools/verifier/win2k/verify.cxx
2020-09-26 16:20:57 +08:00

4113 lines
92 KiB
C++

//
// 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
//