You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1876 lines
47 KiB
1876 lines
47 KiB
//
|
|
// Driver Verifier UI
|
|
// Copyright (c) Microsoft Corporation, 1999
|
|
//
|
|
//
|
|
//
|
|
// module: VSetting.cpp
|
|
// author: DMihai
|
|
// created: 11/1/00
|
|
//
|
|
// Description
|
|
//
|
|
// Implementation of the CVerifierSettings class.
|
|
//
|
|
|
|
|
|
#include "stdafx.h"
|
|
#include "verifier.h"
|
|
|
|
#include "VSetting.h"
|
|
#include "VrfUtil.h"
|
|
#include "VGlobal.h"
|
|
#include "disk.h"
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[]=__FILE__;
|
|
#define new DEBUG_NEW
|
|
#endif
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// CDriverData Class
|
|
//////////////////////////////////////////////////////////////////////
|
|
CDriverData::CDriverData()
|
|
{
|
|
m_SignedStatus = SignedNotVerifiedYet;
|
|
m_VerifyDriverStatus = VerifyDriverNo;
|
|
}
|
|
|
|
CDriverData::CDriverData( const CDriverData &DriverData )
|
|
{
|
|
m_strName = DriverData.m_strName;
|
|
m_SignedStatus = DriverData.m_SignedStatus;
|
|
m_VerifyDriverStatus= DriverData.m_VerifyDriverStatus;
|
|
}
|
|
|
|
CDriverData::CDriverData( LPCTSTR szDriverName )
|
|
{
|
|
m_SignedStatus = SignedNotVerifiedYet;
|
|
m_VerifyDriverStatus = VerifyDriverNo;
|
|
|
|
m_strName = szDriverName;
|
|
}
|
|
|
|
CDriverData::~CDriverData()
|
|
{
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
BOOL CDriverData::LoadDriverHeaderData()
|
|
{
|
|
//
|
|
// N.B.
|
|
//
|
|
// The imagehlp functions are not multithreading safe
|
|
// (see Whistler bug #88373) so if we want to use them from more than
|
|
// one thread we will have to aquire some critical section before.
|
|
//
|
|
// Currently only one thread is using the imagehlp APIs in this app
|
|
// (CSlowProgressDlg::LoadDriverDataWorkerThread) so we don't need
|
|
// our synchronization.
|
|
//
|
|
|
|
LPTSTR szDriverName;
|
|
LPTSTR szDriversDir;
|
|
PLOADED_IMAGE pLoadedImage;
|
|
BOOL bSuccess;
|
|
BOOL bUnloaded;
|
|
|
|
bSuccess = FALSE;
|
|
|
|
ASSERT( m_strName.GetLength() > 0 );
|
|
|
|
//
|
|
// ImageLoad doesn't know about const pointers so
|
|
// we have to GetBuffer here :-(
|
|
//
|
|
|
|
szDriverName = m_strName.GetBuffer( m_strName.GetLength() + 1 );
|
|
|
|
if( NULL == szDriverName )
|
|
{
|
|
goto Done;
|
|
}
|
|
|
|
szDriversDir = g_strDriversDir.GetBuffer( g_strDriversDir.GetLength() + 1 );
|
|
|
|
if( NULL == szDriversDir )
|
|
{
|
|
m_strName.ReleaseBuffer();
|
|
|
|
goto Done;
|
|
}
|
|
|
|
//
|
|
// Load the image
|
|
//
|
|
|
|
pLoadedImage = VrfImageLoad( szDriverName,
|
|
szDriversDir );
|
|
|
|
if( NULL == pLoadedImage )
|
|
{
|
|
//
|
|
// Could not load the image from %windir%\system32\drivers
|
|
// Try again from the PATH
|
|
//
|
|
|
|
pLoadedImage = VrfImageLoad( szDriverName,
|
|
NULL );
|
|
}
|
|
|
|
//
|
|
// Give our string buffers back to MFC
|
|
//
|
|
|
|
m_strName.ReleaseBuffer();
|
|
g_strDriversDir.ReleaseBuffer();
|
|
|
|
if( NULL == pLoadedImage )
|
|
{
|
|
//
|
|
// We couldn't load this image - bad luck
|
|
//
|
|
|
|
TRACE( _T( "ImageLoad failed for %s, error %u\n" ),
|
|
(LPCTSTR) m_strName,
|
|
GetLastError() );
|
|
|
|
goto Done;
|
|
}
|
|
|
|
//
|
|
// Keep the OS and image version information (4 means NT 4 etc.)
|
|
//
|
|
|
|
m_wMajorOperatingSystemVersion =
|
|
pLoadedImage->FileHeader->OptionalHeader.MajorOperatingSystemVersion;
|
|
|
|
m_wMajorImageVersion =
|
|
pLoadedImage->FileHeader->OptionalHeader.MajorImageVersion;
|
|
|
|
//
|
|
// Check if the current driver is a miniport
|
|
//
|
|
|
|
VrfIsDriverMiniport( pLoadedImage,
|
|
m_strMiniportName );
|
|
|
|
//
|
|
// Clean-up
|
|
//
|
|
|
|
bUnloaded = ImageUnload( pLoadedImage );
|
|
|
|
//
|
|
// If ImageUnload fails we cannot do much about it...
|
|
//
|
|
|
|
ASSERT( bUnloaded );
|
|
|
|
bSuccess = TRUE;
|
|
|
|
Done:
|
|
|
|
return bSuccess;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
BOOL CDriverData::LoadDriverVersionData()
|
|
{
|
|
BOOL bResult;
|
|
PVOID pWholeVerBlock;
|
|
PVOID pTranslationInfoBuffer;
|
|
LPCTSTR szVariableValue;
|
|
LPTSTR szDriverPath;
|
|
DWORD dwWholeBlockSize;
|
|
DWORD dwDummyHandle;
|
|
UINT uInfoLengthInTChars;
|
|
TCHAR szLocale[ 32 ];
|
|
TCHAR szBlockName[ 64 ];
|
|
CString strDriverPath;
|
|
|
|
bResult = FALSE;
|
|
|
|
//
|
|
// Get the size of the file info block
|
|
//
|
|
// GetFileVersionInfoSize doesn't know about
|
|
// const pointers so we need to GetBuffer here :-(
|
|
//
|
|
|
|
strDriverPath = g_strDriversDir + '\\' + m_strName;
|
|
|
|
szDriverPath = strDriverPath.GetBuffer( strDriverPath.GetLength() + 1 );
|
|
|
|
if( NULL == szDriverPath )
|
|
{
|
|
goto InitializeWithDefaults;
|
|
}
|
|
|
|
dwWholeBlockSize = GetFileVersionInfoSize(
|
|
szDriverPath,
|
|
&dwDummyHandle );
|
|
|
|
strDriverPath.ReleaseBuffer();
|
|
|
|
if( dwWholeBlockSize == 0 )
|
|
{
|
|
//
|
|
// Couldn't find the binary in %windir%\system32\drivers
|
|
// Try %windir%\system32 too
|
|
//
|
|
|
|
strDriverPath = g_strSystemDir + '\\' + m_strName;
|
|
|
|
szDriverPath = strDriverPath.GetBuffer( strDriverPath.GetLength() + 1 );
|
|
|
|
if( NULL == szDriverPath )
|
|
{
|
|
goto InitializeWithDefaults;
|
|
}
|
|
|
|
dwWholeBlockSize = GetFileVersionInfoSize(
|
|
szDriverPath,
|
|
&dwDummyHandle );
|
|
|
|
strDriverPath.ReleaseBuffer();
|
|
|
|
if( dwWholeBlockSize == 0 )
|
|
{
|
|
//
|
|
// Couldn't read version information
|
|
//
|
|
|
|
goto InitializeWithDefaults;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Allocate the buffer for the version information
|
|
//
|
|
|
|
pWholeVerBlock = malloc( dwWholeBlockSize );
|
|
|
|
if( pWholeVerBlock == NULL )
|
|
{
|
|
goto InitializeWithDefaults;
|
|
}
|
|
|
|
//
|
|
// Get the version information
|
|
//
|
|
// GetFileVersionInfo doesn't know about
|
|
// const pointers so we need to GetBuffer here :-(
|
|
//
|
|
|
|
szDriverPath = strDriverPath.GetBuffer( strDriverPath.GetLength() + 1 );
|
|
|
|
if( NULL == szDriverPath )
|
|
{
|
|
free( pWholeVerBlock );
|
|
|
|
goto InitializeWithDefaults;
|
|
}
|
|
|
|
bResult = GetFileVersionInfo(
|
|
szDriverPath,
|
|
dwDummyHandle,
|
|
dwWholeBlockSize,
|
|
pWholeVerBlock );
|
|
|
|
strDriverPath.ReleaseBuffer();
|
|
|
|
if( bResult != TRUE )
|
|
{
|
|
free( pWholeVerBlock );
|
|
|
|
goto InitializeWithDefaults;
|
|
}
|
|
|
|
//
|
|
// Get the locale info
|
|
//
|
|
|
|
bResult = VerQueryValue(
|
|
pWholeVerBlock,
|
|
_T( "\\VarFileInfo\\Translation" ),
|
|
&pTranslationInfoBuffer,
|
|
&uInfoLengthInTChars );
|
|
|
|
if( TRUE != bResult || NULL == pTranslationInfoBuffer )
|
|
{
|
|
free( pWholeVerBlock );
|
|
|
|
goto InitializeWithDefaults;
|
|
}
|
|
|
|
//
|
|
// Locale info comes back as two little endian words.
|
|
// Flip 'em, 'cause we need them big endian for our calls.
|
|
//
|
|
|
|
_stprintf(
|
|
szLocale,
|
|
_T( "%02X%02X%02X%02X" ),
|
|
(ULONG) HIBYTE( LOWORD ( * (LPDWORD) pTranslationInfoBuffer) ),
|
|
(ULONG) LOBYTE( LOWORD ( * (LPDWORD) pTranslationInfoBuffer) ),
|
|
(ULONG) HIBYTE( HIWORD ( * (LPDWORD) pTranslationInfoBuffer) ),
|
|
(ULONG) LOBYTE( HIWORD ( * (LPDWORD) pTranslationInfoBuffer) ) );
|
|
|
|
//
|
|
// Get the file version
|
|
//
|
|
|
|
_stprintf(
|
|
szBlockName,
|
|
_T( "\\StringFileInfo\\%s\\FileVersion" ),
|
|
szLocale );
|
|
|
|
bResult = VerQueryValue(
|
|
pWholeVerBlock,
|
|
szBlockName,
|
|
(PVOID*) &szVariableValue,
|
|
&uInfoLengthInTChars );
|
|
|
|
if( TRUE != bResult || 0 == uInfoLengthInTChars )
|
|
{
|
|
//
|
|
// Couldn't find the version
|
|
//
|
|
|
|
VERIFY( m_strFileVersion.LoadString( IDS_UNKNOWN ) );
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Found the version
|
|
//
|
|
|
|
m_strFileVersion = szVariableValue;
|
|
}
|
|
|
|
//
|
|
// Get the company name
|
|
//
|
|
|
|
_stprintf(
|
|
szBlockName,
|
|
_T( "\\StringFileInfo\\%s\\CompanyName" ),
|
|
szLocale );
|
|
|
|
bResult = VerQueryValue(
|
|
pWholeVerBlock,
|
|
szBlockName,
|
|
(PVOID*) &szVariableValue,
|
|
&uInfoLengthInTChars );
|
|
|
|
if( TRUE != bResult || uInfoLengthInTChars == 0 )
|
|
{
|
|
//
|
|
// Coudln't find the company name
|
|
//
|
|
|
|
m_strCompanyName.LoadString( IDS_UNKNOWN );
|
|
}
|
|
else
|
|
{
|
|
m_strCompanyName = szVariableValue;
|
|
}
|
|
|
|
//
|
|
// Get the FileDescription
|
|
//
|
|
|
|
_stprintf(
|
|
szBlockName,
|
|
_T( "\\StringFileInfo\\%s\\FileDescription" ),
|
|
szLocale );
|
|
|
|
bResult = VerQueryValue(
|
|
pWholeVerBlock,
|
|
szBlockName,
|
|
(PVOID*) &szVariableValue,
|
|
&uInfoLengthInTChars );
|
|
|
|
if( TRUE != bResult || uInfoLengthInTChars == 0 )
|
|
{
|
|
//
|
|
// Coudln't find the FileDescription
|
|
//
|
|
|
|
m_strFileDescription.LoadString( IDS_UNKNOWN );
|
|
}
|
|
else
|
|
{
|
|
m_strFileDescription = szVariableValue;
|
|
}
|
|
|
|
//
|
|
// clean-up
|
|
//
|
|
|
|
free( pWholeVerBlock );
|
|
|
|
goto Done;
|
|
|
|
InitializeWithDefaults:
|
|
|
|
m_strCompanyName.LoadString( IDS_UNKNOWN );
|
|
m_strFileVersion.LoadString( IDS_UNKNOWN );
|
|
m_strFileDescription.LoadString( IDS_UNKNOWN );
|
|
|
|
Done:
|
|
//
|
|
// We always return TRUE from this function because
|
|
// the app will work fine without the version info -
|
|
// it's just something that we would like to be able to display
|
|
//
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
BOOL CDriverData::LoadDriverImageData()
|
|
{
|
|
BOOL bResult1;
|
|
BOOL bResult2;
|
|
|
|
bResult1 = LoadDriverHeaderData();
|
|
bResult2 = LoadDriverVersionData();
|
|
|
|
return ( bResult1 && bResult2 );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
void CDriverData::AssertValid() const
|
|
{
|
|
ASSERT( SignedNotVerifiedYet == m_SignedStatus ||
|
|
SignedYes == m_SignedStatus ||
|
|
SignedNo == m_SignedStatus );
|
|
|
|
ASSERT( VerifyDriverNo == m_VerifyDriverStatus ||
|
|
VerifyDriverYes == m_VerifyDriverStatus );
|
|
|
|
CObject::AssertValid();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// CDriverDataArray Class
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
CDriverDataArray::~CDriverDataArray()
|
|
{
|
|
DeleteAll();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
VOID CDriverDataArray::DeleteAll()
|
|
{
|
|
INT_PTR nArraySize;
|
|
CDriverData *pCrtDriverData;
|
|
|
|
nArraySize = GetSize();
|
|
|
|
while( nArraySize > 0 )
|
|
{
|
|
nArraySize -= 1;
|
|
|
|
pCrtDriverData = GetAt( nArraySize );
|
|
|
|
ASSERT_VALID( pCrtDriverData );
|
|
|
|
delete pCrtDriverData;
|
|
}
|
|
|
|
RemoveAll();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
CDriverData *CDriverDataArray::GetAt( INT_PTR nIndex ) const
|
|
{
|
|
return (CDriverData *)CObArray::GetAt( nIndex );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
CDriverDataArray &CDriverDataArray::operator = (const CDriverDataArray &DriversDataArray)
|
|
{
|
|
INT_PTR nNewArraySize;
|
|
INT_PTR nCrtElement;
|
|
CDriverData *pCopiedDriverData;
|
|
CDriverData *pNewDriverData;
|
|
|
|
DeleteAll();
|
|
|
|
nNewArraySize = DriversDataArray.GetSize();
|
|
|
|
for( nCrtElement = 0; nCrtElement < nNewArraySize; nCrtElement += 1 )
|
|
{
|
|
pCopiedDriverData = DriversDataArray.GetAt( nCrtElement );
|
|
ASSERT_VALID( pCopiedDriverData );
|
|
|
|
pNewDriverData = new CDriverData( *pCopiedDriverData );
|
|
|
|
if( NULL != pNewDriverData )
|
|
{
|
|
ASSERT_VALID( pNewDriverData );
|
|
|
|
Add( pNewDriverData );
|
|
}
|
|
else
|
|
{
|
|
VrfErrorResourceFormat( IDS_NOT_ENOUGH_MEMORY );
|
|
goto Done;
|
|
}
|
|
}
|
|
|
|
Done:
|
|
//
|
|
// All done, assert that our data is consistent
|
|
//
|
|
|
|
ASSERT_VALID( this );
|
|
|
|
return *this;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// CDriversSet Class
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Construction/Destruction
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
CDriversSet::CDriversSet()
|
|
{
|
|
m_DriverSetType = DriversSetNotSigned;
|
|
m_bDriverDataInitialized = FALSE;
|
|
m_bUnsignedDriverDataInitialized = FALSE;
|
|
}
|
|
|
|
CDriversSet::~CDriversSet()
|
|
{
|
|
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
BOOL CDriversSet::FindUnsignedDrivers( HANDLE hAbortEvent,
|
|
CVrfProgressCtrl &ProgressCtl)
|
|
{
|
|
INT_PTR nAllDriverNames;
|
|
INT_PTR nCrtDriverName;
|
|
DWORD dwWaitResult;
|
|
BOOL bSigned;
|
|
BOOL bChangedCurrentDirectory;
|
|
CDriverData *pDriverData;
|
|
|
|
ProgressCtl.SetRange32(0, 100);
|
|
ProgressCtl.SetStep( 1 );
|
|
ProgressCtl.SetPos( 0 );
|
|
|
|
bChangedCurrentDirectory = FALSE;
|
|
|
|
if( TRUE != m_bUnsignedDriverDataInitialized )
|
|
{
|
|
ASSERT( TRUE == m_bDriverDataInitialized );
|
|
|
|
//
|
|
// We are going to check all drivers' signature
|
|
// so change directory to %windir%\system32\drivers first
|
|
//
|
|
|
|
bChangedCurrentDirectory = SetCurrentDirectory( g_strDriversDir );
|
|
|
|
if( TRUE != bChangedCurrentDirectory )
|
|
{
|
|
VrfErrorResourceFormat( IDS_CANNOT_SET_CURRENT_DIRECTORY,
|
|
(LPCTSTR) g_strDriversDir );
|
|
}
|
|
|
|
//
|
|
// The unsigned drivers data is not initialized yet.
|
|
// Try to initialize it now.
|
|
//
|
|
|
|
nAllDriverNames = m_aDriverData.GetSize();
|
|
|
|
ProgressCtl.SetRange32(0, nAllDriverNames );
|
|
|
|
for( nCrtDriverName = 0; nCrtDriverName < nAllDriverNames; nCrtDriverName+=1 )
|
|
{
|
|
if( NULL != hAbortEvent )
|
|
{
|
|
//
|
|
// Check if the thread has to die
|
|
//
|
|
|
|
dwWaitResult = WaitForSingleObject( hAbortEvent,
|
|
0 );
|
|
|
|
if( WAIT_OBJECT_0 == dwWaitResult )
|
|
{
|
|
//
|
|
// We have to die...
|
|
//
|
|
|
|
TRACE( _T( "CDriversSet::FindUnsignedDrivers : aborting at driver %d of %d\n" ),
|
|
nCrtDriverName,
|
|
nAllDriverNames );
|
|
|
|
goto Done;
|
|
}
|
|
}
|
|
|
|
pDriverData = m_aDriverData.GetAt( nCrtDriverName );
|
|
|
|
ASSERT_VALID( pDriverData );
|
|
|
|
//
|
|
// If we already checked the signature of this driver before
|
|
// don't spend any more time on it - use the cached data
|
|
//
|
|
|
|
if( CDriverData::SignedNotVerifiedYet == pDriverData->m_SignedStatus )
|
|
{
|
|
bSigned = IsDriverSigned( pDriverData->m_strName );
|
|
|
|
if( TRUE != bSigned )
|
|
{
|
|
//
|
|
// This driver is not signed
|
|
//
|
|
|
|
pDriverData->m_SignedStatus = CDriverData::SignedNo;
|
|
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// This driver is signed
|
|
//
|
|
|
|
pDriverData->m_SignedStatus = CDriverData::SignedYes;
|
|
}
|
|
}
|
|
|
|
ProgressCtl.StepIt();
|
|
}
|
|
|
|
m_bUnsignedDriverDataInitialized = TRUE;
|
|
}
|
|
|
|
Done:
|
|
|
|
if( TRUE == bChangedCurrentDirectory )
|
|
{
|
|
SetCurrentDirectory( g_strInitialCurrentDirectory );
|
|
}
|
|
|
|
return m_bUnsignedDriverDataInitialized;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
BOOL CDriversSet::LoadAllDriversData( HANDLE hAbortEvent,
|
|
CVrfProgressCtrl &ProgressCtl )
|
|
{
|
|
ULONG uBufferSize;
|
|
ULONG uCrtModule;
|
|
PVOID pBuffer;
|
|
INT nCrtModuleNameLength;
|
|
INT nBackSlashIndex;
|
|
INT_PTR nDrvDataIndex;
|
|
NTSTATUS Status;
|
|
LPTSTR szCrtModuleName;
|
|
DWORD dwWaitResult;
|
|
CString strCrModuleName;
|
|
CDriverData *pDriverData;
|
|
PRTL_PROCESS_MODULES Modules;
|
|
|
|
ProgressCtl.SetPos( 0 );
|
|
ProgressCtl.SetRange32( 0, 100 );
|
|
ProgressCtl.SetStep( 1 );
|
|
|
|
m_aDriverData.DeleteAll();
|
|
|
|
if( TRUE != m_bDriverDataInitialized )
|
|
{
|
|
for( uBufferSize = 0x10000; TRUE; uBufferSize += 0x1000)
|
|
{
|
|
//
|
|
// Allocate a new buffer
|
|
//
|
|
|
|
pBuffer = new BYTE[ uBufferSize ];
|
|
|
|
if( NULL == pBuffer )
|
|
{
|
|
goto Done;
|
|
}
|
|
|
|
//
|
|
// Query the kernel
|
|
//
|
|
|
|
Status = NtQuerySystemInformation ( SystemModuleInformation,
|
|
pBuffer,
|
|
uBufferSize,
|
|
NULL);
|
|
|
|
if( ! NT_SUCCESS( Status ) )
|
|
{
|
|
delete [] pBuffer;
|
|
|
|
if (Status == STATUS_INFO_LENGTH_MISMATCH)
|
|
{
|
|
//
|
|
// Try with a bigger buffer
|
|
//
|
|
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Fatal error - we cannot query
|
|
//
|
|
|
|
VrfErrorResourceFormat( IDS_CANT_GET_ACTIVE_DRVLIST,
|
|
Status );
|
|
|
|
goto Done;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Got all the information we needed
|
|
//
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
Modules = (PRTL_PROCESS_MODULES)pBuffer;
|
|
|
|
ProgressCtl.SetRange32(0, Modules->NumberOfModules );
|
|
|
|
for( uCrtModule = 0; uCrtModule < Modules->NumberOfModules; uCrtModule += 1 )
|
|
{
|
|
//
|
|
// Check if the user wants to abort this long file processing...
|
|
//
|
|
|
|
if( NULL != hAbortEvent )
|
|
{
|
|
//
|
|
// Check if the thread has to die
|
|
//
|
|
|
|
dwWaitResult = WaitForSingleObject( hAbortEvent,
|
|
0 );
|
|
|
|
if( WAIT_OBJECT_0 == dwWaitResult )
|
|
{
|
|
//
|
|
// We have to die...
|
|
//
|
|
|
|
TRACE( _T( "CDriversSet::LoadAllDriversData : aborting at driver %u of %u\n" ),
|
|
uCrtModule,
|
|
(ULONG) Modules->NumberOfModules );
|
|
|
|
delete [] pBuffer;
|
|
|
|
goto Done;
|
|
}
|
|
}
|
|
|
|
if( Modules->Modules[uCrtModule].ImageBase < g_pHighestUserAddress )
|
|
{
|
|
//
|
|
// This is a user-mode module - we don't care about it
|
|
//
|
|
|
|
ProgressCtl.StepIt();
|
|
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Add this driver to our list
|
|
//
|
|
|
|
nCrtModuleNameLength = strlen( (const char*)&Modules->Modules[uCrtModule].FullPathName[0] );
|
|
|
|
szCrtModuleName = strCrModuleName.GetBuffer( nCrtModuleNameLength + 1 );
|
|
|
|
if( NULL == szCrtModuleName )
|
|
{
|
|
VrfErrorResourceFormat( IDS_NOT_ENOUGH_MEMORY );
|
|
|
|
goto Done;
|
|
}
|
|
|
|
#ifdef UNICODE
|
|
|
|
MultiByteToWideChar( CP_ACP,
|
|
0,
|
|
(const char*)&Modules->Modules[uCrtModule].FullPathName[0],
|
|
-1,
|
|
szCrtModuleName,
|
|
( nCrtModuleNameLength + 1 ) * sizeof( TCHAR ) );
|
|
|
|
#else
|
|
strcpy( szCrtModuleName,
|
|
(const char*)&Modules->Modules[uCrtModule].FullPathName[0] );
|
|
#endif
|
|
|
|
strCrModuleName.ReleaseBuffer();
|
|
|
|
//
|
|
// Keep only the file name, without the path
|
|
//
|
|
// It turns out that NtQuerySystemInformation ( SystemModuleInformation )
|
|
// can return the path in several different formats
|
|
//
|
|
// E.g.
|
|
//
|
|
// \winnt\system32\ntoskrnl.exe
|
|
// acpi.sys
|
|
// \winnt\system32\drivers\battc.sys
|
|
// \systemroot\system32\drivers\videoprt.sys
|
|
//
|
|
|
|
nBackSlashIndex = strCrModuleName.ReverseFind( _T( '\\' ) );
|
|
|
|
if( nBackSlashIndex > 0 )
|
|
{
|
|
strCrModuleName = strCrModuleName.Right( nCrtModuleNameLength - nBackSlashIndex - 1 );
|
|
}
|
|
|
|
//
|
|
// Add a data entry for this driver
|
|
//
|
|
|
|
strCrModuleName.MakeLower();
|
|
|
|
nDrvDataIndex = AddNewDriverData( strCrModuleName );
|
|
|
|
//
|
|
// Deal with the kernel and HAL differently
|
|
//
|
|
|
|
if( ( uCrtModule == 0 || uCrtModule == 1 ) && nDrvDataIndex >= 0)
|
|
{
|
|
pDriverData = m_aDriverData.GetAt( nDrvDataIndex );
|
|
|
|
ASSERT_VALID( pDriverData );
|
|
|
|
if( 0 == uCrtModule )
|
|
{
|
|
//
|
|
// This is the kernel
|
|
//
|
|
|
|
pDriverData->m_strReservedName = _T( "ntoskrnl.exe" );
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// This is the kernel
|
|
//
|
|
|
|
pDriverData->m_strReservedName = _T( "hal.dll" );
|
|
}
|
|
}
|
|
|
|
ProgressCtl.StepIt();
|
|
}
|
|
|
|
delete [] pBuffer;
|
|
|
|
m_bDriverDataInitialized = TRUE;
|
|
}
|
|
|
|
Done:
|
|
|
|
return m_bDriverDataInitialized;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
BOOL CDriversSet::ShouldDriverBeVerified( const CDriverData *pDriverData ) const
|
|
{
|
|
BOOL bResult;
|
|
|
|
bResult = FALSE;
|
|
|
|
switch( m_DriverSetType )
|
|
{
|
|
case DriversSetNotSigned:
|
|
bResult = ( CDriverData::SignedNo == pDriverData->m_SignedStatus );
|
|
break;
|
|
|
|
case DriversSetOldOs:
|
|
bResult = ( 0 != pDriverData->m_wMajorOperatingSystemVersion && 5 > pDriverData->m_wMajorOperatingSystemVersion ) ||
|
|
( 0 != pDriverData->m_wMajorImageVersion && 5 > pDriverData->m_wMajorImageVersion );
|
|
break;
|
|
|
|
case DriversSetAllDrivers:
|
|
bResult = TRUE;
|
|
break;
|
|
|
|
case DriversSetCustom:
|
|
bResult = ( CDriverData::VerifyDriverYes == pDriverData->m_VerifyDriverStatus );
|
|
break;
|
|
|
|
default:
|
|
//
|
|
// Oops, how did we get here?!?
|
|
//
|
|
|
|
ASSERT( FALSE );
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
BOOL CDriversSet::ShouldVerifySomeDrivers( ) const
|
|
{
|
|
INT_PTR nDrivers;
|
|
INT_PTR nCrtDriver;
|
|
CDriverData *pDriverData;
|
|
BOOL bShouldVerifySome;
|
|
|
|
bShouldVerifySome = FALSE;
|
|
|
|
nDrivers = m_aDriverData.GetSize();
|
|
|
|
for( nCrtDriver = 0; nCrtDriver < nDrivers; nCrtDriver += 1 )
|
|
{
|
|
pDriverData = m_aDriverData.GetAt( nCrtDriver );
|
|
|
|
ASSERT_VALID( pDriverData );
|
|
|
|
if( ShouldDriverBeVerified( pDriverData ) )
|
|
{
|
|
bShouldVerifySome = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return bShouldVerifySome;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
BOOL CDriversSet::GetDriversToVerify( CString &strDriversToVerify )
|
|
{
|
|
INT_PTR nDriversNo;
|
|
INT_PTR nCrtDriver;
|
|
CDriverData *pCrtDrvData;
|
|
|
|
if( DriversSetAllDrivers == m_DriverSetType )
|
|
{
|
|
//
|
|
// Verify all drivers
|
|
//
|
|
|
|
strDriversToVerify = _T( '*' );
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Parse all the drivers list and see which ones should be verified
|
|
//
|
|
|
|
strDriversToVerify = _T( "" );
|
|
|
|
nDriversNo = m_aDriverData.GetSize();
|
|
|
|
for( nCrtDriver = 0; nCrtDriver < nDriversNo; nCrtDriver += 1 )
|
|
{
|
|
pCrtDrvData = m_aDriverData.GetAt( nCrtDriver );
|
|
|
|
ASSERT_VALID( pCrtDrvData );
|
|
|
|
if( ShouldDriverBeVerified( pCrtDrvData ) )
|
|
{
|
|
if( pCrtDrvData->m_strReservedName.GetLength() > 0 )
|
|
{
|
|
//
|
|
// Kernel or HAL
|
|
//
|
|
|
|
VrfAddDriverNameNoDuplicates( pCrtDrvData->m_strReservedName,
|
|
strDriversToVerify );
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Regular driver
|
|
//
|
|
|
|
VrfAddDriverNameNoDuplicates( pCrtDrvData->m_strName,
|
|
strDriversToVerify );
|
|
}
|
|
|
|
if( pCrtDrvData->m_strMiniportName.GetLength() > 0 )
|
|
{
|
|
//
|
|
// This is a miniport - auto-enable the corresponding driver
|
|
//
|
|
|
|
TRACE( _T( "Auto-enabling %s\n" ), (LPCTSTR)pCrtDrvData->m_strMiniportName );
|
|
|
|
VrfAddDriverNameNoDuplicates( pCrtDrvData->m_strMiniportName,
|
|
strDriversToVerify );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
INT_PTR CDriversSet::AddNewDriverData( LPCTSTR szDriverName )
|
|
{
|
|
INT_PTR nIndexInArray;
|
|
CDriverData *pNewDriverData;
|
|
BOOL bSuccess;
|
|
|
|
ASSERT( IsDriverNameInList( szDriverName ) == FALSE );
|
|
|
|
nIndexInArray = -1;
|
|
|
|
pNewDriverData = new CDriverData( szDriverName );
|
|
|
|
if( NULL != pNewDriverData )
|
|
{
|
|
pNewDriverData->LoadDriverImageData();
|
|
|
|
TRY
|
|
{
|
|
nIndexInArray = m_aDriverData.Add( pNewDriverData );
|
|
}
|
|
CATCH( CMemoryException, pMemException )
|
|
{
|
|
VrfErrorResourceFormat( IDS_NOT_ENOUGH_MEMORY );
|
|
nIndexInArray = -1;
|
|
|
|
//
|
|
// Clean-up the allocation since we cannot add it to our list
|
|
//
|
|
|
|
delete pNewDriverData;
|
|
}
|
|
END_CATCH
|
|
}
|
|
|
|
return nIndexInArray;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Is this driver name already in our list?
|
|
//
|
|
|
|
BOOL CDriversSet::IsDriverNameInList( LPCTSTR szDriverName )
|
|
{
|
|
INT_PTR nDrivers;
|
|
INT_PTR nCrtDriver;
|
|
CDriverData *pCrtDriverData;
|
|
BOOL bIsInList;
|
|
|
|
bIsInList = FALSE;
|
|
|
|
nDrivers = m_aDriverData.GetSize();
|
|
|
|
for( nCrtDriver = 0; nCrtDriver < nDrivers; nCrtDriver += 1 )
|
|
{
|
|
pCrtDriverData = m_aDriverData.GetAt( nCrtDriver );
|
|
|
|
ASSERT_VALID( pCrtDriverData );
|
|
|
|
if( pCrtDriverData->m_strName.CompareNoCase( szDriverName ) == 0 )
|
|
{
|
|
bIsInList = TRUE;
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
return bIsInList;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Operators
|
|
//
|
|
|
|
CDriversSet & CDriversSet::operator = (const CDriversSet &DriversSet)
|
|
{
|
|
m_DriverSetType = DriversSet.m_DriverSetType;
|
|
m_aDriverData = DriversSet.m_aDriverData;
|
|
m_bDriverDataInitialized = DriversSet.m_bDriverDataInitialized;
|
|
m_bUnsignedDriverDataInitialized = DriversSet.m_bUnsignedDriverDataInitialized;
|
|
|
|
::CopyStringArray(
|
|
DriversSet.m_astrNotInstalledDriversToVerify,
|
|
m_astrNotInstalledDriversToVerify );
|
|
|
|
//
|
|
// All done - assert that our data is consistent
|
|
//
|
|
|
|
ASSERT_VALID( this );
|
|
|
|
return *this;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Overrides
|
|
//
|
|
|
|
void CDriversSet::AssertValid() const
|
|
{
|
|
ASSERT( DriversSetCustom == m_DriverSetType ||
|
|
DriversSetOldOs == m_DriverSetType ||
|
|
DriversSetNotSigned == m_DriverSetType ||
|
|
DriversSetAllDrivers== m_DriverSetType );
|
|
|
|
ASSERT( TRUE == m_bDriverDataInitialized ||
|
|
FALSE == m_bDriverDataInitialized );
|
|
|
|
ASSERT( TRUE == m_bUnsignedDriverDataInitialized ||
|
|
FALSE == m_bUnsignedDriverDataInitialized );
|
|
|
|
m_aDriverData.AssertValid();
|
|
m_astrNotInstalledDriversToVerify.AssertValid();
|
|
|
|
CObject::AssertValid();
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////
|
|
// CSettingsBits Class
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Construction/Destruction
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
CSettingsBits::CSettingsBits()
|
|
{
|
|
m_SettingsType = SettingsTypeTypical;
|
|
}
|
|
|
|
CSettingsBits::~CSettingsBits()
|
|
{
|
|
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Operators
|
|
//
|
|
|
|
CSettingsBits & CSettingsBits::operator = (const CSettingsBits &SettingsBits)
|
|
{
|
|
m_SettingsType = SettingsBits.m_SettingsType;
|
|
|
|
m_bSpecialPoolEnabled = SettingsBits.m_bSpecialPoolEnabled;
|
|
m_bForceIrqlEnabled = SettingsBits.m_bForceIrqlEnabled;
|
|
m_bLowResEnabled = SettingsBits.m_bLowResEnabled;
|
|
m_bPoolTrackingEnabled = SettingsBits.m_bPoolTrackingEnabled;
|
|
m_bIoEnabled = SettingsBits.m_bIoEnabled;
|
|
m_bDeadlockDetectEnabled= SettingsBits.m_bDeadlockDetectEnabled;
|
|
m_bDMAVerifEnabled = SettingsBits.m_bDMAVerifEnabled;
|
|
m_bEnhIoEnabled = SettingsBits.m_bEnhIoEnabled;
|
|
|
|
//
|
|
// All done, assert that our data is consistent
|
|
//
|
|
|
|
ASSERT_VALID( this );
|
|
|
|
return *this;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Overrides
|
|
//
|
|
|
|
void CSettingsBits::AssertValid() const
|
|
{
|
|
CObject::AssertValid();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
VOID CSettingsBits::SetTypicalOnly()
|
|
{
|
|
m_SettingsType = SettingsTypeTypical;
|
|
|
|
m_bSpecialPoolEnabled = TRUE;
|
|
m_bForceIrqlEnabled = TRUE;
|
|
m_bPoolTrackingEnabled = TRUE;
|
|
m_bIoEnabled = TRUE;
|
|
m_bDeadlockDetectEnabled= TRUE;
|
|
m_bDMAVerifEnabled = TRUE;
|
|
|
|
//
|
|
// Low resource simulation
|
|
//
|
|
|
|
m_bLowResEnabled = FALSE;
|
|
|
|
//
|
|
// Extreme or spurious tests
|
|
//
|
|
|
|
m_bEnhIoEnabled = FALSE;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
VOID CSettingsBits::EnableTypicalTests( BOOL bEnable )
|
|
{
|
|
ASSERT( SettingsTypeTypical == m_SettingsType ||
|
|
SettingsTypeCustom == m_SettingsType );
|
|
|
|
m_bSpecialPoolEnabled = ( FALSE != bEnable );
|
|
m_bForceIrqlEnabled = ( FALSE != bEnable );
|
|
m_bPoolTrackingEnabled = ( FALSE != bEnable );
|
|
m_bIoEnabled = ( FALSE != bEnable );
|
|
m_bDeadlockDetectEnabled= ( FALSE != bEnable );
|
|
m_bDMAVerifEnabled = ( FALSE != bEnable );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
VOID CSettingsBits::EnableExcessiveTests( BOOL bEnable )
|
|
{
|
|
m_bEnhIoEnabled = ( FALSE != bEnable );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
VOID CSettingsBits::EnableLowResTests( BOOL bEnable )
|
|
{
|
|
m_bLowResEnabled = ( FALSE != bEnable );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
BOOL CSettingsBits::GetVerifierFlags( DWORD &dwVerifyFlags )
|
|
{
|
|
dwVerifyFlags = 0;
|
|
|
|
if( FALSE != m_bSpecialPoolEnabled )
|
|
{
|
|
dwVerifyFlags |= DRIVER_VERIFIER_SPECIAL_POOLING;
|
|
}
|
|
|
|
if( FALSE != m_bForceIrqlEnabled )
|
|
{
|
|
dwVerifyFlags |= DRIVER_VERIFIER_FORCE_IRQL_CHECKING;
|
|
}
|
|
|
|
if( FALSE != m_bLowResEnabled )
|
|
{
|
|
dwVerifyFlags |= DRIVER_VERIFIER_INJECT_ALLOCATION_FAILURES;
|
|
}
|
|
|
|
if( FALSE != m_bPoolTrackingEnabled )
|
|
{
|
|
dwVerifyFlags |= DRIVER_VERIFIER_TRACK_POOL_ALLOCATIONS;
|
|
}
|
|
|
|
if( FALSE != m_bIoEnabled )
|
|
{
|
|
dwVerifyFlags |= DRIVER_VERIFIER_IO_CHECKING;
|
|
}
|
|
|
|
if( FALSE != m_bDeadlockDetectEnabled )
|
|
{
|
|
dwVerifyFlags |= DRIVER_VERIFIER_DEADLOCK_DETECTION;
|
|
}
|
|
|
|
if( FALSE != m_bDMAVerifEnabled )
|
|
{
|
|
dwVerifyFlags |= DRIVER_VERIFIER_DMA_VERIFIER;
|
|
}
|
|
|
|
if( FALSE != m_bEnhIoEnabled )
|
|
{
|
|
dwVerifyFlags |= DRIVER_VERIFIER_ENHANCED_IO_CHECKING;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////
|
|
// CVerifierSettings Class
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Construction/Destruction
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
CVerifierSettings::CVerifierSettings()
|
|
{
|
|
}
|
|
|
|
CVerifierSettings::~CVerifierSettings()
|
|
{
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
CVerifierSettings &CVerifierSettings::operator = (const CVerifierSettings &VerifSettings)
|
|
{
|
|
m_SettingsBits = VerifSettings.m_SettingsBits;
|
|
m_DriversSet = VerifSettings.m_DriversSet;
|
|
m_aDiskData = VerifSettings.m_aDiskData;
|
|
|
|
//
|
|
// All done - assert that our data is consistent
|
|
//
|
|
|
|
ASSERT_VALID( this );
|
|
|
|
return *this;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
BOOL CVerifierSettings::SaveToRegistry()
|
|
{
|
|
DWORD dwVerifyFlags;
|
|
DWORD dwPrevFlags;
|
|
BOOL bSuccess;
|
|
CString strDriversToVerify;
|
|
CString strPrevVerifiedDrivers;
|
|
CString strDisksToVerify;
|
|
|
|
dwVerifyFlags = 0;
|
|
|
|
//
|
|
// Get the list of drivers to verify
|
|
//
|
|
|
|
bSuccess = m_DriversSet.GetDriversToVerify( strDriversToVerify ) &&
|
|
m_SettingsBits.GetVerifierFlags( dwVerifyFlags );
|
|
|
|
if( FALSE != bSuccess )
|
|
{
|
|
//
|
|
// Have something to write to the registry
|
|
//
|
|
|
|
//
|
|
// Try to get the old settings
|
|
//
|
|
|
|
dwPrevFlags = 0;
|
|
|
|
VrfReadVerifierSettings( strPrevVerifiedDrivers,
|
|
dwPrevFlags );
|
|
|
|
if( strDriversToVerify.CompareNoCase( strPrevVerifiedDrivers ) != 0 ||
|
|
dwVerifyFlags != dwPrevFlags )
|
|
{
|
|
bSuccess = VrfWriteVerifierSettings( TRUE,
|
|
strDriversToVerify,
|
|
TRUE,
|
|
dwVerifyFlags );
|
|
|
|
}
|
|
}
|
|
|
|
if( FALSE != bSuccess )
|
|
{
|
|
bSuccess = m_aDiskData.SaveNewSettings();
|
|
}
|
|
|
|
if( FALSE != bSuccess )
|
|
{
|
|
if( FALSE == g_bSettingsSaved )
|
|
{
|
|
VrfMesssageFromResource( IDS_NO_SETTINGS_WERE_CHANGED );
|
|
}
|
|
else
|
|
{
|
|
VrfMesssageFromResource( IDS_REBOOT );
|
|
}
|
|
}
|
|
|
|
return bSuccess;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Overrides
|
|
//
|
|
|
|
void CVerifierSettings::AssertValid() const
|
|
{
|
|
m_SettingsBits.AssertValid();
|
|
m_DriversSet.AssertValid();
|
|
m_aDiskData.AssertValid();
|
|
|
|
|
|
CObject::AssertValid();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Runtime data - queried from the kernel
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// class CRuntimeDriverData
|
|
//
|
|
|
|
CRuntimeDriverData::CRuntimeDriverData()
|
|
{
|
|
Loads = 0;
|
|
Unloads = 0;
|
|
|
|
CurrentPagedPoolAllocations = 0;
|
|
CurrentNonPagedPoolAllocations = 0;
|
|
PeakPagedPoolAllocations = 0;
|
|
PeakNonPagedPoolAllocations = 0;
|
|
|
|
PagedPoolUsageInBytes = 0;
|
|
NonPagedPoolUsageInBytes = 0;
|
|
PeakPagedPoolUsageInBytes = 0;
|
|
PeakNonPagedPoolUsageInBytes = 0;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// class CRuntimeDriverDataArray
|
|
//
|
|
|
|
CRuntimeDriverDataArray::~CRuntimeDriverDataArray()
|
|
{
|
|
DeleteAll();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
CRuntimeDriverData *CRuntimeDriverDataArray::GetAt( INT_PTR nIndex )
|
|
{
|
|
CRuntimeDriverData *pRetVal = (CRuntimeDriverData *)CObArray::GetAt( nIndex );
|
|
|
|
ASSERT_VALID( pRetVal );
|
|
|
|
return pRetVal;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
VOID CRuntimeDriverDataArray::DeleteAll()
|
|
{
|
|
INT_PTR nArraySize;
|
|
CRuntimeDriverData *pCrtDriverData;
|
|
|
|
nArraySize = GetSize();
|
|
|
|
while( nArraySize > 0 )
|
|
{
|
|
nArraySize -= 1;
|
|
|
|
pCrtDriverData = GetAt( nArraySize );
|
|
|
|
ASSERT_VALID( pCrtDriverData );
|
|
|
|
delete pCrtDriverData;
|
|
}
|
|
|
|
RemoveAll();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// class CRuntimeVerifierData
|
|
//
|
|
|
|
CRuntimeVerifierData::CRuntimeVerifierData()
|
|
{
|
|
FillWithDefaults();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
VOID CRuntimeVerifierData::FillWithDefaults()
|
|
{
|
|
m_bSpecialPool = FALSE;
|
|
m_bPoolTracking = FALSE;
|
|
m_bForceIrql = FALSE;
|
|
m_bIo = FALSE;
|
|
m_bEnhIo = FALSE;
|
|
m_bDeadlockDetect = FALSE;
|
|
m_bDMAVerif = FALSE;
|
|
m_bLowRes = FALSE;
|
|
|
|
RaiseIrqls = 0;
|
|
AcquireSpinLocks = 0;
|
|
SynchronizeExecutions = 0;
|
|
AllocationsAttempted = 0;
|
|
|
|
AllocationsSucceeded = 0;
|
|
AllocationsSucceededSpecialPool = 0;
|
|
AllocationsWithNoTag;
|
|
|
|
Trims = 0;
|
|
AllocationsFailed = 0;
|
|
AllocationsFailedDeliberately = 0;
|
|
|
|
UnTrackedPool = 0;
|
|
|
|
Level = 0;
|
|
|
|
m_RuntimeDriverDataArray.DeleteAll();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
BOOL CRuntimeVerifierData::IsDriverVerified( LPCTSTR szDriveName )
|
|
{
|
|
CRuntimeDriverData *pCrtDriverData;
|
|
INT_PTR nDrivers;
|
|
BOOL bFound;
|
|
|
|
bFound = FALSE;
|
|
|
|
nDrivers = m_RuntimeDriverDataArray.GetSize();
|
|
|
|
while( nDrivers > 0 )
|
|
{
|
|
nDrivers -= 1;
|
|
|
|
pCrtDriverData = m_RuntimeDriverDataArray.GetAt( nDrivers );
|
|
|
|
ASSERT_VALID( pCrtDriverData );
|
|
|
|
if( 0 == pCrtDriverData->m_strName.CompareNoCase( szDriveName ) )
|
|
{
|
|
bFound = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return bFound;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// CDiskData Class
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
CDiskData::CDiskData( LPCTSTR szVerifierEnabled,
|
|
LPCTSTR szDiskDevicesForDisplay,
|
|
LPCTSTR szDiskDevicesPDOName )
|
|
{
|
|
m_bVerifierEnabled = ( 0 != _ttoi( szVerifierEnabled ) );
|
|
|
|
m_strDiskDevicesForDisplay = szDiskDevicesForDisplay;
|
|
m_strDiskDevicesPDOName = szDiskDevicesPDOName;
|
|
}
|
|
|
|
CDiskData::CDiskData( const CDiskData &DiskData )
|
|
{
|
|
m_bVerifierEnabled = DiskData.m_bVerifierEnabled;
|
|
m_strDiskDevicesForDisplay = DiskData.m_strDiskDevicesForDisplay;
|
|
m_strDiskDevicesPDOName = DiskData.m_strDiskDevicesPDOName;
|
|
}
|
|
|
|
|
|
CDiskData::~CDiskData()
|
|
{
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
void CDiskData::AssertValid() const
|
|
{
|
|
ASSERT( m_bVerifierEnabled == FALSE || m_bVerifierEnabled == TRUE );
|
|
ASSERT( m_strDiskDevicesForDisplay.GetLength() > 0 );
|
|
ASSERT( m_strDiskDevicesPDOName.GetLength() > 0 );
|
|
|
|
CObject::AssertValid();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// CDiskDataArray Class
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
CDiskDataArray::CDiskDataArray()
|
|
{
|
|
}
|
|
|
|
CDiskDataArray::~CDiskDataArray()
|
|
{
|
|
DeleteAll();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
VOID CDiskDataArray::DeleteAll()
|
|
{
|
|
INT_PTR nArraySize;
|
|
CDiskData *pCrtDiskData;
|
|
|
|
nArraySize = GetSize();
|
|
|
|
while( nArraySize > 0 )
|
|
{
|
|
nArraySize -= 1;
|
|
|
|
pCrtDiskData = GetAt( nArraySize );
|
|
|
|
ASSERT_VALID( pCrtDiskData );
|
|
|
|
delete pCrtDiskData;
|
|
}
|
|
|
|
RemoveAll();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
CDiskData *CDiskDataArray::GetAt( INT_PTR nIndex ) const
|
|
{
|
|
return (CDiskData *)CObArray::GetAt( nIndex );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
CDiskDataArray &CDiskDataArray::operator = (const CDiskDataArray &DiskDataArray)
|
|
{
|
|
INT_PTR nNewArraySize;
|
|
INT_PTR nCrtElement;
|
|
CDiskData *pCopiedDiskData;
|
|
CDiskData *pNewDiskData;
|
|
|
|
DeleteAll();
|
|
|
|
nNewArraySize = DiskDataArray.GetSize();
|
|
|
|
for( nCrtElement = 0; nCrtElement < nNewArraySize; nCrtElement += 1 )
|
|
{
|
|
pCopiedDiskData = DiskDataArray.GetAt( nCrtElement );
|
|
ASSERT_VALID( pCopiedDiskData );
|
|
|
|
pNewDiskData = new CDiskData( *pCopiedDiskData );
|
|
|
|
if( NULL != pNewDiskData )
|
|
{
|
|
ASSERT_VALID( pNewDiskData );
|
|
|
|
Add( pNewDiskData );
|
|
}
|
|
else
|
|
{
|
|
VrfErrorResourceFormat( IDS_NOT_ENOUGH_MEMORY );
|
|
goto Done;
|
|
}
|
|
}
|
|
|
|
Done:
|
|
//
|
|
// All done, assert that our data is consistent
|
|
//
|
|
|
|
ASSERT_VALID( this );
|
|
|
|
return *this;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
BOOL CDiskDataArray::InitializeDiskList()
|
|
{
|
|
BOOLEAN bSuccess;
|
|
INT nCrtLength;
|
|
CDiskData *pNewDiskData;
|
|
LPTSTR DiskDevicesForDisplay = NULL;
|
|
LPTSTR DiskDevicesPDOName = NULL;
|
|
LPTSTR VerifierEnabled = NULL;
|
|
LPTSTR DiskDevicesForDisplayCrt;
|
|
LPTSTR DiskDevicesPDONameCrt;
|
|
LPTSTR VerifierEnabledCrt;
|
|
|
|
DeleteAll();
|
|
|
|
bSuccess = DiskEnumerate( g_szFilter,
|
|
&DiskDevicesForDisplay,
|
|
&DiskDevicesPDOName,
|
|
&VerifierEnabled );
|
|
|
|
if( FALSE != bSuccess )
|
|
{
|
|
|
|
DiskDevicesForDisplayCrt = DiskDevicesForDisplay;
|
|
DiskDevicesPDONameCrt = DiskDevicesPDOName;
|
|
VerifierEnabledCrt = VerifierEnabled;
|
|
|
|
do
|
|
{
|
|
pNewDiskData = new CDiskData( VerifierEnabledCrt,
|
|
DiskDevicesForDisplayCrt,
|
|
DiskDevicesPDONameCrt );
|
|
|
|
if( NULL == pNewDiskData )
|
|
{
|
|
bSuccess = FALSE;
|
|
break;
|
|
}
|
|
|
|
ASSERT_VALID( pNewDiskData );
|
|
|
|
nCrtLength = pNewDiskData->m_strDiskDevicesForDisplay.GetLength();
|
|
if( nCrtLength == 0 )
|
|
{
|
|
delete pNewDiskData;
|
|
break;
|
|
}
|
|
DiskDevicesForDisplayCrt += (nCrtLength + 1);
|
|
|
|
nCrtLength = pNewDiskData->m_strDiskDevicesPDOName.GetLength();
|
|
if( nCrtLength == 0 )
|
|
{
|
|
delete pNewDiskData;
|
|
break;
|
|
}
|
|
DiskDevicesPDONameCrt += (nCrtLength + 1);
|
|
|
|
VerifierEnabledCrt += ( _tcslen( VerifierEnabledCrt ) + 1 );
|
|
|
|
Add( pNewDiskData );
|
|
}
|
|
while( TRUE );
|
|
|
|
FreeDiskMultiSz( DiskDevicesForDisplay );
|
|
FreeDiskMultiSz( DiskDevicesPDOName );
|
|
FreeDiskMultiSz( VerifierEnabled );
|
|
}
|
|
|
|
return (FALSE != bSuccess);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
BOOL CDiskDataArray::VerifyAnyDisk()
|
|
{
|
|
INT_PTR nArraySize;
|
|
CDiskData *pDiskData;
|
|
|
|
nArraySize = GetSize();
|
|
|
|
while( nArraySize > 0 )
|
|
{
|
|
nArraySize -= 1;
|
|
|
|
pDiskData = GetAt( nArraySize );
|
|
ASSERT_VALID( pDiskData );
|
|
|
|
if( FALSE != pDiskData->m_bVerifierEnabled )
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
BOOL CDiskDataArray::SaveNewSettings()
|
|
{
|
|
BOOL bSuccess;
|
|
INT_PTR nArraySize;
|
|
CDiskData *pNewDiskData;
|
|
CDiskData *pOldDiskData;
|
|
LPTSTR szDiskDevicesPDOName;
|
|
|
|
bSuccess = TRUE;
|
|
|
|
nArraySize = GetSize();
|
|
|
|
while( nArraySize > 0 )
|
|
{
|
|
nArraySize -= 1;
|
|
|
|
pNewDiskData = GetAt( nArraySize );
|
|
ASSERT_VALID( pNewDiskData );
|
|
|
|
pOldDiskData = g_OldDiskData.GetAt( nArraySize );
|
|
ASSERT_VALID( pOldDiskData );
|
|
|
|
if( pNewDiskData->m_bVerifierEnabled != pOldDiskData->m_bVerifierEnabled )
|
|
{
|
|
szDiskDevicesPDOName = pNewDiskData->m_strDiskDevicesPDOName.GetBuffer(
|
|
pNewDiskData->m_strDiskDevicesPDOName.GetLength() + 1 );
|
|
|
|
if( NULL == szDiskDevicesPDOName )
|
|
{
|
|
bSuccess = FALSE;
|
|
break;
|
|
}
|
|
|
|
if( FALSE != pNewDiskData->m_bVerifierEnabled )
|
|
{
|
|
//
|
|
// Verifier will be enabled for this disk.
|
|
//
|
|
|
|
bSuccess = ( AddFilter( g_szFilter,
|
|
szDiskDevicesPDOName) != FALSE);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Verifier will be disabled for this disk.
|
|
//
|
|
|
|
bSuccess = ( DelFilter( g_szFilter,
|
|
szDiskDevicesPDOName ) != FALSE);
|
|
}
|
|
|
|
pNewDiskData->m_strDiskDevicesPDOName.ReleaseBuffer();
|
|
|
|
if( FALSE == bSuccess )
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
g_bSettingsSaved = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
return bSuccess;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
VOID CDiskDataArray::SetVerifyAllDisks( BOOL bEnabled )
|
|
{
|
|
INT_PTR nArraySize;
|
|
CDiskData *pDiskData;
|
|
|
|
nArraySize = GetSize();
|
|
|
|
while( nArraySize > 0 )
|
|
{
|
|
nArraySize -= 1;
|
|
|
|
pDiskData = GetAt( nArraySize );
|
|
ASSERT_VALID( pDiskData );
|
|
|
|
pDiskData->m_bVerifierEnabled = bEnabled;
|
|
}
|
|
}
|