Leaked source code of windows server 2003
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.
 
 
 
 
 
 

993 lines
22 KiB

#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <winioctl.h>
#include <stdio.h>
#include <stdlib.h>
#include "saio.h"
#include "..\driver\ioctl.h"
void
PrintACPITable(
PVOID AcpiTable
);
PWSTR SaDeviceName[] =
{
{ NULL }, // SA_DEVICE_UNKNOWN
{ L"\\\\?\\GLOBALROOT\\Device\\ServerApplianceLocalDisplay" }, // SA_DEVICE_DISPLAY
{ L"\\\\?\\GLOBALROOT\\Device\\ServerApplianceKeypad" }, // SA_DEVICE_KEYPAD
{ L"\\\\?\\GLOBALROOT\\Device\\ServerApplianceNvram" }, // SA_DEVICE_NVRAM
{ L"\\\\?\\GLOBALROOT\\Device\\ServerApplianceWatchdog" } // SA_DEVICE_WATCHDOG
};
ULONG NvramData[32];
UCHAR KeyBuffer[32];
PVOID WdTable;
HANDLE
OpenSaDevice(
ULONG DeviceType
)
{
HANDLE hDevice;
WCHAR buf[128];
wcscpy( buf, L"\\\\?\\GLOBALROOT" );
switch (DeviceType) {
case SA_DEVICE_DISPLAY:
wcscat( buf, SA_DEVICE_DISPLAY_NAME_STRING );
break;
case SA_DEVICE_KEYPAD:
wcscat( buf, SA_DEVICE_KEYPAD_NAME_STRING );
break;
case SA_DEVICE_NVRAM:
wcscat( buf, SA_DEVICE_NVRAM_NAME_STRING );
break;
case SA_DEVICE_WATCHDOG:
wcscat( buf, SA_DEVICE_WATCHDOG_NAME_STRING );
break;
}
hDevice = CreateFile(
buf,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL
);
return hDevice;
}
HANDLE
OpenSaTestDriver(
void
)
{
HANDLE hDevice;
hDevice = CreateFile(
L"\\\\.\\SaTest",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL
);
return hDevice;
}
int
WriteBitmap(
PUCHAR Bitmap,
ULONG Width,
ULONG Height,
ULONG BitmapSize
)
{
HANDLE hFile;
SA_DISPLAY_SHOW_MESSAGE SaDisplay;
ULONG Count;
hFile = OpenSaDevice( SA_DEVICE_DISPLAY );
if (hFile == INVALID_HANDLE_VALUE) {
return -1;
}
SaDisplay.SizeOfStruct = sizeof(SA_DISPLAY_SHOW_MESSAGE);
SaDisplay.MsgCode = SA_DISPLAY_READY;
SaDisplay.Width = (USHORT)Width;
SaDisplay.Height = (USHORT)Height;
memcpy( SaDisplay.Bits, Bitmap, BitmapSize );
WriteFile( hFile, &SaDisplay, sizeof(SA_DISPLAY_SHOW_MESSAGE), &Count, NULL );
CloseHandle( hFile );
return 0;
}
void
ConvertBottomLeft2TopLeft(
PUCHAR Bits,
ULONG Width,
ULONG Height
)
{
ULONG Row;
ULONG Col;
UCHAR Temp;
Width = Width >> 3;
for (Row = 0; Row < (Height / 2); Row++) {
for (Col = 0; Col < Width; Col++) {
Temp = Bits[Row * Width + Col];
Bits[Row * Width + Col] = Bits[(Height - Row - 1) * Width + Col];
Bits[(Height - Row - 1) * Width + Col] = Temp;
}
}
}
int
DisplayBitmap(
PWSTR BitmapName
)
{
HANDLE hFile;
ULONG FileSize;
PUCHAR BitmapData;
PBITMAPFILEHEADER bmf;
PBITMAPINFOHEADER bmi;
ULONG Bytes;
PUCHAR Bits;
hFile = CreateFile(
BitmapName,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL
);
if (hFile == INVALID_HANDLE_VALUE) {
return -1;
}
FileSize = GetFileSize( hFile, NULL );
BitmapData = (PUCHAR) malloc( FileSize );
if (BitmapData == NULL) {
return -1;
}
memset( BitmapData, 0, FileSize );
if (!ReadFile( hFile, BitmapData, FileSize, &Bytes, NULL )) {
return -1;
}
bmf = (PBITMAPFILEHEADER) BitmapData;
bmi = (PBITMAPINFOHEADER) (BitmapData + sizeof(BITMAPFILEHEADER));
if (bmf->bfType != 0x4d42) {
return -1;
}
if (bmi->biBitCount != 1 && bmi->biCompression != 0) {
return -1;
}
Bits = (PUCHAR) BitmapData + bmf->bfOffBits;
ConvertBottomLeft2TopLeft( Bits, bmi->biWidth, bmi->biHeight );
WriteBitmap(
Bits,
bmi->biWidth,
bmi->biHeight,
(bmi->biWidth >> 3) * bmi->biHeight //NewSize
);
free( BitmapData );
CloseHandle( hFile );
return 0;
}
int
ClearDisplay(
int val
)
{
PUCHAR BitmapData;
ULONG Width = 128;
ULONG Height = 64;
ULONG Size = (Width * Height) / 8;
BitmapData = (PUCHAR) malloc( Size );
if (BitmapData == NULL) {
return -1;
}
memset( BitmapData, val, Size );
return WriteBitmap( BitmapData, Width, Height, Size );
}
int
DoKeypadTest(
void
)
{
HANDLE hFile;
ULONG Count;
UCHAR Keypress;
hFile = OpenSaDevice( SA_DEVICE_KEYPAD );
if (hFile == INVALID_HANDLE_VALUE) {
return -1;
}
while (1) {
wprintf( L">>> " );
if (ReadFile( hFile, KeyBuffer, sizeof(UCHAR), &Count, NULL )) {
Keypress = KeyBuffer[0];
if (Keypress & SA_KEYPAD_UP) {
wprintf( L"Up Arrow\n" );
} else
if (Keypress & SA_KEYPAD_DOWN) {
wprintf( L"Down Arrow\n" );
} else
if (Keypress & SA_KEYPAD_LEFT) {
wprintf( L"Left Arrow\n" );
} else
if (Keypress & SA_KEYPAD_RIGHT) {
wprintf( L"Right Arrow\n" );
} else
if (Keypress & SA_KEYPAD_CANCEL) {
wprintf( L"Escape\n" );
} else
if (Keypress & SA_KEYPAD_SELECT) {
wprintf( L"Enter\n" );
} else {
wprintf( L"**-> Unknown key [%x] <-**\n", Keypress );
}
}
}
CloseHandle( hFile );
return 0;
}
int
NvramWrite(
ULONG Slot,
ULONG Val
)
{
HANDLE hFile;
ULONG Count;
hFile = OpenSaDevice( SA_DEVICE_NVRAM );
if (hFile == INVALID_HANDLE_VALUE) {
return -1;
}
SetFilePointer( hFile, sizeof(ULONG)*Slot, NULL, FILE_BEGIN );
WriteFile( hFile, &Val, sizeof(ULONG), &Count, NULL );
CloseHandle( hFile );
return 0;
}
ULONG
NvramRead(
ULONG Slot
)
{
HANDLE hFile;
ULONG Count;
ULONG Val;
hFile = OpenSaDevice( SA_DEVICE_NVRAM );
if (hFile == INVALID_HANDLE_VALUE) {
return -1;
}
SetFilePointer( hFile, sizeof(ULONG)*Slot, NULL, FILE_BEGIN );
ReadFile( hFile, &Val, sizeof(ULONG), &Count, NULL );
CloseHandle( hFile );
return Val;
}
BOOL
BootCounterRead(
ULONG Slot,
PULONG Val
)
{
HANDLE hFile;
BOOL b;
ULONG Bytes;
SA_NVRAM_BOOT_COUNTER BootCounter;
hFile = OpenSaDevice( SA_DEVICE_NVRAM );
if (hFile == INVALID_HANDLE_VALUE) {
return -1;
}
BootCounter.SizeOfStruct = sizeof(SA_NVRAM_BOOT_COUNTER);
BootCounter.Number = Slot;
BootCounter.Value = 0;
b = DeviceIoControl(
hFile,
IOCTL_NVRAM_READ_BOOT_COUNTER,
NULL,
0,
&BootCounter,
sizeof(SA_NVRAM_BOOT_COUNTER),
&Bytes,
NULL
);
if (!b) {
*Val = 0;
} else {
*Val = BootCounter.Value;
}
CloseHandle( hFile );
return b;
}
BOOL
BootCounterWrite(
ULONG Slot,
ULONG Val
)
{
HANDLE hFile;
BOOL b;
ULONG Bytes;
SA_NVRAM_BOOT_COUNTER BootCounter;
hFile = OpenSaDevice( SA_DEVICE_NVRAM );
if (hFile == INVALID_HANDLE_VALUE) {
return -1;
}
BootCounter.SizeOfStruct = sizeof(SA_NVRAM_BOOT_COUNTER);
BootCounter.Number = Slot;
BootCounter.Value = Val;
b = DeviceIoControl(
hFile,
IOCTL_NVRAM_WRITE_BOOT_COUNTER,
&BootCounter,
sizeof(SA_NVRAM_BOOT_COUNTER),
NULL,
0,
&Bytes,
NULL
);
CloseHandle( hFile );
return b;
}
int
DoWatchdogTest(
void
)
{
HANDLE hFileWd;
HANDLE hFileNvram;
ULONG Count;
ULONG WatchdogState;
ULONG i;
hFileNvram = OpenSaDevice( SA_DEVICE_NVRAM );
if (hFileNvram == INVALID_HANDLE_VALUE) {
return -1;
}
ReadFile( hFileNvram, NvramData, sizeof(NvramData), &Count, NULL );
for (i=0; i<32; i++) {
wprintf( L"[%08x]\n", NvramData[i] );
}
NvramData[28] = 10;
NvramData[29] = 10;
NvramData[30] = 10;
NvramData[31] = 10;
WriteFile( hFileNvram, &NvramData, sizeof(NvramData), &Count, NULL );
CloseHandle( hFileNvram );
hFileWd = OpenSaDevice( SA_DEVICE_WATCHDOG );
if (hFileWd == INVALID_HANDLE_VALUE) {
return -1;
}
WatchdogState = 1;
Count = DeviceIoControl(
hFileWd,
IOCTL_SAWD_DISABLE,
&WatchdogState,
sizeof(ULONG),
&WatchdogState,
sizeof(ULONG),
&Count,
NULL
);
CloseHandle( hFileWd );
return 0;
}
int
DoWatchdogPingLoop(
void
)
{
HANDLE hFile;
ULONG Count;
hFile = OpenSaDevice( SA_DEVICE_WATCHDOG );
if (hFile == INVALID_HANDLE_VALUE) {
return -1;
}
while (1) {
DeviceIoControl(
hFile,
IOCTL_SAWD_PING,
NULL,
0,
NULL,
0,
&Count,
NULL
);
wprintf( L"ping...\n" );
Sleep( 90 * 1000 );
}
CloseHandle( hFile );
return 0;
}
int
InstallTestDriver(
void
)
{
SC_HANDLE ScmHandle;
SC_HANDLE ServiceHandle;
WCHAR DriverBinaryPath[MAX_PATH];
PWSTR s;
if (GetModuleFileName( NULL, DriverBinaryPath, sizeof(DriverBinaryPath)/sizeof(WCHAR) ) == 0) {
return GetLastError();
}
s = wcsrchr( DriverBinaryPath, L'\\' );
if (s == NULL) {
return -1;
}
s += 1;
wcscpy( s, L"satest.sys" );
ScmHandle = OpenSCManager(
NULL,
NULL,
SC_MANAGER_ALL_ACCESS
);
if (ScmHandle == NULL) {
return GetLastError();
}
ServiceHandle = CreateService(
ScmHandle,
L"satest",
L"satest",
SERVICE_ALL_ACCESS,
SERVICE_KERNEL_DRIVER,
SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL,
DriverBinaryPath,
NULL,
NULL,
NULL,
NULL,
NULL
);
if (ServiceHandle == NULL) {
CloseServiceHandle( ScmHandle );
return GetLastError();
}
if (!StartService( ServiceHandle, NULL, NULL )) {
CloseServiceHandle( ServiceHandle );
CloseServiceHandle( ScmHandle );
return GetLastError();
}
CloseServiceHandle( ServiceHandle );
CloseServiceHandle( ScmHandle );
return 0;
}
int
UnInstallTestDriver(
void
)
{
SC_HANDLE ScmHandle;
SC_HANDLE ServiceHandle;
SERVICE_STATUS Status;
ScmHandle = OpenSCManager(
NULL,
NULL,
SC_MANAGER_ALL_ACCESS
);
if (ScmHandle == NULL) {
return GetLastError();
}
ServiceHandle = OpenService(
ScmHandle,
L"satest",
SERVICE_ALL_ACCESS
);
if (ServiceHandle == NULL) {
CloseServiceHandle( ScmHandle );
return GetLastError();
}
if (!ControlService( ServiceHandle, SERVICE_CONTROL_STOP, &Status )) {
CloseServiceHandle( ServiceHandle );
CloseServiceHandle( ScmHandle );
return GetLastError();
}
if (!DeleteService( ServiceHandle )) {
CloseServiceHandle( ServiceHandle );
CloseServiceHandle( ScmHandle );
return GetLastError();
}
CloseServiceHandle( ServiceHandle );
CloseServiceHandle( ScmHandle );
return 0;
}
int
GetAcpiTable(
void
)
{
HANDLE SatestDevice;
BOOL b;
ULONG Bytes;
WdTable = (PVOID) malloc( 4096 );
if (WdTable == NULL) {
wprintf( L"could not allocate memory for ACPI table\n" );
return -1;
}
SatestDevice = OpenSaTestDriver();
if (SatestDevice == INVALID_HANDLE_VALUE) {
wprintf( L"could not open satest driver, ec=[%d]\n", GetLastError() );
return -1;
}
b = DeviceIoControl(
SatestDevice,
IOCTL_SATEST_GET_ACPI_TABLE,
NULL,
0,
WdTable,
4096,
&Bytes,
NULL
);
if (!b) {
wprintf( L"could not get the WDRT ACPI table data, ec=[%d]", GetLastError() );
CloseHandle( SatestDevice );
return -1;
}
CloseHandle( SatestDevice );
return 0;
}
int
QueryWdTimerInfo(
WCHAR option
)
{
HANDLE SatestDevice;
BOOL b;
ULONG Bytes;
SYSTEM_WATCHDOG_TIMER_INFORMATION WdTimerInfo;
switch (option) {
case L'x':
WdTimerInfo.WdInfoClass = WdInfoTimeoutValue;
break;
case L't':
WdTimerInfo.WdInfoClass = WdInfoTriggerAction;
break;
case L's':
WdTimerInfo.WdInfoClass = WdInfoState;
break;
default:
wprintf( L"missing option\n" );
return -1;
}
SatestDevice = OpenSaTestDriver();
if (SatestDevice == INVALID_HANDLE_VALUE) {
wprintf( L"could not open satest driver, ec=[%d]\n", GetLastError() );
return -1;
}
b = DeviceIoControl(
SatestDevice,
IOCTL_SATEST_QUERY_WATCHDOG_TIMER_INFORMATION,
NULL,
0,
&WdTimerInfo,
sizeof(WdTimerInfo),
&Bytes,
NULL
);
if (!b) {
wprintf( L"could not query the WD timer info, ec=[%d]", GetLastError() );
CloseHandle( SatestDevice );
return -1;
}
switch (option) {
case L'x':
wprintf( L"Watchdog timeout value = [%x]\n", WdTimerInfo.DataValue );
break;
case L't':
wprintf( L"Watchdog trigger action = [%x]\n", WdTimerInfo.DataValue );
break;
case L's':
wprintf( L"Watchdog state = [%x]\n", WdTimerInfo.DataValue );
break;
}
CloseHandle( SatestDevice );
return 0;
}
int
SetWdTimerInfo(
PWSTR option
)
{
HANDLE SatestDevice;
BOOL b;
ULONG Bytes;
SYSTEM_WATCHDOG_TIMER_INFORMATION WdTimerInfo;
switch (option[0]) {
case L'x':
if (option[1] != '=') {
wprintf( L"missing timeout value\n" );
return -1;
}
WdTimerInfo.WdInfoClass = WdInfoTimeoutValue;
WdTimerInfo.DataValue = wcstoul( &option[2], NULL, 0 );
break;
case L't':
if (option[1] != '=') {
wprintf( L"missing trigger action value\n" );
return -1;
}
WdTimerInfo.WdInfoClass = WdInfoTriggerAction;
WdTimerInfo.DataValue = wcstoul( &option[2], NULL, 0 );
break;
case L'r':
WdTimerInfo.WdInfoClass = WdInfoResetTimer;
WdTimerInfo.DataValue = 0;
break;
case L'p':
WdTimerInfo.WdInfoClass = WdInfoStopTimer;
WdTimerInfo.DataValue = 0;
break;
case L's':
WdTimerInfo.WdInfoClass = WdInfoStartTimer;
WdTimerInfo.DataValue = 0;
break;
default:
wprintf( L"missing option\n" );
return -1;
}
SatestDevice = OpenSaTestDriver();
if (SatestDevice == INVALID_HANDLE_VALUE) {
wprintf( L"could not open satest driver, ec=[%d]\n", GetLastError() );
return -1;
}
b = DeviceIoControl(
SatestDevice,
IOCTL_SATEST_SET_WATCHDOG_TIMER_INFORMATION,
&WdTimerInfo,
sizeof(WdTimerInfo),
NULL,
0,
&Bytes,
NULL
);
if (!b) {
wprintf( L"could not set the WD timer info, ec=[%d]", GetLastError() );
CloseHandle( SatestDevice );
return -1;
}
CloseHandle( SatestDevice );
return 0;
}
int
StopWatchdogPing(
void
)
{
return SetWdTimerInfo( L"t=0xbadbadff" );
}
int Usage( void )
{
wprintf( L"\nServer Availaibility Command Line Test Tool\n" );
wprintf( L"Copyright Microsoft Corporation\n" );
wprintf( L"\n" );
wprintf( L"SATEST\n" );
wprintf( L"\n" );
wprintf( L" c - Clear the local display\n" );
wprintf( L" w <bitmap file name> - Display a bitmap on the local display\n" );
wprintf( L" n<r|w>:<slot number> [data value] - Read or write to nvram data slot\n" );
wprintf( L" b<r|w>:<slot number> [data value] - Read or write to boot counter\n" );
wprintf( L" k - Keypad test\n" );
wprintf( L" a - Dump ACPI table\n" );
wprintf( L" t - Stop pinging watchdog hardware timer\n" );
wprintf( L" q:<x|t|s> - Query watchdog timer information\n" );
wprintf( L" x = Timeout value\n" );
wprintf( L" t = Trigger action\n" );
wprintf( L" s = State\n" );
wprintf( L" s:<x|t|s>=<value> - Set watchdog timer information\n" );
wprintf( L" x = Timeout value\n" );
wprintf( L" t = Trigger action\n" );
wprintf( L" r = Reset timer\n" );
wprintf( L" p = Stop timer\n" );
wprintf( L" s = Start timer\n" );
return 0;
}
int _cdecl
wmain(
int argc,
WCHAR *argv[]
)
{
if (argc == 1) {
Usage();
return -1;
}
switch (argv[1][0]) {
case L'?':
Usage();
break;
case L'c':
if (argc == 3) {
int val = wcstoul( argv[2], NULL, 0 );
ClearDisplay( val );
} else {
ClearDisplay( 0 );
}
break;
case L'w':
DisplayBitmap( argv[2] );
break;
case L'n':
{
int slot = 0;
ULONG val = 0;
BOOL Read = TRUE;
if (argv[1][1] == 'r') {
Read = TRUE;
} else if (argv[1][1] == 'w') {
Read = FALSE;
} else {
wprintf( L"test n[r|w]:<slot> <value>\n" );
return -1;
}
if (argv[1][2] != ':') {
wprintf( L"test n[r|w]:<slot> <value>\n" );
return -1;
}
slot = argv[1][3] - L'0';
if (Read) {
val = NvramRead( slot );
wprintf( L"Slot #%x [%08x]\n", slot, val );
} else {
val = wcstoul( argv[2], NULL, 0 );
NvramWrite( slot, val );
}
}
break;
case L'b':
{
int slot = 0;
ULONG val = 0;
BOOL Read = TRUE;
if (argv[1][1] == 'r') {
Read = TRUE;
} else if (argv[1][1] == 'w') {
Read = FALSE;
} else {
wprintf( L"test b[r|w]:<slot> <value>\n" );
return -1;
}
if (argv[1][2] != ':') {
wprintf( L"test b[r|w]:<slot> <value>\n" );
return -1;
}
slot = argv[1][3] - L'0';
if (Read) {
if (BootCounterRead( slot, &val )) {
wprintf( L"Boot counter #%x [%08x]\n", slot, val );
} else {
wprintf( L"Could not read boot counter #%d, ec=%d\n", slot, GetLastError() );
}
} else {
val = wcstoul( argv[2], NULL, 0 );
if (!BootCounterWrite( slot, val )) {
wprintf( L"Could not write boot counter #%d, ec=%d\n", slot, GetLastError() );
}
}
}
break;
case L'k':
DoKeypadTest();
break;
case L'd':
DoWatchdogPingLoop();
break;
case L'a':
if (InstallTestDriver() == ERROR_SUCCESS) {
if (GetAcpiTable() == 0) {
PrintACPITable( WdTable );
}
UnInstallTestDriver();
}
break;
case L'q':
if (argv[1][1] != ':') {
return -1;
}
if (InstallTestDriver() == ERROR_SUCCESS) {
QueryWdTimerInfo( argv[1][2] );
UnInstallTestDriver();
}
break;
case L's':
if (argv[1][1] != ':') {
return -1;
}
if (InstallTestDriver() == ERROR_SUCCESS) {
SetWdTimerInfo( &argv[1][2] );
UnInstallTestDriver();
}
break;
case L't':
if (InstallTestDriver() == ERROR_SUCCESS) {
StopWatchdogPing();
UnInstallTestDriver();
}
break;
default:
Usage();
break;
}
return 0;
}