[USERSRV] Hard-error improvements 7/7

- Use a more descriptive "unknown hard error" string than Windows' one.
- Improve the computation of the buffer size for the hard error message
  by using _vscwprintf() instead of just "guessing" which size the fully
  printf'ed message could be.
This commit is contained in:
Hermès Bélusca-Maïto 2018-03-23 23:50:50 +01:00
parent 2363fee51f
commit 29d56f2b29
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0

View file

@ -61,6 +61,28 @@ RtlLoadUnicodeString(
} }
/*
* NOTE: _scwprintf() is NOT exported by ntdll.dll,
* only _vscwprintf() is, so we need to implement it here.
* Code comes from sdk/lib/crt/printf/_scwprintf.c .
*/
int
__cdecl
_scwprintf(
const wchar_t *format,
...)
{
int len;
va_list args;
va_start(args, format);
len = _vscwprintf(format, args);
va_end(args);
return len;
}
/* FIXME */ /* FIXME */
int int
WINAPI WINAPI
@ -349,9 +371,18 @@ UserpFormatMessages(
OUT PULONG pdwTimeout, OUT PULONG pdwTimeout,
IN PHARDERROR_MSG Message) IN PHARDERROR_MSG Message)
{ {
/* Special hardcoded messages */
static const PCWSTR pszUnknownHardError =
L"Unknown Hard Error 0x%08lx\n"
L"Parameters: 0x%p 0x%p 0x%p 0x%p";
static const PCWSTR pszExceptionHardError =
L"Exception processing message 0x%08lx\n"
L"Parameters: 0x%p 0x%p 0x%p 0x%p";
NTSTATUS Status; NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE hProcess; HANDLE hProcess;
ULONG Severity = (ULONG)(Message->Status) >> 30;
ULONG SizeOfStrings; ULONG SizeOfStrings;
ULONG_PTR Parameters[MAXIMUM_HARDERROR_PARAMETERS] = {0}; ULONG_PTR Parameters[MAXIMUM_HARDERROR_PARAMETERS] = {0};
ULONG_PTR CopyParameters[MAXIMUM_HARDERROR_PARAMETERS]; ULONG_PTR CopyParameters[MAXIMUM_HARDERROR_PARAMETERS];
@ -361,8 +392,6 @@ UserpFormatMessages(
PMESSAGE_RESOURCE_ENTRY MessageResource; PMESSAGE_RESOURCE_ENTRY MessageResource;
PWSTR FormatString, pszBuffer; PWSTR FormatString, pszBuffer;
size_t cszBuffer; size_t cszBuffer;
ULONG Severity = (ULONG)(Message->Status) >> 30;
ULONG Size;
/* Open client process */ /* Open client process */
InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL); InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
@ -379,6 +408,13 @@ UserpFormatMessages(
/* Capture all string parameters from the process memory */ /* Capture all string parameters from the process memory */
UserpCaptureStringParameters(Parameters, &SizeOfStrings, Message, hProcess); UserpCaptureStringParameters(Parameters, &SizeOfStrings, Message, hProcess);
/* Initialize the output strings */
TextStringU->Length = 0;
TextStringU->Buffer[0] = UNICODE_NULL;
CaptionStringU->Length = 0;
CaptionStringU->Buffer[0] = UNICODE_NULL;
/* /*
* Check whether it is a service notification, in which case * Check whether it is a service notification, in which case
* we format the parameters and take the short route. * we format the parameters and take the short route.
@ -395,29 +431,15 @@ UserpFormatMessages(
*/ */
*pdwType = (UINT)Parameters[2] & ~MB_SERVICE_NOTIFICATION; *pdwType = (UINT)Parameters[2] & ~MB_SERVICE_NOTIFICATION;
/* Duplicate the UNICODE text message */ /*
* Duplicate the UNICODE text message and caption.
* If no strings or invalid ones have been provided, keep
* the original buffers and reset the string lengths to zero.
*/
if (Message->UnicodeStringParameterMask & 0x1) if (Message->UnicodeStringParameterMask & 0x1)
{
/* A string has been provided: duplicate it */
UserpDuplicateParamStringToUnicodeString(TextStringU, (PCWSTR)Parameters[0]); UserpDuplicateParamStringToUnicodeString(TextStringU, (PCWSTR)Parameters[0]);
}
else
{
/* No string (or invalid one) has been provided: keep the original buffer and reset the string length to zero */
TextStringU->Length = 0;
}
/* Duplicate the UNICODE caption */
if (Message->UnicodeStringParameterMask & 0x2) if (Message->UnicodeStringParameterMask & 0x2)
{
/* A string has been provided: duplicate it */
UserpDuplicateParamStringToUnicodeString(CaptionStringU, (PCWSTR)Parameters[1]); UserpDuplicateParamStringToUnicodeString(CaptionStringU, (PCWSTR)Parameters[1]);
}
else
{
/* No string (or invalid one) has been provided: keep the original buffer and reset the string length to zero */
CaptionStringU->Length = 0;
}
/* Set the timeout */ /* Set the timeout */
if (Message->NumberOfParameters >= 4) if (Message->NumberOfParameters >= 4)
@ -493,7 +515,8 @@ UserpFormatMessages(
FileNameU = g_SystemProcessU; FileNameU = g_SystemProcessU;
} }
/* Get text string of the error code */ /* Retrieve the description of the error code */
FormatA.Buffer = NULL;
Status = RtlFindMessage(GetModuleHandleW(L"ntdll"), Status = RtlFindMessage(GetModuleHandleW(L"ntdll"),
(ULONG_PTR)RT_MESSAGETABLE, (ULONG_PTR)RT_MESSAGETABLE,
LANG_NEUTRAL, LANG_NEUTRAL,
@ -511,41 +534,40 @@ UserpFormatMessages(
RtlInitAnsiString(&FormatA, (PSTR)MessageResource->Text); RtlInitAnsiString(&FormatA, (PSTR)MessageResource->Text);
/* Status = */ RtlAnsiStringToUnicodeString(&FormatU, &FormatA, TRUE); /* Status = */ RtlAnsiStringToUnicodeString(&FormatU, &FormatA, TRUE);
} }
ASSERT(FormatU.Buffer);
} }
else else
{ {
/* /*
* Fall back to hardcoded value. * Fall back to unknown hard error format string.
* NOTE: The value used here is ReactOS-specific: it allows specifying * NOTE: The value used here is ReactOS-specific: it allows specifying
* the exact hard error status value and the parameters. The version * the exact hard error status value and the parameters, contrary to
* used on Windows only says "Unknown Hard Error". * the one on Windows which only says: "Unknown Hard Error".
*/ */
#if 0 RtlInitEmptyUnicodeString(&FormatU, NULL, 0);
RtlInitUnicodeString(&FormatU, L"Unknown Hard Error 0x%08lx\n"
L"Parameters: 0x%p 0x%p 0x%p 0x%p");
#else
RtlInitUnicodeString(&FormatU, L"Unknown Hard Error 0x%08lx");
CopyParameters[0] = Message->Status;
#endif
FormatA.Buffer = NULL; FormatA.Buffer = NULL;
} }
FormatString = FormatU.Buffer; FormatString = FormatU.Buffer;
/* Check whether a caption exists */ /* Check whether a caption is specified in the format string */
if (FormatString[0] == L'{') if (FormatString && FormatString[0] == L'{')
{ {
/* Set caption start */ /* Set caption start */
TempStringU.Buffer = ++FormatString; TempStringU.Buffer = ++FormatString;
/* Get size of the caption */ /* Get the caption size and find where the format string really starts */
for (Size = 0; *FormatString != UNICODE_NULL && *FormatString != L'}'; Size++) for (TempStringU.Length = 0;
FormatString++; *FormatString != UNICODE_NULL && *FormatString != L'}';
++TempStringU.Length)
{
++FormatString;
}
/* Skip '}', '\r', '\n' */ /* Skip '}', '\r', '\n' */
FormatString += 3; FormatString += 3;
TempStringU.Length = (USHORT)(Size * sizeof(WCHAR)); TempStringU.Length *= sizeof(WCHAR);
TempStringU.MaximumLength = TempStringU.Length; TempStringU.MaximumLength = TempStringU.Length;
} }
else else
@ -612,6 +634,7 @@ UserpFormatMessages(
} }
} }
CaptionStringU->Length = 0; CaptionStringU->Length = 0;
CaptionStringU->Buffer[0] = UNICODE_NULL;
/* Append the file name, the separator and the caption text */ /* Append the file name, the separator and the caption text */
RtlStringCbPrintfW(CaptionStringU->Buffer, RtlStringCbPrintfW(CaptionStringU->Buffer,
@ -620,19 +643,22 @@ UserpFormatMessages(
&WindowTitleU, &FileNameU, &TempStringU); &WindowTitleU, &FileNameU, &TempStringU);
CaptionStringU->Length = (USHORT)(wcslen(CaptionStringU->Buffer) * sizeof(WCHAR)); CaptionStringU->Length = (USHORT)(wcslen(CaptionStringU->Buffer) * sizeof(WCHAR));
/* Free string buffers if needed */ /* Free the strings if needed */
if (WindowTitleU.Buffer) RtlFreeUnicodeString(&WindowTitleU); if (WindowTitleU.Buffer) RtlFreeUnicodeString(&WindowTitleU);
if (hProcess) RtlFreeUnicodeString(&FileNameU); if (hProcess) RtlFreeUnicodeString(&FileNameU);
// FIXME: What is 42 == ?? Format2A.Buffer = NULL;
Size = 42;
/* If we have an unknown hard error, skip the special cases handling */
if (!FormatString)
goto BuildMessage;
/* Check if this is an exception message */ /* Check if this is an exception message */
if (Message->Status == STATUS_UNHANDLED_EXCEPTION) if (Message->Status == STATUS_UNHANDLED_EXCEPTION)
{ {
ULONG ExceptionCode = CopyParameters[0]; ULONG ExceptionCode = CopyParameters[0];
/* Get text string of the exception code */ /* Retrieve the description of the exception code */
Status = RtlFindMessage(GetModuleHandleW(L"ntdll"), Status = RtlFindMessage(GetModuleHandleW(L"ntdll"),
(ULONG_PTR)RT_MESSAGETABLE, (ULONG_PTR)RT_MESSAGETABLE,
LANG_NEUTRAL, LANG_NEUTRAL,
@ -650,10 +676,12 @@ UserpFormatMessages(
RtlInitAnsiString(&Format2A, (PSTR)MessageResource->Text); RtlInitAnsiString(&Format2A, (PSTR)MessageResource->Text);
/* Status = */ RtlAnsiStringToUnicodeString(&Format2U, &Format2A, TRUE); /* Status = */ RtlAnsiStringToUnicodeString(&Format2U, &Format2A, TRUE);
} }
ASSERT(Format2U.Buffer);
/* Handle special cases */ /* Handle special cases */
if (ExceptionCode == STATUS_ACCESS_VIOLATION) if (ExceptionCode == STATUS_ACCESS_VIOLATION)
{ {
/* Use a new FormatString */
FormatString = Format2U.Buffer; FormatString = Format2U.Buffer;
CopyParameters[0] = CopyParameters[1]; CopyParameters[0] = CopyParameters[1];
CopyParameters[1] = CopyParameters[3]; CopyParameters[1] = CopyParameters[3];
@ -664,6 +692,7 @@ UserpFormatMessages(
} }
else if (ExceptionCode == STATUS_IN_PAGE_ERROR) else if (ExceptionCode == STATUS_IN_PAGE_ERROR)
{ {
/* Use a new FormatString */
FormatString = Format2U.Buffer; FormatString = Format2U.Buffer;
CopyParameters[0] = CopyParameters[1]; CopyParameters[0] = CopyParameters[1];
CopyParameters[1] = CopyParameters[3]; CopyParameters[1] = CopyParameters[3];
@ -702,24 +731,64 @@ UserpFormatMessages(
CopyParameters[1] = CopyParameters[0]; CopyParameters[1] = CopyParameters[0];
CopyParameters[0] = (ULONG_PTR)L"unknown software exception"; CopyParameters[0] = (ULONG_PTR)L"unknown software exception";
} }
/* Add explanation text for dialog buttons */
if (Message->ValidResponseOptions == OptionOk ||
Message->ValidResponseOptions == OptionOkCancel)
{
/* Reserve space for one newline and the OK-terminate-program string */
Size += 1 + (g_OKTerminateU.Length / sizeof(WCHAR));
}
if (Message->ValidResponseOptions == OptionOkCancel)
{
/* Reserve space for one newline and the CANCEL-debug-program string */
Size += 1 + (g_CancelDebugU.Length / sizeof(WCHAR));
}
} }
/* Calculate buffer length for the text message */ BuildMessage:
cszBuffer = FormatU.Length + SizeOfStrings + Size * sizeof(WCHAR) + /*
sizeof(UNICODE_NULL); * Calculate buffer length for the text message. If FormatString
* is NULL this means we have an unknown hard error whose format
* string is in FormatU.
*/
cszBuffer = 0;
/* Wrap in SEH to protect from invalid string parameters */
_SEH2_TRY
{
if (!FormatString)
{
/* Fall back to unknown hard error format string, and use the original parameters */
cszBuffer = _scwprintf(pszUnknownHardError,
Message->Status,
Parameters[0], Parameters[1],
Parameters[2], Parameters[3]);
cszBuffer *= sizeof(WCHAR);
}
else
{
cszBuffer = _scwprintf(FormatString,
CopyParameters[0], CopyParameters[1],
CopyParameters[2], CopyParameters[3]);
cszBuffer *= sizeof(WCHAR);
/* Add a description for the dialog buttons */
if (Message->Status == STATUS_UNHANDLED_EXCEPTION)
{
if (Message->ValidResponseOptions == OptionOk ||
Message->ValidResponseOptions == OptionOkCancel)
{
/* Reserve space for one newline and the OK-terminate-program string */
cszBuffer += sizeof(WCHAR) + g_OKTerminateU.Length;
}
if (Message->ValidResponseOptions == OptionOkCancel)
{
/* Reserve space for one newline and the CANCEL-debug-program string */
cszBuffer += sizeof(WCHAR) + g_CancelDebugU.Length;
}
}
}
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
/* An exception occurred, use a default string with the original parameters */
cszBuffer = _scwprintf(pszExceptionHardError,
Message->Status,
Parameters[0], Parameters[1],
Parameters[2], Parameters[3]);
cszBuffer *= sizeof(WCHAR);
}
_SEH2_END;
cszBuffer += SizeOfStrings + sizeof(UNICODE_NULL);
if (TextStringU->MaximumLength < cszBuffer) if (TextStringU->MaximumLength < cszBuffer)
{ {
/* Allocate a larger buffer for the text message */ /* Allocate a larger buffer for the text message */
@ -737,6 +806,7 @@ UserpFormatMessages(
} }
} }
TextStringU->Length = 0; TextStringU->Length = 0;
TextStringU->Buffer[0] = UNICODE_NULL;
/* Wrap in SEH to protect from invalid string parameters */ /* Wrap in SEH to protect from invalid string parameters */
_SEH2_TRY _SEH2_TRY
@ -744,32 +814,45 @@ UserpFormatMessages(
/* Print the string into the buffer */ /* Print the string into the buffer */
pszBuffer = TextStringU->Buffer; pszBuffer = TextStringU->Buffer;
cszBuffer = TextStringU->MaximumLength; cszBuffer = TextStringU->MaximumLength;
RtlStringCbPrintfExW(pszBuffer, cszBuffer,
&pszBuffer, &cszBuffer,
STRSAFE_IGNORE_NULLS,
FormatString,
CopyParameters[0], CopyParameters[1],
CopyParameters[2], CopyParameters[3]);
/* Add explanation text for dialog buttons */ if (!FormatString)
if (Message->Status == STATUS_UNHANDLED_EXCEPTION)
{ {
if (Message->ValidResponseOptions == OptionOk || /* Fall back to unknown hard error format string, and use the original parameters */
Message->ValidResponseOptions == OptionOkCancel) RtlStringCbPrintfW(pszBuffer, cszBuffer,
pszUnknownHardError,
Message->Status,
Parameters[0], Parameters[1],
Parameters[2], Parameters[3]);
}
else
{
RtlStringCbPrintfExW(pszBuffer, cszBuffer,
&pszBuffer, &cszBuffer,
0,
FormatString,
CopyParameters[0], CopyParameters[1],
CopyParameters[2], CopyParameters[3]);
/* Add a description for the dialog buttons */
if (Message->Status == STATUS_UNHANDLED_EXCEPTION)
{ {
RtlStringCbPrintfExW(pszBuffer, cszBuffer, if (Message->ValidResponseOptions == OptionOk ||
&pszBuffer, &cszBuffer, Message->ValidResponseOptions == OptionOkCancel)
STRSAFE_IGNORE_NULLS, {
L"\n%wZ", RtlStringCbPrintfExW(pszBuffer, cszBuffer,
&g_OKTerminateU); &pszBuffer, &cszBuffer,
} 0,
if (Message->ValidResponseOptions == OptionOkCancel) L"\n%wZ",
{ &g_OKTerminateU);
RtlStringCbPrintfExW(pszBuffer, cszBuffer, }
&pszBuffer, &cszBuffer, if (Message->ValidResponseOptions == OptionOkCancel)
STRSAFE_IGNORE_NULLS, {
L"\n%wZ", RtlStringCbPrintfExW(pszBuffer, cszBuffer,
&g_CancelDebugU); &pszBuffer, &cszBuffer,
0,
L"\n%wZ",
&g_CancelDebugU);
}
} }
} }
} }
@ -781,8 +864,7 @@ UserpFormatMessages(
RtlStringCbPrintfW(TextStringU->Buffer, RtlStringCbPrintfW(TextStringU->Buffer,
TextStringU->MaximumLength, TextStringU->MaximumLength,
L"Exception processing message 0x%08lx\n" pszExceptionHardError,
L"Parameters: 0x%p 0x%p 0x%p 0x%p",
Message->Status, Message->Status,
Parameters[0], Parameters[1], Parameters[0], Parameters[1],
Parameters[2], Parameters[3]); Parameters[2], Parameters[3]);
@ -791,12 +873,12 @@ UserpFormatMessages(
TextStringU->Length = (USHORT)(wcslen(TextStringU->Buffer) * sizeof(WCHAR)); TextStringU->Length = (USHORT)(wcslen(TextStringU->Buffer) * sizeof(WCHAR));
/* Free converted Unicode strings */ /* Free the converted UNICODE strings */
if (Format2A.Buffer) RtlFreeUnicodeString(&Format2U); if (Format2A.Buffer) RtlFreeUnicodeString(&Format2U);
if (FormatA.Buffer) RtlFreeUnicodeString(&FormatU); if (FormatA.Buffer) RtlFreeUnicodeString(&FormatU);
Quit: Quit:
/* Final cleanup */ /* Free the captured parameters */
UserpFreeStringParameters(Parameters, Message); UserpFreeStringParameters(Parameters, Message);
} }
@ -850,40 +932,43 @@ GetRegInt(
static BOOL static BOOL
UserpShowInformationBalloon( UserpShowInformationBalloon(
IN PCWSTR Text, IN PUNICODE_STRING TextStringU,
IN PCWSTR Caption, IN PUNICODE_STRING CaptionStringU,
IN UINT Type, IN UINT Type,
IN PHARDERROR_MSG Message) IN PHARDERROR_MSG Message)
{ {
ULONG ShellErrorMode; ULONG ShellErrorMode;
HWND hwnd; HWND hWndTaskman;
COPYDATASTRUCT CopyData; COPYDATASTRUCT CopyData;
PBALLOON_HARD_ERROR_DATA pdata; PBALLOON_HARD_ERROR_DATA pdata;
DWORD dwSize, cbTextLen, cbTitleLen; DWORD dwSize, cbTextLen, cbTitleLen;
PWCHAR pText, pCaption; PWCHAR pText, pCaption;
DWORD ret, dwResult; DWORD ret;
DWORD_PTR dwResult;
/* Query the shell error mode value */ /* Query the shell error mode value */
ShellErrorMode = GetRegInt(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Windows", ShellErrorMode = GetRegInt(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Windows",
L"ShellErrorMode", 0); L"ShellErrorMode", 0);
/* Make the shell display the hard error message in balloon only if necessary */ /* Make the shell display the hard error message only if necessary */
if (ShellErrorMode != 1) if (ShellErrorMode != 1)
return FALSE; return FALSE;
hwnd = GetTaskmanWindow(); /* Retrieve the shell task window */
if (!hwnd) hWndTaskman = GetTaskmanWindow();
if (!hWndTaskman)
{ {
DPRINT1("Failed to find shell task window (last error %lu)\n", GetLastError()); DPRINT1("Failed to find shell task window (last error %lu)\n", GetLastError());
return FALSE; return FALSE;
} }
cbTextLen = ((Text ? wcslen(Text) : 0) + 1) * sizeof(WCHAR); cbTextLen = TextStringU->Length + sizeof(UNICODE_NULL);
cbTitleLen = ((Caption ? wcslen(Caption) : 0) + 1) * sizeof(WCHAR); cbTitleLen = CaptionStringU->Length + sizeof(UNICODE_NULL);
dwSize = sizeof(BALLOON_HARD_ERROR_DATA); dwSize = sizeof(BALLOON_HARD_ERROR_DATA);
dwSize += cbTextLen + cbTitleLen; dwSize += cbTextLen + cbTitleLen;
/* Build the data buffer */
pdata = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, dwSize); pdata = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);
if (!pdata) if (!pdata)
{ {
@ -893,31 +978,27 @@ UserpShowInformationBalloon(
pdata->cbHeaderSize = sizeof(BALLOON_HARD_ERROR_DATA); pdata->cbHeaderSize = sizeof(BALLOON_HARD_ERROR_DATA);
pdata->Status = Message->Status; pdata->Status = Message->Status;
pdata->dwType = Type;
if (NT_SUCCESS(Message->Status)) pdata->TitleOffset = pdata->cbHeaderSize;
pdata->dwType = MB_OK; pdata->MessageOffset = pdata->TitleOffset + cbTitleLen;
else if (Message->Status == STATUS_SERVICE_NOTIFICATION)
pdata->dwType = Type;
else
pdata->dwType = MB_ICONINFORMATION;
pdata->TitleOffset = pdata->cbHeaderSize;
pdata->MessageOffset = pdata->TitleOffset;
pdata->MessageOffset += cbTitleLen;
pCaption = (PWCHAR)((ULONG_PTR)pdata + pdata->TitleOffset); pCaption = (PWCHAR)((ULONG_PTR)pdata + pdata->TitleOffset);
pText = (PWCHAR)((ULONG_PTR)pdata + pdata->MessageOffset); pText = (PWCHAR)((ULONG_PTR)pdata + pdata->MessageOffset);
wcscpy(pCaption, Caption); RtlStringCbCopyNW(pCaption, cbTitleLen, CaptionStringU->Buffer, CaptionStringU->Length);
wcscpy(pText, Text); RtlStringCbCopyNW(pText, cbTextLen, TextStringU->Buffer, TextStringU->Length);
/* Send the message */
/* Retrieve a unique system-wide message to communicate hard error data with the shell */
CopyData.dwData = RegisterWindowMessageW(L"HardError"); CopyData.dwData = RegisterWindowMessageW(L"HardError");
CopyData.cbData = dwSize; CopyData.cbData = dwSize;
CopyData.lpData = pdata; CopyData.lpData = pdata;
dwResult = FALSE; dwResult = FALSE;
ret = SendMessageTimeoutW(hWndTaskman, WM_COPYDATA, 0, (LPARAM)&CopyData,
ret = SendMessageTimeoutW(hwnd, WM_COPYDATA, 0, (LPARAM)&CopyData,
SMTO_NORMAL | SMTO_ABORTIFHUNG, 3000, &dwResult); SMTO_NORMAL | SMTO_ABORTIFHUNG, 3000, &dwResult);
/* Free the buffer */
RtlFreeHeap(RtlGetProcessHeap(), 0, pdata); RtlFreeHeap(RtlGetProcessHeap(), 0, pdata);
return (ret && dwResult) ? TRUE : FALSE; return (ret && dwResult) ? TRUE : FALSE;
@ -926,18 +1007,21 @@ UserpShowInformationBalloon(
static static
HARDERROR_RESPONSE HARDERROR_RESPONSE
UserpMessageBox( UserpMessageBox(
IN PCWSTR Text, IN PUNICODE_STRING TextStringU,
IN PCWSTR Caption, IN PUNICODE_STRING CaptionStringU,
IN UINT Type, IN UINT Type,
IN ULONG Timeout) IN ULONG Timeout)
{ {
ULONG MessageBoxResponse; ULONG MessageBoxResponse;
DPRINT("Text = '%S', Caption = '%S', Type = 0x%lx\n", DPRINT("Text = '%S', Caption = '%S', Type = 0x%lx\n",
Text, Caption, Type); TextStringU->Buffer, CaptionStringU->Buffer, Type);
/* Display a message box */ /* Display a message box */
MessageBoxResponse = MessageBoxTimeoutW(NULL, Text, Caption, Type, 0, Timeout); MessageBoxResponse = MessageBoxTimeoutW(NULL,
TextStringU->Buffer,
CaptionStringU->Buffer,
Type, 0, Timeout);
/* Return response value */ /* Return response value */
switch (MessageBoxResponse) switch (MessageBoxResponse)
@ -1028,7 +1112,8 @@ UserServerHardError(
{ {
if (Message->NumberOfParameters < 3) if (Message->NumberOfParameters < 3)
{ {
DPRINT1("Invalid NumberOfParameters = %d for STATUS_SERVICE_NOTIFICATION\n", Message->NumberOfParameters); DPRINT1("Invalid NumberOfParameters = %d for STATUS_SERVICE_NOTIFICATION\n",
Message->NumberOfParameters);
return; // STATUS_INVALID_PARAMETER; return; // STATUS_INVALID_PARAMETER;
} }
// (Message->UnicodeStringParameterMask & 0x3) // (Message->UnicodeStringParameterMask & 0x3)
@ -1062,8 +1147,8 @@ UserServerHardError(
{ {
/* Display the balloon */ /* Display the balloon */
Message->Response = ResponseOk; Message->Response = ResponseOk;
if (UserpShowInformationBalloon(TextU.Buffer, if (UserpShowInformationBalloon(&TextU,
CaptionU.Buffer, &CaptionU,
dwType, dwType,
Message)) Message))
{ {
@ -1073,8 +1158,8 @@ UserServerHardError(
} }
/* Display the message box */ /* Display the message box */
Message->Response = UserpMessageBox(TextU.Buffer, Message->Response = UserpMessageBox(&TextU,
CaptionU.Buffer, &CaptionU,
dwType, dwType,
Timeout); Timeout);