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.
 
 
 
 
 
 

1228 lines
34 KiB

/*++
Copyright (c) 1991-2002 Microsoft Corporation
Module Name:
erwatch.cpp
Abstract:
This module contains the code to report pending watchdog timeout
events at logon after dirty reboot.
Author:
Michael Maciesowicz (mmacie) 29-May-2001
Environment:
User mode at logon.
Revision History:
--*/
#include "savedump.h"
#include <ntverp.h>
BOOL
WriteWatchdogEventFile(
IN HANDLE FileHandle,
IN PWSTR String
);
BOOL
WriteWatchdogEventFileHeader(
IN HANDLE FileHandle
)
{
WCHAR Buffer[256];
BOOL Status;
SYSTEMTIME Time;
TIME_ZONE_INFORMATION TimeZone;
Status = WriteWatchdogEventFile(FileHandle,
L"//\r\n// Watchdog Event Log File\r\n//\r\n\r\n");
if (TRUE == Status)
{
Status = WriteWatchdogEventFile(FileHandle, L"LogType: Watchdog\r\n");
}
if (TRUE == Status)
{
GetLocalTime(&Time);
if (StringCchPrintf(Buffer,
RTL_NUMBER_OF(Buffer),
L"Created: %d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d\r\n",
Time.wYear,
Time.wMonth,
Time.wDay,
Time.wHour,
Time.wMinute,
Time.wSecond) != S_OK)
{
Status = FALSE;
}
else
{
Status = WriteWatchdogEventFile(FileHandle, Buffer);
}
}
if (TRUE == Status)
{
GetTimeZoneInformation(&TimeZone);
if (StringCchPrintf(Buffer,
RTL_NUMBER_OF(Buffer),
L"TimeZone: %d - %s\r\n",
TimeZone.Bias,
TimeZone.StandardName) != S_OK)
{
Status = FALSE;
}
else
{
Status = WriteWatchdogEventFile(FileHandle, Buffer);
}
}
if (TRUE == Status)
{
if (StringCchPrintf(Buffer, RTL_NUMBER_OF(Buffer),
L"WindowsVersion: " LVER_PRODUCTVERSION_STR
L"\r\n") != S_OK)
{
Status = FALSE;
}
else
{
Status = WriteWatchdogEventFile(FileHandle, Buffer);
}
}
if (TRUE == Status)
{
Status = WriteWatchdogEventFile(FileHandle,
L"EventType: 0xEA - Thread Stuck in Device Driver\r\n");
}
return Status;
}
HANDLE
CreateWatchdogEventFile(
OUT PWSTR FileName
)
{
INT Retry;
WCHAR DirName[MAX_PATH];
SYSTEMTIME Time;
HANDLE FileHandle;
ULONG ReturnedSize;
ASSERT(NULL != FileName);
//
// Create %SystemRoot%\LogFiles\Watchdog directory for event files.
//
ReturnedSize = GetWindowsDirectory(DirName, RTL_NUMBER_OF(DirName));
if (ReturnedSize < 1 || ReturnedSize >= RTL_NUMBER_OF(DirName))
{
return INVALID_HANDLE_VALUE;
}
if (StringCchCat(DirName, RTL_NUMBER_OF(DirName), L"\\LogFiles") != S_OK)
{
return INVALID_HANDLE_VALUE;
}
CreateDirectory(DirName, NULL);
if (StringCchCat(DirName, RTL_NUMBER_OF(DirName), L"\\WatchDog") != S_OK)
{
return INVALID_HANDLE_VALUE;
}
CreateDirectory(DirName, NULL);
//
// Create watchdog event file as YYMMDD_HHMM_NN.wdl.
//
GetLocalTime(&Time);
for (Retry = 1; Retry < ER_WD_MAX_RETRY; Retry++)
{
if (StringCchPrintf(FileName,
MAX_PATH,
L"%s\\%2.2d%2.2d%2.2d_%2.2d%2.2d_%2.2d.wdl",
DirName,
Time.wYear % 100,
Time.wMonth,
Time.wDay,
Time.wHour,
Time.wMinute,
Retry) != S_OK)
{
return INVALID_HANDLE_VALUE;
}
FileHandle = CreateFile(FileName,
GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
CREATE_NEW,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (INVALID_HANDLE_VALUE != FileHandle)
{
break;
}
}
//
// If we failed to create a suitable file name just fail.
//
if (Retry == ER_WD_MAX_RETRY)
{
return INVALID_HANDLE_VALUE;
}
if (!WriteWatchdogEventFileHeader(FileHandle))
{
CloseHandle(FileHandle);
DeleteFile(FileName);
FileHandle = INVALID_HANDLE_VALUE;
}
return FileHandle;
}
VOID
GetDriverInfo(
IN HKEY Key,
IN OPTIONAL PWCHAR Extension,
OUT PER_WD_DRIVER_INFO DriverInfo
)
/*++
Routine Description:
This routine collects driver's version info.
Arguments:
Key - Watchdog open key (device specific).
Extension - Driver file name extension if one should be appended.
DriverInfo - Storage for driver version info.
--*/
{
PVOID VersionBuffer;
PVOID VersionValue;
LONG WinStatus;
DWORD Handle;
ULONG Index;
USHORT CodePage;
UINT Length;
if (NULL == DriverInfo)
{
return;
}
ZeroMemory(DriverInfo, sizeof (ER_WD_DRIVER_INFO));
//
// Get driver file name from registry.
//
if (GetRegStr(Key, L"DriverName",
DriverInfo->DriverName,
RTL_NUMBER_OF(DriverInfo->DriverName),
NULL) != S_OK)
{
StringCchCopy(DriverInfo->DriverName,
RTL_NUMBER_OF(DriverInfo->DriverName),
L"Unknown");
return;
}
if (Extension)
{
if ((wcslen(DriverInfo->DriverName) <= wcslen(Extension)) ||
wcscmp(DriverInfo->DriverName + wcslen(DriverInfo->DriverName) -
wcslen(Extension), Extension))
{
if (StringCchCat(DriverInfo->DriverName,
RTL_NUMBER_OF(DriverInfo->DriverName),
Extension) != S_OK)
{
StringCchCopy(DriverInfo->DriverName,
RTL_NUMBER_OF(DriverInfo->DriverName),
L"Unknown");
return;
}
}
}
Length = GetFileVersionInfoSize(DriverInfo->DriverName, &Handle);
if (Length)
{
VersionBuffer = malloc(Length);
if (NULL != VersionBuffer)
{
if (GetFileVersionInfo(DriverInfo->DriverName, Handle,
Length, VersionBuffer))
{
//
// Get fixed file info.
//
if (VerQueryValue(VersionBuffer,
L"\\",
&VersionValue,
&Length) &&
Length == sizeof(DriverInfo->FixedFileInfo))
{
CopyMemory(&(DriverInfo->FixedFileInfo),
VersionValue,
Length);
}
//
// Try to locate English code page.
//
CodePage = 0;
if (VerQueryValue(VersionBuffer,
L"\\VarFileInfo\\Translation",
&VersionValue,
&Length))
{
for (Index = 0;
Index < Length / sizeof (ER_WD_LANG_AND_CODE_PAGE);
Index++)
{
if (((PER_WD_LANG_AND_CODE_PAGE)VersionValue + Index)->
Language == ER_WD_LANG_ENGLISH)
{
CodePage = ((PER_WD_LANG_AND_CODE_PAGE)
VersionValue + Index)->CodePage;
break;
}
}
}
if (CodePage)
{
WCHAR ValueName[ER_WD_MAX_NAME_LENGTH + 1];
PWCHAR Destination[] =
{
DriverInfo->Comments,
DriverInfo->CompanyName,
DriverInfo->FileDescription,
DriverInfo->FileVersion,
DriverInfo->InternalName,
DriverInfo->LegalCopyright,
DriverInfo->LegalTrademarks,
DriverInfo->OriginalFilename,
DriverInfo->PrivateBuild,
DriverInfo->ProductName,
DriverInfo->ProductVersion,
DriverInfo->SpecialBuild,
NULL
};
PWCHAR Source[] =
{
L"Comments",
L"CompanyName",
L"FileDescription",
L"FileVersion",
L"InternalName",
L"LegalCopyright",
L"LegalTrademarks",
L"OriginalFilename",
L"PrivateBuild",
L"ProductName",
L"ProductVersion",
L"SpecialBuild",
NULL
};
//
// Read version properties.
//
for (Index = 0;
Source[Index] && Destination[Index];
Index++)
{
if (StringCchPrintf(ValueName,
RTL_NUMBER_OF(ValueName),
L"\\StringFileInfo\\%04X%04X\\%s",
ER_WD_LANG_ENGLISH,
CodePage,
Source[Index]) == S_OK &&
VerQueryValue(VersionBuffer,
ValueName,
&VersionValue,
&Length))
{
CopyMemory(Destination[Index],
VersionValue,
min(Length * sizeof (WCHAR),
ER_WD_MAX_FILE_INFO_LENGTH *
sizeof (WCHAR)));
}
}
}
}
free(VersionBuffer);
}
}
}
#define MAX_DATA_CHARS (ER_WD_MAX_DATA_SIZE / sizeof(WCHAR))
BOOL
SaveWatchdogEventData(
IN HANDLE FileHandle,
IN HKEY Key,
IN PER_WD_DRIVER_INFO DriverInfo
)
/*++
Routine Description:
This routine transfers watchdog event data from registry to
the watchdog event report file.
Arguments:
FileHandle - Handle of open watchdog event report file.
Key - Watchdog open key (device specific).
Return Value:
TRUE if successful, FALSE otherwise.
--*/
{
LONG WinStatus;
DWORD Index;
DWORD NameLength;
DWORD DataSize;
DWORD ReturnedSize;
DWORD Type;
WCHAR Name[ER_WD_MAX_NAME_LENGTH + 1];
WCHAR DwordBuffer[20];
PBYTE Data;
BOOL Status = TRUE;
ASSERT(INVALID_HANDLE_VALUE != FileHandle);
Data = (PBYTE)malloc(ER_WD_MAX_DATA_SIZE);
if (NULL == Data)
{
return FALSE;
}
//
// Pull watchdog data from registry and write it to report.
//
for (Index = 0;; Index++)
{
//
// Read watchdog registry value.
//
NameLength = ER_WD_MAX_NAME_LENGTH;
DataSize = ER_WD_MAX_DATA_SIZE;
WinStatus = RegEnumValue(Key,
Index,
Name,
&NameLength,
NULL,
&Type,
Data,
&DataSize);
if (ERROR_NO_MORE_ITEMS == WinStatus)
{
break;
}
if (ERROR_SUCCESS != WinStatus)
{
continue;
}
//
// Pick up strings and dwords only.
//
if ((REG_EXPAND_SZ == Type) || (REG_SZ == Type) ||
(REG_MULTI_SZ == Type) || (REG_DWORD == Type))
{
//
// Write registry entry to watchdog event file.
//
Status = WriteWatchdogEventFile(FileHandle, Name);
if (TRUE != Status)
{
break;
}
Status = WriteWatchdogEventFile(FileHandle, L": ");
if (TRUE != Status)
{
break;
}
if (REG_DWORD == Type)
{
if (StringCchPrintf(DwordBuffer, RTL_NUMBER_OF(DwordBuffer),
L"%u", *(PULONG)Data) != S_OK)
{
Status = FALSE;
}
else
{
Status = WriteWatchdogEventFile(FileHandle, DwordBuffer);
}
}
else
{
Status = WriteWatchdogEventFile(FileHandle, (PWSTR)Data);
}
if (TRUE != Status)
{
break;
}
Status = WriteWatchdogEventFile(FileHandle, L"\r\n");
if (TRUE != Status)
{
break;
}
}
}
//
// Write driver info to report.
//
if (NULL != DriverInfo)
{
if (TRUE == Status)
{
if (StringCchPrintf((PWCHAR)Data, MAX_DATA_CHARS,
L"DriverFixedFileInfo: %08X %08X %08X %08X "
L"%08X %08X %08X %08X %08X %08X %08X %08X %08X\r\n",
DriverInfo->FixedFileInfo.dwSignature,
DriverInfo->FixedFileInfo.dwStrucVersion,
DriverInfo->FixedFileInfo.dwFileVersionMS,
DriverInfo->FixedFileInfo.dwFileVersionLS,
DriverInfo->FixedFileInfo.dwProductVersionMS,
DriverInfo->FixedFileInfo.dwProductVersionLS,
DriverInfo->FixedFileInfo.dwFileFlagsMask,
DriverInfo->FixedFileInfo.dwFileFlags,
DriverInfo->FixedFileInfo.dwFileOS,
DriverInfo->FixedFileInfo.dwFileType,
DriverInfo->FixedFileInfo.dwFileSubtype,
DriverInfo->FixedFileInfo.dwFileDateMS,
DriverInfo->FixedFileInfo.dwFileDateLS) != S_OK)
{
Status = FALSE;
}
else
{
Status = WriteWatchdogEventFile(FileHandle, (PWCHAR)Data);
}
}
if ((TRUE == Status) && DriverInfo->Comments[0])
{
if (StringCchPrintf((PWCHAR)Data, MAX_DATA_CHARS,
L"DriverComments: %s\r\n",
DriverInfo->Comments) != S_OK)
{
Status = FALSE;
}
else
{
Status = WriteWatchdogEventFile(FileHandle, (PWCHAR)Data);
}
}
if ((TRUE == Status) && DriverInfo->CompanyName[0])
{
if (StringCchPrintf((PWCHAR)Data, MAX_DATA_CHARS,
L"DriverCompanyName: %s\r\n",
DriverInfo->CompanyName) != S_OK)
{
Status = FALSE;
}
else
{
Status = WriteWatchdogEventFile(FileHandle, (PWCHAR)Data);
}
}
if ((TRUE == Status) && DriverInfo->FileDescription[0])
{
if (StringCchPrintf((PWCHAR)Data, MAX_DATA_CHARS,
L"DriverFileDescription: %s\r\n",
DriverInfo->FileDescription) != S_OK)
{
Status = FALSE;
}
else
{
Status = WriteWatchdogEventFile(FileHandle, (PWCHAR)Data);
}
}
if ((TRUE == Status) && DriverInfo->FileVersion[0])
{
if (StringCchPrintf((PWCHAR)Data, MAX_DATA_CHARS,
L"DriverFileVersion: %s\r\n",
DriverInfo->FileVersion) != S_OK)
{
Status = FALSE;
}
else
{
Status = WriteWatchdogEventFile(FileHandle, (PWCHAR)Data);
}
}
if ((TRUE == Status) && DriverInfo->InternalName[0])
{
if (StringCchPrintf((PWCHAR)Data, MAX_DATA_CHARS,
L"DriverInternalName: %s\r\n",
DriverInfo->InternalName) != S_OK)
{
Status = FALSE;
}
else
{
Status = WriteWatchdogEventFile(FileHandle, (PWCHAR)Data);
}
}
if ((TRUE == Status) && DriverInfo->LegalCopyright[0])
{
if (StringCchPrintf((PWCHAR)Data, MAX_DATA_CHARS,
L"DriverLegalCopyright: %s\r\n",
DriverInfo->LegalCopyright) != S_OK)
{
Status = FALSE;
}
else
{
Status = WriteWatchdogEventFile(FileHandle, (PWCHAR)Data);
}
}
if ((TRUE == Status) && DriverInfo->LegalTrademarks[0])
{
if (StringCchPrintf((PWCHAR)Data, MAX_DATA_CHARS,
L"DriverLegalTrademarks: %s\r\n",
DriverInfo->LegalTrademarks) != S_OK)
{
Status = FALSE;
}
else
{
Status = WriteWatchdogEventFile(FileHandle, (PWCHAR)Data);
}
}
if ((TRUE == Status) && DriverInfo->OriginalFilename[0])
{
if (StringCchPrintf((PWCHAR)Data, MAX_DATA_CHARS,
L"DriverOriginalFilename: %s\r\n",
DriverInfo->OriginalFilename) != S_OK)
{
Status = FALSE;
}
else
{
Status = WriteWatchdogEventFile(FileHandle, (PWCHAR)Data);
}
}
if ((TRUE == Status) && DriverInfo->PrivateBuild[0])
{
if (StringCchPrintf((PWCHAR)Data, MAX_DATA_CHARS,
L"DriverPrivateBuild: %s\r\n",
DriverInfo->PrivateBuild) != S_OK)
{
Status = FALSE;
}
else
{
Status = WriteWatchdogEventFile(FileHandle, (PWCHAR)Data);
}
}
if ((TRUE == Status) && DriverInfo->ProductName[0])
{
if (StringCchPrintf((PWCHAR)Data, MAX_DATA_CHARS,
L"DriverProductName: %s\r\n",
DriverInfo->ProductName) != S_OK)
{
Status = FALSE;
}
else
{
Status = WriteWatchdogEventFile(FileHandle, (PWCHAR)Data);
}
}
if ((TRUE == Status) && DriverInfo->ProductVersion[0])
{
if (StringCchPrintf((PWCHAR)Data, MAX_DATA_CHARS,
L"DriverProductVersion: %s\r\n",
DriverInfo->ProductVersion) != S_OK)
{
Status = FALSE;
}
else
{
Status = WriteWatchdogEventFile(FileHandle, (PWCHAR)Data);
}
}
if ((TRUE == Status) && DriverInfo->SpecialBuild[0])
{
if (StringCchPrintf((PWCHAR)Data, MAX_DATA_CHARS,
L"DriverSpecialBuild: %s\r\n",
DriverInfo->SpecialBuild) != S_OK)
{
Status = FALSE;
}
else
{
Status = WriteWatchdogEventFile(FileHandle, (PWCHAR)Data);
}
}
}
if (NULL != Data)
{
free(Data);
Data = NULL;
}
return Status;
}
HRESULT
WatchdogEventHandler(
IN BOOL NotifyPcHealth
)
/*++
Routine Description:
This is the boot time routine to handle pending watchdog events.
Arguments:
NotifyPcHealth - TRUE if we should report event to PC Health, FALSE otherwise.
--*/
{
HKEY Key;
ULONG WinStatus;
ULONG Type;
ULONG Length;
ULONG EventFlag;
ULONG Index;
SEventInfoW EventInfo;
HANDLE FileHandle;
WCHAR FileList[2 * MAX_PATH];
PWSTR DeleteLog;
PWSTR FinalFileList;
WCHAR Stage2Url[ER_WD_MAX_URL_LENGTH + 1];
PWCHAR MessageBuffer;
PWCHAR DescriptionBuffer;
PWCHAR DeviceDescription;
PWCHAR String000;
PWCHAR String001;
PWCHAR String002;
PWCHAR String003;
PWCHAR String004;
PWCHAR String005;
BOOL LogStatus;
HRESULT ReturnStatus;
HINSTANCE Instance;
PER_WD_DRIVER_INFO DriverInfo;
OSVERSIONINFOEX OsVersion;
Key = NULL;
MessageBuffer = NULL;
DescriptionBuffer = NULL;
DeviceDescription = NULL;
String000 = NULL;
String001 = NULL;
String002 = NULL;
String003 = NULL;
String004 = NULL;
String005 = NULL;
ReturnStatus = E_FAIL;
Instance = (HINSTANCE)GetModuleHandle(NULL);
DriverInfo = NULL;
LogStatus = FALSE;
DeleteLog = NULL;
//
// Check if Watchdog\Display key present.
//
WinStatus = RegOpenKey(HKEY_LOCAL_MACHINE,
SUBKEY_WATCHDOG_DISPLAY,
&Key);
if (ERROR_SUCCESS != WinStatus)
{
return S_FALSE;
}
//
// Check if watchdog display event captured.
//
GetRegWord32(Key, L"EventFlag", &EventFlag, 0, TRUE);
if (!EventFlag)
{
ReturnStatus = S_FALSE;
goto Exit;
}
//
// Report watchdog event to PC Health if requested.
//
if (!NotifyPcHealth)
{
ReturnStatus = S_FALSE;
goto Exit;
}
//
// Allocate storage for localized strings.
// Load localized strings from resources.
//
String000 = (PWCHAR)malloc(ER_WD_MAX_STRING * sizeof(WCHAR));
String001 = (PWCHAR)malloc(ER_WD_MAX_STRING * sizeof(WCHAR));
String002 = (PWCHAR)malloc(ER_WD_MAX_STRING * sizeof(WCHAR));
String003 = (PWCHAR)malloc(ER_WD_MAX_STRING * sizeof(WCHAR));
String004 = (PWCHAR)malloc(ER_WD_MAX_STRING * sizeof(WCHAR));
String005 = (PWCHAR)malloc(ER_WD_MAX_STRING * sizeof(WCHAR));
if (!String000 ||
!LoadString(Instance, IDS_000, String000, ER_WD_MAX_STRING) ||
!String001 ||
!LoadString(Instance, IDS_001, String001, ER_WD_MAX_STRING) ||
!String002 ||
!LoadString(Instance, IDS_002, String002, ER_WD_MAX_STRING) ||
!String003 ||
!LoadString(Instance, IDS_003, String003, ER_WD_MAX_STRING) ||
!String004 ||
!LoadString(Instance, IDS_004, String004, ER_WD_MAX_STRING) ||
!String005 ||
!LoadString(Instance, IDS_005, String005, ER_WD_MAX_STRING))
{
ReturnStatus = E_OUTOFMEMORY;
goto Exit;
}
//
// Allocate and get DriverInfo data.
// DriverInfo is not critical information so don't
// quit on failure.
//
DriverInfo = (PER_WD_DRIVER_INFO)malloc(sizeof (ER_WD_DRIVER_INFO));
if (NULL != DriverInfo)
{
GetDriverInfo(Key, L".dll", DriverInfo);
}
//
// Create watchdog report file.
//
FileHandle = CreateWatchdogEventFile(FileList);
if (INVALID_HANDLE_VALUE != FileHandle)
{
LogStatus = TRUE;
DeleteLog = FileList + wcslen(FileList);
}
if (TRUE == LogStatus)
{
LogStatus = WriteWatchdogEventFile(
FileHandle,
L"\r\n//\r\n"
L"// The driver for the display device got stuck in an infinite loop. This\r\n"
L"// usually indicates a problem with the device itself or with the device\r\n"
L"// driver programming the hardware incorrectly. Please check with your\r\n"
L"// display device vendor for any driver updates.\r\n"
L"//\r\n\r\n");
}
if (TRUE == LogStatus)
{
LogStatus = SaveWatchdogEventData(FileHandle, Key, DriverInfo);
}
if (INVALID_HANDLE_VALUE != FileHandle)
{
CloseHandle(FileHandle);
}
//
// Append minidump file name if minidump available (server won't have it).
//
if (LogStatus)
{
if (g_MiniDumpFile[0])
{
if (StringCchCat(FileList, RTL_NUMBER_OF(FileList),
L"|") != S_OK ||
StringCchCat(FileList, RTL_NUMBER_OF(FileList),
g_MiniDumpFile) != S_OK)
{
ReturnStatus = E_OUTOFMEMORY;
goto Exit;
}
}
FinalFileList = FileList;
}
else if (g_MiniDumpFile[0])
{
FinalFileList = g_MiniDumpFile;
}
else
{
// Nothing to report.
ReturnStatus = S_FALSE;
goto Exit;
}
//
// Get device description.
//
DescriptionBuffer = NULL;
DeviceDescription = NULL;
Length = 0;
WinStatus = RegQueryValueEx(Key,
L"DeviceDescription",
NULL,
&Type,
NULL,
&Length);
if (ERROR_SUCCESS == WinStatus && Type == REG_SZ)
{
DescriptionBuffer = (PWCHAR)malloc(Length + sizeof(WCHAR));
if (NULL != DescriptionBuffer)
{
WinStatus = RegQueryValueEx(Key,
L"DeviceDescription",
NULL,
&Type,
(LPBYTE)DescriptionBuffer,
&Length);
DescriptionBuffer[Length / sizeof(WCHAR)] = 0;
}
else
{
Length = 0;
}
}
else
{
WinStatus = ERROR_INVALID_PARAMETER;
}
if ((ERROR_SUCCESS == WinStatus) && (0 != Length))
{
DeviceDescription = DescriptionBuffer;
}
else
{
DeviceDescription = String004;
Length = (ER_WD_MAX_STRING + 1) * sizeof (WCHAR);
}
Length += 2 * ER_WD_MAX_STRING * sizeof (WCHAR);
MessageBuffer = (PWCHAR)malloc(Length);
if (NULL != MessageBuffer)
{
// This should never overflow as we allocated the right amount.
StringCbPrintf(MessageBuffer,
Length,
L"%s%s%s",
String003,
DeviceDescription,
String005);
}
//
// Create stage 2 URL and fill in EventInfo.
//
OsVersion.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);
if (!GetVersionEx((LPOSVERSIONINFOW)&OsVersion))
{
ReturnStatus = LAST_HR();
goto Exit;
}
ZeroMemory(&EventInfo, sizeof (EventInfo));
if (g_DumpHeader.Signature == DUMP_SIGNATURE &&
(g_DumpHeader.BugCheckCode & 0xff) == 0xea)
{
//
// We bluescreened with bugcheck EA - we have minidump and wdl.
//
if ((ReturnStatus =
StringCchPrintf(Stage2Url,
RTL_NUMBER_OF(Stage2Url),
L"\r\nStage2URL=/dw/BlueTwo.asp?"
L"BCCode=%x&BCP1=%p&BCP2=%p&BCP3=%p&BCP4=%p&"
L"OSVer=%d_%d_%d&SP=%d_%d&Product=%d_%d",
g_DumpHeader.BugCheckCode,
(PVOID)(g_DumpHeader.BugCheckParameter1),
(PVOID)(g_DumpHeader.BugCheckParameter2),
(PVOID)(g_DumpHeader.BugCheckParameter3),
(PVOID)(g_DumpHeader.BugCheckParameter4),
OsVersion.dwMajorVersion,
OsVersion.dwMinorVersion,
OsVersion.dwBuildNumber,
OsVersion.wServicePackMajor,
OsVersion.wServicePackMinor,
OsVersion.wSuiteMask,
OsVersion.wProductType)) != S_OK)
{
goto Exit;
}
EventInfo.wszCorpPath = L"blue";
}
else if (g_DumpHeader.Signature == DUMP_SIGNATURE &&
0 == g_DumpHeader.BugCheckCode)
{
//
// User dirty rebooted with watchdog event trapped - we have only wdl.
//
if ((ReturnStatus =
StringCchPrintf(Stage2Url,
RTL_NUMBER_OF(Stage2Url),
L"\r\nStage2URL=/dw/ShutdownTwo.asp?"
L"OSVer=%d_%d_%d&SP=%d_%d&Product=%d_%d",
OsVersion.dwMajorVersion,
OsVersion.dwMinorVersion,
OsVersion.dwBuildNumber,
OsVersion.wServicePackMajor,
OsVersion.wServicePackMinor,
OsVersion.wSuiteMask,
OsVersion.wProductType)) != S_OK)
{
goto Exit;
}
EventInfo.wszCorpPath = L"shutdown";
}
else
{
ReturnStatus = E_UNEXPECTED;
goto Exit;
}
EventInfo.cbSEI = sizeof (EventInfo);
EventInfo.wszEventName = L"Thread Stuck in Device Driver";
EventInfo.wszErrMsg = String002;
EventInfo.wszHdr = String001;
EventInfo.wszTitle = String000;
EventInfo.wszStage1 = NULL;
EventInfo.wszStage2 = Stage2Url;
EventInfo.wszFileList = FinalFileList;
EventInfo.wszEventSrc = NULL;
EventInfo.wszPlea = MessageBuffer;
EventInfo.wszSendBtn = NULL;
EventInfo.wszNoSendBtn = NULL;
EventInfo.fUseLitePlea = FALSE;
EventInfo.fUseIEForURLs = FALSE;
EventInfo.fNoBucketLogs = TRUE;
EventInfo.fNoDefCabLimit = TRUE;
//
// Notify PC Health.
//
ReturnStatus =
FrrvToStatus(ReportEREvent(eetUseEventInfo, NULL, &EventInfo));
// XXX drewb - Leave the log around for later use? When does
// this get deleted? This is what previous code did.
DeleteLog = NULL;
Exit:
//
// Knock down watchdog's EventFlag. We do this after registering our
// event with PC Health.
//
if (Key)
{
RegDeleteValue(Key, L"EventFlag");
RegCloseKey(Key);
}
//
// TODO: Handle additional device classes here when supported.
//
if (DeleteLog)
{
*DeleteLog = 0;
DeleteFile(FileList);
}
free(DescriptionBuffer);
free(MessageBuffer);
free(String000);
free(String001);
free(String002);
free(String003);
free(String004);
free(String005);
free(DriverInfo);
return ReturnStatus;
}
BOOL
WriteWatchdogEventFile(
IN HANDLE FileHandle,
IN PWSTR String
)
/*++
Routine Description:
This routine writes a string to watchdog event report file.
Arguments:
FileHandle - Handle of open watchdog event report file.
String - Points to the string to write.
Return Value:
TRUE if successful, FALSE otherwise.
--*/
{
DWORD Size;
DWORD ReturnedSize;
PCHAR MultiByte;
BOOL Status;
ASSERT(INVALID_HANDLE_VALUE != FileHandle);
ASSERT(NULL != String);
//
// Get buffer size for translated string.
//
Size = WideCharToMultiByte(CP_ACP,
0,
String,
-1,
NULL,
0,
NULL,
NULL);
if (Size <= 1)
{
return Size > 0;
}
MultiByte = (PCHAR)malloc(Size);
if (NULL == MultiByte)
{
return FALSE;
}
Size = WideCharToMultiByte(CP_ACP,
0,
String,
-1,
MultiByte,
Size,
NULL,
NULL);
if (Size > 0)
{
Status = WriteFile(FileHandle,
MultiByte,
Size - 1,
&ReturnedSize,
NULL);
}
else
{
ASSERT(FALSE);
Status = FALSE;
}
free(MultiByte);
return Status;
}