2007年5月3日星期四

看过《windows internals》前两章 作了个小程序

/*===================================================================
* Filename CheckKernel.c
*
* Author: kcrazy
* Email: thekcrazy@gmail.com
*
* Description: 检查Windows所使用的内核及HAL的原始版本
*
* Date: 2007-4-27 Original from kcrazy
*
* Version: 1.0
==================================================================*/

#include
#include
#include

#pragma comment (lib, "Version.lib")

DWORD IsPAE( VOID );

BOOL GetFileInfo( LPWSTR lpFileName, LPWSTR Info, LPWSTR Buf, UINT Len );

int main( int argc,char *argv[] )
{
DWORD pae;
WCHAR StrBuffer[255] = {0};

/* 判断是否启用PAE */
pae = IsPAE();

/* 获取执行体和内核的原始文件 */
if (pae == 0)
{
GetFileInfo( L"ntoskrnl.exe", L"\\OriginalFilename", StrBuffer, sizeof(WCHAR) * 255 );
}
else if (pae == 1)
{
GetFileInfo( L"ntkrnlpa.exe", L"\\OriginalFilename", StrBuffer, sizeof(WCHAR) * 255 );
}
else
{
printf( "UnKnow Error!\n" );

return 0;
}

printf( "Original Kernel File:\t%S\t", StrBuffer );

if (wcscmp( StrBuffer, L"ntoskrnl.exe" ) == 0)
{
printf( " - 单CPU的原始执行体和内核\n" );
}
else if (wcscmp( StrBuffer, L"ntkrnlpa.exe" ) == 0)
{
printf( " - 单CPU支持PAE的原始执行体和内核\n" );
}
else if (wcscmp( StrBuffer, L"ntkrnlmp.exe" ) == 0)
{
printf( " - 多CPU的原始执行体和内核\n" );
}
else if (wcscmp( StrBuffer, L"ntkrpamp.exe" ) == 0)
{
printf( " - 多CPU支持PAE的原始执行体和内核\n" );
}

/* 获取内核版本信息 */
GetFileInfo( L"ntkrnlpa.exe", L"\\ProductVersion", StrBuffer, sizeof(WCHAR) * 255 );

printf( "Kernel Version:\t\t%S\n", StrBuffer );

/* 获取HAL原始文件 */
GetFileInfo( L"hal.dll", L"\\OriginalFilename", StrBuffer, sizeof(WCHAR) * 255 );

printf( "Original HAL File:\t%S\t", StrBuffer );

if (wcscmp( StrBuffer, L"hal.dll" ) == 0)
{
printf( " - 标准PC\n" );
}
else if (wcscmp( StrBuffer, L"halacpi.dll" ) == 0)
{
printf( " - 高级配置和电源接口(ACPI) PC\n" );
}
else if (wcscmp( StrBuffer, L"halapic.dll" ) == 0)
{
printf( " - 高级可编程中断控制器(APIC) PC\n" );
}
else if (wcscmp( StrBuffer, L"halaacpi.dll" ) == 0)
{
printf( " - APIC ACPI PC\n" );
}
else if (wcscmp( StrBuffer, L"halmps.dll" ) == 0)
{
printf( " - 多处理器PC\n" );
}
else if (wcscmp( StrBuffer, L"halmacpi.dll" ) == 0)
{
printf( " - 多处理器ACPI PC\n" );
}
else if (wcscmp( StrBuffer, L"halborg.dll" ) == 0)
{
printf( " - Silicon图形工作站\n" );
}
else if (wcscmp( StrBuffer, L"halsp.dll" ) == 0)
{
printf( " - Compaq SystemPro\n" );
}

system( "PAUSE" );

return 0;
}

DWORD IsPAE( VOID )
{
HKEY hKey;
LONG ret;
DWORD Value;
DWORD cbValue;

ret = RegOpenKeyW(
HKEY_LOCAL_MACHINE,
L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management",
&hKey );
if (ret != ERROR_SUCCESS)
{
return -1;
}

cbValue = sizeof(DWORD);

ret = RegQueryValueExW( hKey, L"PhysicalAddressExtension", NULL, NULL, (LPBYTE)&Value, &cbValue );
if (ret != ERROR_SUCCESS)
{
RegCloseKey( hKey );
return -1;
}

RegCloseKey( hKey );

return Value;
}


BOOL GetFileInfo( LPWSTR lpFileName, LPWSTR Info, LPWSTR Buf, UINT Len )
{
DWORD dwHandle;
DWORD dwSize;
PVOID Buffer;
PVOID lpData;
UINT cbTranslate;
UINT index;
WCHAR SubBlock[255];

struct LANGANDCODEPAGE
{
WORD wLanguage;
WORD wCodePage;
} *lpTranslate;


dwSize = GetFileVersionInfoSizeW( lpFileName, &dwHandle );
if (dwSize == 0)
{
dwSize = GetLastError();
return FALSE;
}

Buffer = malloc( dwSize );
if (Buffer == NULL)
{
return FALSE;
}
memset( Buffer, 0, dwSize );

if (!GetFileVersionInfoW( lpFileName, 0, dwSize, Buffer ))
{
free( Buffer );
return FALSE;
}

if (!VerQueryValueW( Buffer, L"\\VarFileInfo\\Translation", &lpTranslate, &cbTranslate ))
{
free( Buffer );
return FALSE;
}

for (index = 0; index < (cbTranslate / sizeof(struct LANGANDCODEPAGE)); index++)
{
memset( SubBlock, 0, sizeof(WCHAR) * 255 );
swprintf(
SubBlock,
L"\\StringFileInfo\\%04x%04x%s",
lpTranslate[index].wLanguage,
lpTranslate[index].wCodePage,
Info );
}

VerQueryValueW( Buffer, SubBlock, &lpData, &Len );

memset( Buf, 0, Len );
wcscpy( Buf, lpData );

free( Buffer );

return TRUE;
}