ReactOS 0.4.15-dev-7953-g1f49173
harderror.c File Reference
#include "usersrv.h"
#include <ndk/mmfuncs.h>
#include <undocelfapi.h>
#include <ntstrsafe.h>
#include "resource.h"
#include <debug.h>
Include dependency graph for harderror.c:

Go to the source code of this file.

Macros

#define NTOS_MODE_USER
 
#define NDEBUG
 

Functions

VOID RtlLoadUnicodeString (IN HINSTANCE hInstance OPTIONAL, IN UINT uID, OUT PUNICODE_STRING pUnicodeString, IN PCWSTR pDefaultString)
 
int __cdecl _scwprintf (const wchar_t *format,...)
 
int WINAPI MessageBoxTimeoutW (HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType, WORD wLanguageId, DWORD dwTime)
 
static VOID UserpCaptureStringParameters (OUT PULONG_PTR Parameters, OUT PULONG SizeOfAllUnicodeStrings, IN PHARDERROR_MSG Message, IN HANDLE hProcess OPTIONAL)
 
static VOID UserpFreeStringParameters (IN OUT PULONG_PTR Parameters, IN PHARDERROR_MSG Message)
 
static NTSTATUS UserpGetClientFileName (OUT PUNICODE_STRING ClientFileNameU, IN HANDLE hProcess)
 
static VOID UserpDuplicateParamStringToUnicodeString (IN OUT PUNICODE_STRING UnicodeString, IN PCWSTR ParamString)
 
static VOID UserpFormatMessages (IN OUT PUNICODE_STRING TextStringU, IN OUT PUNICODE_STRING CaptionStringU, OUT PUINT pdwType, OUT PULONG pdwTimeout, IN PHARDERROR_MSG Message)
 
static ULONG GetRegInt (IN PCWSTR KeyName, IN PCWSTR ValueName, IN ULONG DefaultValue)
 
static BOOL UserpShowInformationBalloon (IN PUNICODE_STRING TextStringU, IN PUNICODE_STRING CaptionStringU, IN UINT Type, IN PHARDERROR_MSG Message)
 
static HARDERROR_RESPONSE UserpMessageBox (IN PUNICODE_STRING TextStringU, IN PUNICODE_STRING CaptionStringU, IN UINT Type, IN ULONG Timeout)
 
static VOID UserpLogHardError (IN PUNICODE_STRING TextStringU, IN PUNICODE_STRING CaptionStringU)
 
VOID NTAPI UserServerHardError (IN PCSR_THREAD ThreadData, IN PHARDERROR_MSG Message)
 
VOID UserInitHardErrorsCache (VOID)
 

Variables

LANGID g_CurrentUserLangId = 0
 
UNICODE_STRING g_SuccessU = {0, 0, NULL}
 
UNICODE_STRING g_InformationU = {0, 0, NULL}
 
UNICODE_STRING g_WarningU = {0, 0, NULL}
 
UNICODE_STRING g_ErrorU = {0, 0, NULL}
 
UNICODE_STRING g_SystemProcessU = {0, 0, NULL}
 
UNICODE_STRING g_OKTerminateU = {0, 0, NULL}
 
UNICODE_STRING g_CancelDebugU = {0, 0, NULL}
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 23 of file harderror.c.

◆ NTOS_MODE_USER

#define NTOS_MODE_USER

Definition at line 15 of file harderror.c.

Function Documentation

◆ _scwprintf()

int __cdecl _scwprintf ( const wchar_t format,
  ... 
)

Definition at line 71 of file harderror.c.

74{
75 int len;
77
80 va_end(args);
81
82 return len;
83}
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
GLenum GLsizei len
Definition: glext.h:6722
_Check_return_ _CRTIMP int __cdecl _vscwprintf(_In_z_ _Printf_format_string_ const wchar_t *_Format, va_list _ArgList)
#define args
Definition: format.c:66
Definition: match.c:390

Referenced by UserpFormatMessages().

◆ GetRegInt()

static ULONG GetRegInt ( IN PCWSTR  KeyName,
IN PCWSTR  ValueName,
IN ULONG  DefaultValue 
)
static

Definition at line 885 of file harderror.c.

889{
891 ULONG Value = DefaultValue;
896 UCHAR ValueBuffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(ULONG)];
898
901 &String,
903 NULL,
904 NULL);
905
906 /* Open the registry key */
908 if (NT_SUCCESS(Status))
909 {
910 /* Query the value */
913 &String,
915 ValueInfo,
916 sizeof(ValueBuffer),
917 &ResultLength);
918
919 /* Close the registry key */
921
922 if (NT_SUCCESS(Status) && (ValueInfo->Type == REG_DWORD))
923 {
924 /* Directly retrieve the data */
925 Value = *(PULONG)ValueInfo->Data;
926 }
927 }
928
929 return Value;
930}
LONG NTSTATUS
Definition: precomp.h:26
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Status
Definition: gdiplustypes.h:25
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
@ KeyValuePartialInformation
Definition: nt_native.h:1182
#define KEY_READ
Definition: nt_native.h:1023
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI NTSTATUS NTAPI NtQueryValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, IN PVOID KeyValueInformation, IN ULONG Length, IN PULONG ResultLength)
struct _KEY_VALUE_PARTIAL_INFORMATION KEY_VALUE_PARTIAL_INFORMATION
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
struct _KEY_VALUE_PARTIAL_INFORMATION * PKEY_VALUE_PARTIAL_INFORMATION
#define REG_DWORD
Definition: sdbapi.c:596
uint32_t * PULONG
Definition: typedefs.h:59
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3776
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2699
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2433
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by UserpShowInformationBalloon(), and UserServerHardError().

◆ MessageBoxTimeoutW()

int WINAPI MessageBoxTimeoutW ( HWND  hWnd,
LPCWSTR  lpText,
LPCWSTR  lpCaption,
UINT  uType,
WORD  wLanguageId,
DWORD  dwTime 
)

Referenced by UserpMessageBox().

◆ RtlLoadUnicodeString()

VOID RtlLoadUnicodeString ( IN HINSTANCE hInstance  OPTIONAL,
IN UINT  uID,
OUT PUNICODE_STRING  pUnicodeString,
IN PCWSTR  pDefaultString 
)

Definition at line 40 of file harderror.c.

45{
47
48 /* Try to load the string from the resource */
49 Length = LoadStringW(hInstance, uID, (LPWSTR)&pUnicodeString->Buffer, 0);
50 if (Length == 0)
51 {
52 /* If the resource string was not found, use the fallback default one */
53 RtlInitUnicodeString(pUnicodeString, pDefaultString);
54 }
55 else
56 {
57 /* Set the string length (not NULL-terminated!) */
58 pUnicodeString->MaximumLength = (USHORT)(Length * sizeof(WCHAR));
59 pUnicodeString->Length = pUnicodeString->MaximumLength;
60 }
61}
HINSTANCE hInstance
Definition: charmap.c:19
unsigned int UINT
Definition: ndis.h:50
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
unsigned short USHORT
Definition: pedump.c:61
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by UserInitHardErrorsCache().

◆ UserInitHardErrorsCache()

VOID UserInitHardErrorsCache ( VOID  )

Definition at line 1189 of file harderror.c.

1190{
1192 LCID CurrentUserLCID = 0;
1193
1194 Status = NtQueryDefaultLocale(TRUE, &CurrentUserLCID);
1195 if (!NT_SUCCESS(Status) || CurrentUserLCID == 0)
1196 {
1197 /* Fall back to english locale */
1198 DPRINT1("NtQueryDefaultLocale failed with Status = 0x%08lx\n", Status);
1199 // LOCALE_SYSTEM_DEFAULT;
1201 }
1202 if (g_CurrentUserLangId == LANGIDFROMLCID(CurrentUserLCID))
1203 {
1204 /* The current lang ID and the hard error strings have already been cached */
1205 return;
1206 }
1207
1208 /* Load the strings using the current system locale */
1210 &g_SuccessU, L"Success");
1212 &g_InformationU, L"System Information");
1214 &g_WarningU, L"System Warning");
1216 &g_ErrorU, L"System Error");
1217 // "unknown software exception"
1219 &g_SystemProcessU, L"System Process");
1221 &g_OKTerminateU, L"Click on OK to terminate the program.");
1223 &g_CancelDebugU, L"Click on CANCEL to debug the program.");
1224
1225 /* Remember that we cached the hard error strings */
1226 g_CurrentUserLangId = LANGIDFROMLCID(CurrentUserLCID);
1227}
#define DPRINT1
Definition: precomp.h:8
#define TRUE
Definition: types.h:120
VOID RtlLoadUnicodeString(IN HINSTANCE hInstance OPTIONAL, IN UINT uID, OUT PUNICODE_STRING pUnicodeString, IN PCWSTR pDefaultString)
Definition: harderror.c:40
LANGID g_CurrentUserLangId
Definition: harderror.c:30
UNICODE_STRING g_ErrorU
Definition: harderror.c:34
UNICODE_STRING g_SuccessU
Definition: harderror.c:31
UNICODE_STRING g_WarningU
Definition: harderror.c:33
UNICODE_STRING g_InformationU
Definition: harderror.c:32
UNICODE_STRING g_OKTerminateU
Definition: harderror.c:36
UNICODE_STRING g_SystemProcessU
Definition: harderror.c:35
UNICODE_STRING g_CancelDebugU
Definition: harderror.c:37
#define SORT_DEFAULT
#define MAKELCID(lgid, srtid)
NTSTATUS NTAPI NtQueryDefaultLocale(IN BOOLEAN UserProfile, OUT PLCID DefaultLocaleId)
Definition: locale.c:396
#define L(x)
Definition: ntvdm.h:50
#define MAKELANGID(p, s)
Definition: nls.h:15
#define LANG_ENGLISH
Definition: nls.h:52
#define LANGIDFROMLCID(l)
Definition: nls.h:18
DWORD LCID
Definition: nls.h:13
#define SUBLANG_ENGLISH_US
Definition: nls.h:222
HINSTANCE UserServerDllInstance
Definition: init.c:21
#define IDS_SEVERITY_INFORMATIONAL
Definition: resource.h:20
#define IDS_SEVERITY_WARNING
Definition: resource.h:21
#define IDS_SEVERITY_SUCCESS
Definition: resource.h:19
#define IDS_SYSTEM_PROCESS
Definition: resource.h:24
#define IDS_OK_TERMINATE_PROGRAM
Definition: resource.h:26
#define IDS_SEVERITY_ERROR
Definition: resource.h:22
#define IDS_CANCEL_DEBUG_PROGRAM
Definition: resource.h:27

Referenced by CSR_SERVER_DLL_INIT(), and UserServerHardError().

◆ UserpCaptureStringParameters()

static VOID UserpCaptureStringParameters ( OUT PULONG_PTR  Parameters,
OUT PULONG  SizeOfAllUnicodeStrings,
IN PHARDERROR_MSG  Message,
IN HANDLE hProcess  OPTIONAL 
)
static

Definition at line 100 of file harderror.c.

105{
107 ULONG nParam, Size = 0;
108 UNICODE_STRING TempStringU, ParamStringU;
109 ANSI_STRING TempStringA;
110
111 if (SizeOfAllUnicodeStrings)
112 *SizeOfAllUnicodeStrings = 0;
113
114 /* Read all strings from client space */
115 for (nParam = 0; nParam < Message->NumberOfParameters; ++nParam)
116 {
117 Parameters[nParam] = 0;
118
119 /* Check if the current parameter is a unicode string */
120 if (Message->UnicodeStringParameterMask & (1 << nParam))
121 {
122 /* Skip this string if we do not have a client process */
123 if (!hProcess)
124 continue;
125
126 /* Read the UNICODE_STRING from the process memory */
128 (PVOID)Message->Parameters[nParam],
129 &ParamStringU,
130 sizeof(ParamStringU),
131 NULL);
132 if (!NT_SUCCESS(Status))
133 {
134 /* We failed, skip this string */
135 DPRINT1("NtReadVirtualMemory(Message->Parameters) failed, Status 0x%lx, skipping.\n", Status);
136 continue;
137 }
138
139 /* Allocate a buffer for the string and reserve a NULL terminator */
140 TempStringU.MaximumLength = ParamStringU.Length + sizeof(UNICODE_NULL);
141 TempStringU.Length = ParamStringU.Length;
142 TempStringU.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
144 TempStringU.MaximumLength);
145 if (!TempStringU.Buffer)
146 {
147 /* We failed, skip this string */
148 DPRINT1("Cannot allocate memory with size %u, skipping.\n", TempStringU.MaximumLength);
149 continue;
150 }
151
152 /* Read the string buffer from the process memory */
154 ParamStringU.Buffer,
155 TempStringU.Buffer,
156 ParamStringU.Length,
157 NULL);
158 if (!NT_SUCCESS(Status))
159 {
160 /* We failed, skip this string */
161 DPRINT1("NtReadVirtualMemory(ParamStringU) failed, Status 0x%lx, skipping.\n", Status);
162 RtlFreeHeap(RtlGetProcessHeap(), 0, TempStringU.Buffer);
163 continue;
164 }
165 /* NULL-terminate the string */
166 TempStringU.Buffer[TempStringU.Length / sizeof(WCHAR)] = UNICODE_NULL;
167
168 DPRINT("ParamString = \'%wZ\'\n", &TempStringU);
169
171 {
172 /* Just keep the allocated NULL-terminated UNICODE string */
173 Parameters[nParam] = (ULONG_PTR)TempStringU.Buffer;
174 Size += TempStringU.Length;
175 }
176 else
177 {
178 /* Allocate a buffer for conversion to ANSI string */
179 TempStringA.MaximumLength = (USHORT)RtlUnicodeStringToAnsiSize(&TempStringU);
180 TempStringA.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
182 TempStringA.MaximumLength);
183 if (!TempStringA.Buffer)
184 {
185 /* We failed, skip this string */
186 DPRINT1("Cannot allocate memory with size %u, skipping.\n", TempStringA.MaximumLength);
187 RtlFreeHeap(RtlGetProcessHeap(), 0, TempStringU.Buffer);
188 continue;
189 }
190
191 /* Convert string to ANSI and free temporary buffer */
192 Status = RtlUnicodeStringToAnsiString(&TempStringA, &TempStringU, FALSE);
193 RtlFreeHeap(RtlGetProcessHeap(), 0, TempStringU.Buffer);
194 if (!NT_SUCCESS(Status))
195 {
196 /* We failed, skip this string */
197 DPRINT1("RtlUnicodeStringToAnsiString() failed, Status 0x%lx, skipping.\n", Status);
198 RtlFreeHeap(RtlGetProcessHeap(), 0, TempStringA.Buffer);
199 continue;
200 }
201
202 /* Note: RtlUnicodeStringToAnsiString() returns a NULL-terminated string */
203 Parameters[nParam] = (ULONG_PTR)TempStringA.Buffer;
204 Size += TempStringU.Length;
205 }
206 }
207 else
208 {
209 /* It's not a unicode string, just copy the parameter */
210 Parameters[nParam] = Message->Parameters[nParam];
211 }
212 }
213
214 if (SizeOfAllUnicodeStrings)
215 *SizeOfAllUnicodeStrings = Size;
216}
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
#define FALSE
Definition: types.h:117
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
static const WCHAR Message[]
Definition: register.c:74
#define ULONG_PTR
Definition: config.h:101
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:71
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
#define UNICODE_NULL
NTSTATUS NTAPI NtReadVirtualMemory(IN HANDLE ProcessHandle, IN PVOID BaseAddress, OUT PVOID Buffer, IN SIZE_T NumberOfBytesToRead, OUT PSIZE_T NumberOfBytesRead OPTIONAL)
Definition: virtual.c:2816
#define STATUS_SERVICE_NOTIFICATION
Definition: ntstatus.h:138
#define DPRINT
Definition: sndvol32.h:71
USHORT MaximumLength
Definition: env_spec_w32.h:377
USHORT MaximumLength
Definition: env_spec_w32.h:370
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:869
#define RtlUnicodeStringToAnsiSize(String)
Definition: rtlfuncs.h:1005

Referenced by UserpFormatMessages().

◆ UserpDuplicateParamStringToUnicodeString()

static VOID UserpDuplicateParamStringToUnicodeString ( IN OUT PUNICODE_STRING  UnicodeString,
IN PCWSTR  ParamString 
)
static

Definition at line 331 of file harderror.c.

334{
335 UNICODE_STRING FormatU, TempStringU;
336
337 /* Calculate buffer length for the text message */
339 if (UnicodeString->MaximumLength < FormatU.MaximumLength)
340 {
341 /* Duplicate the text message in a larger buffer */
343 &FormatU, &TempStringU)))
344 {
345 *UnicodeString = TempStringU;
346 }
347 else
348 {
349 /* We could not allocate a larger buffer; continue using the smaller original buffer */
350 DPRINT1("Cannot allocate memory for UnicodeString, use original buffer.\n");
351
352 /* Copy the truncated string, NULL-terminate it */
353 FormatU.MaximumLength = UnicodeString->MaximumLength;
354 FormatU.Length = FormatU.MaximumLength - sizeof(UNICODE_NULL);
356 }
357 }
358 else
359 {
360 /* Copy the string, NULL-terminate it */
362 }
363}
#define RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
Definition: green.h:15
NTSYSAPI NTSTATUS WINAPI RtlDuplicateUnicodeString(int, const UNICODE_STRING *, UNICODE_STRING *)
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
@ ParamString
Definition: rassapi.h:56
uint16_t * PWSTR
Definition: typedefs.h:56

Referenced by UserpFormatMessages().

◆ UserpFormatMessages()

static VOID UserpFormatMessages ( IN OUT PUNICODE_STRING  TextStringU,
IN OUT PUNICODE_STRING  CaptionStringU,
OUT PUINT  pdwType,
OUT PULONG  pdwTimeout,
IN PHARDERROR_MSG  Message 
)
static

Definition at line 367 of file harderror.c.

373{
374 /* Special hardcoded messages */
375 static const PCWSTR pszUnknownHardError =
376 L"Unknown Hard Error 0x%08lx\n"
377 L"Parameters: 0x%p 0x%p 0x%p 0x%p";
378 static const PCWSTR pszExceptionHardError =
379 L"Exception processing message 0x%08lx\n"
380 L"Parameters: 0x%p 0x%p 0x%p 0x%p";
381
385 ULONG Severity = (ULONG)(Message->Status) >> 30;
386 ULONG SizeOfStrings;
389 UNICODE_STRING WindowTitleU, FileNameU, TempStringU, FormatU, Format2U;
390 ANSI_STRING FormatA, Format2A;
391 HWND hwndOwner;
392 PMESSAGE_RESOURCE_ENTRY MessageResource;
393 PWSTR FormatString, pszBuffer;
394 size_t cszBuffer;
395
396 /* Open client process */
401 &Message->h.ClientId);
402 if (!NT_SUCCESS(Status))
403 {
404 DPRINT1("NtOpenProcess failed with status 0x%08lx, possibly SYSTEM process.\n", Status);
405 hProcess = NULL;
406 }
407
408 /* Capture all string parameters from the process memory */
410
411 /* Initialize the output strings */
412 TextStringU->Length = 0;
413 TextStringU->Buffer[0] = UNICODE_NULL;
414
415 CaptionStringU->Length = 0;
416 CaptionStringU->Buffer[0] = UNICODE_NULL;
417
418 /*
419 * Check whether it is a service notification, in which case
420 * we format the parameters and take the short route.
421 */
423 {
424 /* Close the process handle */
426
427 /*
428 * Retrieve the message box flags. Note that we filter out
429 * MB_SERVICE_NOTIFICATION to not enter an infinite recursive
430 * loop when we will call MessageBox() later on.
431 */
432 *pdwType = (UINT)Parameters[2] & ~MB_SERVICE_NOTIFICATION;
433
434 /*
435 * Duplicate the UNICODE text message and caption.
436 * If no strings or invalid ones have been provided, keep
437 * the original buffers and reset the string lengths to zero.
438 */
439 if (Message->UnicodeStringParameterMask & 0x1)
441 if (Message->UnicodeStringParameterMask & 0x2)
443
444 /* Set the timeout */
445 if (Message->NumberOfParameters >= 4)
446 *pdwTimeout = (ULONG)Parameters[3];
447 else
448 *pdwTimeout = INFINITE;
449
450 goto Quit;
451 }
452
453 /* Set the message box type */
454 *pdwType = 0;
455 switch (Message->ValidResponseOptions)
456 {
458 *pdwType = MB_ABORTRETRYIGNORE;
459 break;
460 case OptionOk:
461 *pdwType = MB_OK;
462 break;
463 case OptionOkCancel:
464 *pdwType = MB_OKCANCEL;
465 break;
467 *pdwType = MB_RETRYCANCEL;
468 break;
469 case OptionYesNo:
470 *pdwType = MB_YESNO;
471 break;
473 *pdwType = MB_YESNOCANCEL;
474 break;
476 *pdwType = MB_OK;
477 break;
478 case OptionOkNoWait:
479 *pdwType = MB_OK;
480 break;
482 *pdwType = MB_CANCELTRYCONTINUE;
483 break;
484 }
485
486 /* Set the severity icon */
487 // STATUS_SEVERITY_SUCCESS
488 if (Severity == STATUS_SEVERITY_INFORMATIONAL) *pdwType |= MB_ICONINFORMATION;
489 else if (Severity == STATUS_SEVERITY_WARNING) *pdwType |= MB_ICONWARNING;
490 else if (Severity == STATUS_SEVERITY_ERROR) *pdwType |= MB_ICONERROR;
491
492 *pdwType |= MB_SYSTEMMODAL | MB_SETFOREGROUND;
493
494 /* Set the timeout */
495 *pdwTimeout = INFINITE;
496
497 /* Copy the Parameters array locally */
498 RtlCopyMemory(&CopyParameters, Parameters, sizeof(CopyParameters));
499
500 /* Get the file name of the client process */
502 if (hProcess)
504
505 /* Close the process handle but keep its original value to know where stuff came from */
507
508 /*
509 * Fall back to SYSTEM process if the client process handle
510 * was NULL or we failed retrieving a file name.
511 */
512 if (!hProcess || !NT_SUCCESS(Status) || !FileNameU.Buffer)
513 {
514 hProcess = NULL;
515 FileNameU = g_SystemProcessU;
516 }
517
518 /* Retrieve the description of the error code */
519 FormatA.Buffer = NULL;
523 Message->Status,
524 &MessageResource);
525 if (NT_SUCCESS(Status))
526 {
527 if (MessageResource->Flags)
528 {
529 RtlInitUnicodeString(&FormatU, (PWSTR)MessageResource->Text);
530 FormatA.Buffer = NULL;
531 }
532 else
533 {
534 RtlInitAnsiString(&FormatA, (PSTR)MessageResource->Text);
535 /* Status = */ RtlAnsiStringToUnicodeString(&FormatU, &FormatA, TRUE);
536 }
537 ASSERT(FormatU.Buffer);
538 }
539 else
540 {
541 /*
542 * Fall back to unknown hard error format string.
543 * NOTE: The value used here is ReactOS-specific: it allows specifying
544 * the exact hard error status value and the parameters, contrary to
545 * the one on Windows that only says: "Unknown Hard Error".
546 */
547 RtlInitEmptyUnicodeString(&FormatU, NULL, 0);
548 FormatA.Buffer = NULL;
549 }
550
551 FormatString = FormatU.Buffer;
552
553 /* Check whether a caption is specified in the format string */
554 if (FormatString && FormatString[0] == L'{')
555 {
556 /* Set caption start */
557 TempStringU.Buffer = ++FormatString;
558
559 /* Get the caption size and find where the format string really starts */
560 for (TempStringU.Length = 0;
562 ++TempStringU.Length)
563 {
564 ++FormatString;
565 }
566
567 /* Skip '}', '\r', '\n' */
568 FormatString += 3;
569
570 TempStringU.Length *= sizeof(WCHAR);
571 TempStringU.MaximumLength = TempStringU.Length;
572 }
573 else
574 {
575 if (Severity == STATUS_SEVERITY_SUCCESS)
576 TempStringU = g_SuccessU;
577 else if (Severity == STATUS_SEVERITY_INFORMATIONAL)
578 TempStringU = g_InformationU;
579 else if (Severity == STATUS_SEVERITY_WARNING)
580 TempStringU = g_WarningU;
581 else if (Severity == STATUS_SEVERITY_ERROR)
582 TempStringU = g_ErrorU;
583 else
584 ASSERT(FALSE); // Unexpected, since Severity is only <= 3.
585 }
586
587 /* Retrieve the window title of the client, if it has one */
588 RtlInitEmptyUnicodeString(&WindowTitleU, L"", 0);
589 hwndOwner = NULL;
590 EnumThreadWindows(HandleToUlong(Message->h.ClientId.UniqueThread),
591 FindTopLevelWnd, (LPARAM)&hwndOwner);
592 if (hwndOwner)
593 {
594 cszBuffer = GetWindowTextLengthW(hwndOwner);
595 if (cszBuffer != 0)
596 {
597 cszBuffer += 3; // 2 characters for ": " and a NULL terminator.
598 cszBuffer *= sizeof(WCHAR);
599 pszBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
601 cszBuffer);
602 if (pszBuffer)
603 {
604 RtlInitEmptyUnicodeString(&WindowTitleU, pszBuffer, (USHORT)cszBuffer);
605 cszBuffer = GetWindowTextW(hwndOwner,
606 WindowTitleU.Buffer,
607 WindowTitleU.MaximumLength / sizeof(WCHAR));
608 WindowTitleU.Length = (USHORT)(cszBuffer * sizeof(WCHAR));
609 RtlAppendUnicodeToString(&WindowTitleU, L": ");
610 }
611 }
612 }
613
614 /* Calculate buffer length for the caption */
615 cszBuffer = WindowTitleU.Length + FileNameU.Length + TempStringU.Length +
616 3 * sizeof(WCHAR) + sizeof(UNICODE_NULL);
617 if (CaptionStringU->MaximumLength < cszBuffer)
618 {
619 /* Allocate a larger buffer for the caption */
620 pszBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
622 cszBuffer);
623 if (!pszBuffer)
624 {
625 /* We could not allocate a larger buffer; continue using the smaller original buffer */
626 DPRINT1("Cannot allocate memory for CaptionStringU, use original buffer.\n");
627 }
628 else
629 {
630 RtlInitEmptyUnicodeString(CaptionStringU, pszBuffer, (USHORT)cszBuffer);
631 }
632 }
633 CaptionStringU->Length = 0;
634 CaptionStringU->Buffer[0] = UNICODE_NULL;
635
636 /* Build the caption */
637 RtlStringCbPrintfW(CaptionStringU->Buffer,
638 CaptionStringU->MaximumLength,
639 L"%wZ%wZ - %wZ",
640 &WindowTitleU, &FileNameU, &TempStringU);
641 CaptionStringU->Length = (USHORT)(wcslen(CaptionStringU->Buffer) * sizeof(WCHAR));
642
643 /* Free the strings if needed */
644 if (WindowTitleU.Buffer && (WindowTitleU.MaximumLength != 0))
645 RtlFreeUnicodeString(&WindowTitleU);
646 if (hProcess)
647 RtlFreeUnicodeString(&FileNameU);
648
649 Format2A.Buffer = NULL;
650
651 /* If we have an unknown hard error, skip the special cases handling */
652 if (!FormatString)
653 goto BuildMessage;
654
655 /* Check if this is an exception message */
656 if (Message->Status == STATUS_UNHANDLED_EXCEPTION)
657 {
658 ULONG ExceptionCode = CopyParameters[0];
659
660 /* Retrieve the description of the exception code */
665 &MessageResource);
666 if (NT_SUCCESS(Status))
667 {
668 if (MessageResource->Flags)
669 {
670 RtlInitUnicodeString(&Format2U, (PWSTR)MessageResource->Text);
671 Format2A.Buffer = NULL;
672 }
673 else
674 {
675 RtlInitAnsiString(&Format2A, (PSTR)MessageResource->Text);
676 /* Status = */ RtlAnsiStringToUnicodeString(&Format2U, &Format2A, TRUE);
677 }
678 ASSERT(Format2U.Buffer);
679
680 /* Handle special cases */
682 {
683 /* Use a new FormatString */
684 FormatString = Format2U.Buffer;
685 CopyParameters[0] = CopyParameters[1];
686 CopyParameters[1] = CopyParameters[3];
687 if (CopyParameters[2])
688 CopyParameters[2] = (ULONG_PTR)L"written";
689 else
690 CopyParameters[2] = (ULONG_PTR)L"read";
691 }
693 {
694 /* Use a new FormatString */
695 FormatString = Format2U.Buffer;
696 CopyParameters[0] = CopyParameters[1];
697 CopyParameters[1] = CopyParameters[3];
698 }
699 else
700 {
701 /* Keep the existing FormatString */
702 CopyParameters[2] = CopyParameters[1];
703 CopyParameters[1] = CopyParameters[0];
704
705 pszBuffer = Format2U.Buffer;
706 if (!_wcsnicmp(pszBuffer, L"{EXCEPTION}", 11))
707 {
708 /*
709 * This is a named exception. Skip the mark and
710 * retrieve the exception name that follows it.
711 */
712 pszBuffer += 11;
713
714 /* Skip '\r', '\n' */
715 pszBuffer += 2;
716
717 CopyParameters[0] = (ULONG_PTR)pszBuffer;
718 }
719 else
720 {
721 /* Fall back to hardcoded value */
722 CopyParameters[0] = (ULONG_PTR)L"unknown software exception";
723 }
724 }
725 }
726 else
727 {
728 /* Fall back to hardcoded value, and keep the existing FormatString */
729 CopyParameters[2] = CopyParameters[1];
730 CopyParameters[1] = CopyParameters[0];
731 CopyParameters[0] = (ULONG_PTR)L"unknown software exception";
732 }
733 }
734
735BuildMessage:
736 /*
737 * Calculate buffer length for the text message. If FormatString
738 * is NULL this means we have an unknown hard error whose format
739 * string is in FormatU.
740 */
741 cszBuffer = 0;
742 /* Wrap in SEH to protect from invalid string parameters */
744 {
745 if (!FormatString)
746 {
747 /* Fall back to unknown hard error format string, and use the original parameters */
748 cszBuffer = _scwprintf(pszUnknownHardError,
749 Message->Status,
750 Parameters[0], Parameters[1],
751 Parameters[2], Parameters[3]);
752 cszBuffer *= sizeof(WCHAR);
753 }
754 else
755 {
756 cszBuffer = _scwprintf(FormatString,
757 CopyParameters[0], CopyParameters[1],
758 CopyParameters[2], CopyParameters[3]);
759 cszBuffer *= sizeof(WCHAR);
760
761 /* Add a description for the dialog buttons */
762 if (Message->Status == STATUS_UNHANDLED_EXCEPTION)
763 {
764 if (Message->ValidResponseOptions == OptionOk ||
765 Message->ValidResponseOptions == OptionOkCancel)
766 {
767 /* Reserve space for one newline and the OK-terminate-program string */
768 cszBuffer += sizeof(WCHAR) + g_OKTerminateU.Length;
769 }
770 if (Message->ValidResponseOptions == OptionOkCancel)
771 {
772 /* Reserve space for one newline and the CANCEL-debug-program string */
773 cszBuffer += sizeof(WCHAR) + g_CancelDebugU.Length;
774 }
775 }
776 }
777 }
779 {
780 /* An exception occurred, use a default string with the original parameters */
781 cszBuffer = _scwprintf(pszExceptionHardError,
782 Message->Status,
783 Parameters[0], Parameters[1],
784 Parameters[2], Parameters[3]);
785 cszBuffer *= sizeof(WCHAR);
786 }
787 _SEH2_END;
788
789 cszBuffer += SizeOfStrings + sizeof(UNICODE_NULL);
790
791 if (TextStringU->MaximumLength < cszBuffer)
792 {
793 /* Allocate a larger buffer for the text message */
794 pszBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
796 cszBuffer);
797 if (!pszBuffer)
798 {
799 /* We could not allocate a larger buffer; continue using the smaller original buffer */
800 DPRINT1("Cannot allocate memory for TextStringU, use original buffer.\n");
801 }
802 else
803 {
804 RtlInitEmptyUnicodeString(TextStringU, pszBuffer, (USHORT)cszBuffer);
805 }
806 }
807 TextStringU->Length = 0;
808 TextStringU->Buffer[0] = UNICODE_NULL;
809
810 /* Wrap in SEH to protect from invalid string parameters */
812 {
813 /* Print the string into the buffer */
814 pszBuffer = TextStringU->Buffer;
815 cszBuffer = TextStringU->MaximumLength;
816
817 if (!FormatString)
818 {
819 /* Fall back to unknown hard error format string, and use the original parameters */
820 RtlStringCbPrintfW(pszBuffer, cszBuffer,
821 pszUnknownHardError,
822 Message->Status,
823 Parameters[0], Parameters[1],
824 Parameters[2], Parameters[3]);
825 }
826 else
827 {
828 RtlStringCbPrintfExW(pszBuffer, cszBuffer,
829 &pszBuffer, &cszBuffer,
830 0,
832 CopyParameters[0], CopyParameters[1],
833 CopyParameters[2], CopyParameters[3]);
834
835 /* Add a description for the dialog buttons */
836 if (Message->Status == STATUS_UNHANDLED_EXCEPTION)
837 {
838 if (Message->ValidResponseOptions == OptionOk ||
839 Message->ValidResponseOptions == OptionOkCancel)
840 {
841 RtlStringCbPrintfExW(pszBuffer, cszBuffer,
842 &pszBuffer, &cszBuffer,
843 0,
844 L"\n%wZ",
846 }
847 if (Message->ValidResponseOptions == OptionOkCancel)
848 {
849 RtlStringCbPrintfExW(pszBuffer, cszBuffer,
850 &pszBuffer, &cszBuffer,
851 0,
852 L"\n%wZ",
854 }
855 }
856 }
857 }
859 {
860 /* An exception occurred, use a default string with the original parameters */
861 DPRINT1("Exception 0x%08lx occurred while building hard-error message, fall back to default message.\n",
863
864 RtlStringCbPrintfW(TextStringU->Buffer,
865 TextStringU->MaximumLength,
866 pszExceptionHardError,
867 Message->Status,
868 Parameters[0], Parameters[1],
869 Parameters[2], Parameters[3]);
870 }
871 _SEH2_END;
872
873 TextStringU->Length = (USHORT)(wcslen(TextStringU->Buffer) * sizeof(WCHAR));
874
875 /* Free the converted UNICODE strings */
876 if (Format2A.Buffer) RtlFreeUnicodeString(&Format2U);
877 if (FormatA.Buffer) RtlFreeUnicodeString(&FormatU);
878
879Quit:
880 /* Free the captured parameters */
882}
#define HandleToUlong(h)
Definition: basetsd.h:79
_Inout_ PIRP _In_ NTSTATUS ExceptionCode
Definition: cdprocs.h:1774
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
#define INFINITE
Definition: serial.h:102
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
#define STATUS_SEVERITY_WARNING
Definition: errmsg.h:58
#define STATUS_SEVERITY_ERROR
Definition: errmsg.h:61
#define STATUS_SEVERITY_INFORMATIONAL
Definition: errmsg.h:60
#define STATUS_SEVERITY_SUCCESS
Definition: errmsg.h:59
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
DWORD FormatString(DWORD dwFlags, HINSTANCE hInstance, DWORD dwStringId, DWORD dwLanguageId, LPWSTR lpBuffer, DWORD nSize, va_list *Arguments)
Definition: fontview.c:34
static VOID UserpCaptureStringParameters(OUT PULONG_PTR Parameters, OUT PULONG SizeOfAllUnicodeStrings, IN PHARDERROR_MSG Message, IN HANDLE hProcess OPTIONAL)
Definition: harderror.c:100
int __cdecl _scwprintf(const wchar_t *format,...)
Definition: harderror.c:71
static NTSTATUS UserpGetClientFileName(OUT PUNICODE_STRING ClientFileNameU, IN HANDLE hProcess)
Definition: harderror.c:240
static VOID UserpDuplicateParamStringToUnicodeString(IN OUT PUNICODE_STRING UnicodeString, IN PCWSTR ParamString)
Definition: harderror.c:331
static VOID UserpFreeStringParameters(IN OUT PULONG_PTR Parameters, IN PHARDERROR_MSG Message)
Definition: harderror.c:220
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define PROCESS_VM_READ
Definition: pstypes.h:161
#define PROCESS_QUERY_INFORMATION
Definition: pstypes.h:166
#define ASSERT(a)
Definition: mode.c:44
#define MAXIMUM_HARDERROR_PARAMETERS
Definition: extypes.h:145
@ OptionYesNoCancel
Definition: extypes.h:191
@ OptionYesNo
Definition: extypes.h:190
@ OptionAbortRetryIgnore
Definition: extypes.h:186
@ OptionCancelTryContinue
Definition: extypes.h:194
@ OptionShutdownSystem
Definition: extypes.h:192
@ OptionOkCancel
Definition: extypes.h:188
@ OptionRetryCancel
Definition: extypes.h:189
@ OptionOk
Definition: extypes.h:187
@ OptionOkNoWait
Definition: extypes.h:193
NTSYSAPI NTSTATUS NTAPI RtlFindMessage(_In_ PVOID BaseAddress, _In_ ULONG Type, _In_ ULONG Language, _In_ ULONG MessageId, _Out_ PMESSAGE_RESOURCE_ENTRY *MessageResourceEntry)
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
NTSTATUS NTAPI NtOpenProcess(OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN PCLIENT_ID ClientId)
Definition: process.c:1440
#define STATUS_UNHANDLED_EXCEPTION
Definition: ntstatus.h:560
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
#define STATUS_IN_PAGE_ERROR
Definition: ntstatus.h:243
NTSTRSAFEVAPI RtlStringCbPrintfExW(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _Outptr_opt_result_bytebuffer_(*pcbRemaining) NTSTRSAFE_PWSTR *ppszDestEnd, _Out_opt_ size_t *pcbRemaining, _In_ STRSAFE_DWORD dwFlags, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1335
NTSTRSAFEVAPI RtlStringCbPrintfW(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1173
#define RT_MESSAGETABLE
Definition: pedump.c:373
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
#define LANG_NEUTRAL
Definition: nls.h:22
#define STATUS_SUCCESS
Definition: shellext.h:65
Definition: rtltypes.h:1896
UCHAR Text[ANYSIZE_ARRAY]
Definition: rtltypes.h:1899
USHORT Flags
Definition: rtltypes.h:1898
char * PSTR
Definition: typedefs.h:51
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define MB_CANCELTRYCONTINUE
Definition: vfdguiut.c:34
int WINAPI GetWindowTextW(HWND hWnd, LPWSTR lpString, int nMaxCount)
Definition: window.c:1412
BOOL CALLBACK FindTopLevelWnd(IN HWND hWnd, IN LPARAM lParam)
Definition: init.c:94
LONG_PTR LPARAM
Definition: windef.h:208
#define MB_SETFOREGROUND
Definition: winuser.h:814
#define MB_SYSTEMMODAL
Definition: winuser.h:815
#define MB_RETRYCANCEL
Definition: winuser.h:805
#define MB_YESNO
Definition: winuser.h:817
#define MB_ICONERROR
Definition: winuser.h:787
#define MB_OKCANCEL
Definition: winuser.h:804
#define MB_ABORTRETRYIGNORE
Definition: winuser.h:791
int WINAPI GetWindowTextLengthW(_In_ HWND)
#define MB_OK
Definition: winuser.h:790
#define MB_ICONWARNING
Definition: winuser.h:786
#define MB_ICONINFORMATION
Definition: winuser.h:802
BOOL WINAPI EnumThreadWindows(_In_ DWORD, _In_ WNDENUMPROC, _In_ LPARAM)
#define MB_YESNOCANCEL
Definition: winuser.h:818

Referenced by UserServerHardError().

◆ UserpFreeStringParameters()

static VOID UserpFreeStringParameters ( IN OUT PULONG_PTR  Parameters,
IN PHARDERROR_MSG  Message 
)
static

Definition at line 220 of file harderror.c.

223{
224 ULONG nParam;
225
226 /* Loop all parameters */
227 for (nParam = 0; nParam < Message->NumberOfParameters; ++nParam)
228 {
229 /* Check if the current parameter is a string */
230 if ((Message->UnicodeStringParameterMask & (1 << nParam)) && (Parameters[nParam] != 0))
231 {
232 /* Free the string buffer */
233 RtlFreeHeap(RtlGetProcessHeap(), 0, (PVOID)Parameters[nParam]);
234 }
235 }
236}

Referenced by UserpFormatMessages().

◆ UserpGetClientFileName()

static NTSTATUS UserpGetClientFileName ( OUT PUNICODE_STRING  ClientFileNameU,
IN HANDLE  hProcess 
)
static

Definition at line 240 of file harderror.c.

243{
247 PPEB_LDR_DATA Ldr;
248 PROCESS_BASIC_INFORMATION ClientBasicInfo;
250 PVOID ClientDllBase;
252 PPEB Peb;
253
254 /* Initialize string */
255 RtlInitEmptyUnicodeString(ClientFileNameU, NULL, 0);
256
257 /* Query process information */
260 &ClientBasicInfo,
261 sizeof(ClientBasicInfo),
262 NULL);
263 if (!NT_SUCCESS(Status)) return Status;
264
265 /* Locate the process loader data table and retrieve its name from it */
266
267 Peb = ClientBasicInfo.PebBaseAddress;
268 if (!Peb) return STATUS_UNSUCCESSFUL;
269
270 Status = NtReadVirtualMemory(hProcess, &Peb->Ldr, &Ldr, sizeof(Ldr), NULL);
271 if (!NT_SUCCESS(Status)) return Status;
272
276 &Entry,
277 sizeof(Entry),
278 NULL);
279 if (!NT_SUCCESS(Status)) return Status;
280
282
283 Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
284
286 Module,
287 &ModuleData,
288 sizeof(ModuleData),
289 NULL);
290 if (!NT_SUCCESS(Status)) return Status;
291
294 &ClientDllBase,
295 sizeof(ClientDllBase),
296 NULL);
297 if (!NT_SUCCESS(Status)) return Status;
298
299 if (ClientDllBase != ModuleData.DllBase) return STATUS_UNSUCCESSFUL;
300
301 ClientFileNameU->MaximumLength = ModuleData.BaseDllName.MaximumLength;
302 ClientFileNameU->Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
304 ClientFileNameU->MaximumLength);
305 if (!ClientFileNameU->Buffer)
306 {
307 RtlInitEmptyUnicodeString(ClientFileNameU, NULL, 0);
308 return STATUS_NO_MEMORY;
309 }
310
312 ModuleData.BaseDllName.Buffer,
313 ClientFileNameU->Buffer,
314 ClientFileNameU->MaximumLength,
315 NULL);
316 if (!NT_SUCCESS(Status))
317 {
318 RtlFreeHeap(RtlGetProcessHeap(), 0, ClientFileNameU->Buffer);
319 RtlInitEmptyUnicodeString(ClientFileNameU, NULL, 0);
320 return Status;
321 }
322
323 ClientFileNameU->Length = (USHORT)(wcslen(ClientFileNameU->Buffer) * sizeof(WCHAR));
324 DPRINT("ClientFileNameU = \'%wZ\'\n", &ClientFileNameU);
325
326 return STATUS_SUCCESS;
327}
PPEB Peb
Definition: dllmain.c:27
@ ProcessBasicInformation
Definition: winternl.h:394
LIST_ENTRY * ModuleListHead
Definition: kdpacket.c:23
NTSTATUS NTAPI NtQueryInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _Out_ PVOID ProcessInformation, _In_ ULONG ProcessInformationLength, _Out_opt_ PULONG ReturnLength)
Definition: query.c:59
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
base of all file and directory entries
Definition: entries.h:83
Definition: btrfs_drv.h:1876
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
LIST_ENTRY InLoadOrderModuleList
Definition: ldrtypes.h:120
PPEB_LDR_DATA Ldr
Definition: btrfs_drv.h:1912
PVOID ImageBaseAddress
Definition: ntddk_ex.h:245
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132

Referenced by UserpFormatMessages().

◆ UserpLogHardError()

static VOID UserpLogHardError ( IN PUNICODE_STRING  TextStringU,
IN PUNICODE_STRING  CaptionStringU 
)
static

Definition at line 1045 of file harderror.c.

1048{
1050 HANDLE hEventLog;
1051 UNICODE_STRING UNCServerNameU = {0, 0, NULL};
1052 UNICODE_STRING SourceNameU = RTL_CONSTANT_STRING(L"Application Popup");
1053 PUNICODE_STRING Strings[] = {CaptionStringU, TextStringU};
1054
1055 Status = ElfRegisterEventSourceW(&UNCServerNameU, &SourceNameU, &hEventLog);
1056 if (!NT_SUCCESS(Status) || !hEventLog)
1057 {
1058 DPRINT1("ElfRegisterEventSourceW failed with Status 0x%08lx\n", Status);
1059 return;
1060 }
1061
1062 Status = ElfReportEventW(hEventLog,
1064 0,
1066 NULL, // lpUserSid
1068 0, // dwDataSize
1069 Strings,
1070 NULL, // lpRawData
1071 0,
1072 NULL,
1073 NULL);
1074 if (!NT_SUCCESS(Status))
1075 DPRINT1("ElfReportEventW failed with Status 0x%08lx\n", Status);
1076
1077 ElfDeregisterEventSource(hEventLog);
1078}
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
NTSTATUS NTAPI ElfDeregisterEventSource(IN HANDLE hEventLog)
Definition: eventlog.c:455
NTSTATUS NTAPI ElfReportEventW(IN HANDLE hEventLog, IN USHORT EventType, IN USHORT EventCategory, IN ULONG EventID, IN PSID UserSID, IN USHORT NumStrings, IN ULONG DataSize, IN PUNICODE_STRING *Strings, IN PVOID Data, IN USHORT Flags, IN OUT PULONG RecordNumber, IN OUT PULONG TimeWritten)
Definition: eventlog.c:1462
NTSTATUS NTAPI ElfRegisterEventSourceW(IN PUNICODE_STRING UNCServerNameU, IN PUNICODE_STRING SourceNameU, OUT PHANDLE phEventLog)
Definition: eventlog.c:1261
static const WCHAR Strings[]
Definition: reg.c:35
#define STATUS_LOG_HARD_ERROR
Definition: ntstatus.h:140
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#define EVENTLOG_INFORMATION_TYPE
Definition: winnt_old.h:2836

Referenced by UserServerHardError().

◆ UserpMessageBox()

static HARDERROR_RESPONSE UserpMessageBox ( IN PUNICODE_STRING  TextStringU,
IN PUNICODE_STRING  CaptionStringU,
IN UINT  Type,
IN ULONG  Timeout 
)
static

Definition at line 1008 of file harderror.c.

1013{
1014 ULONG MessageBoxResponse;
1015
1016 DPRINT("Text = '%S', Caption = '%S', Type = 0x%lx\n",
1017 TextStringU->Buffer, CaptionStringU->Buffer, Type);
1018
1019 /* Display a message box */
1020 MessageBoxResponse = MessageBoxTimeoutW(NULL,
1021 TextStringU->Buffer,
1022 CaptionStringU->Buffer,
1023 Type, 0, Timeout);
1024
1025 /* Return response value */
1026 switch (MessageBoxResponse)
1027 {
1028 case IDOK: return ResponseOk;
1029 case IDCANCEL: return ResponseCancel;
1030 case IDYES: return ResponseYes;
1031 case IDNO: return ResponseNo;
1032 case IDABORT: return ResponseAbort;
1033 case IDIGNORE: return ResponseIgnore;
1034 case IDRETRY: return ResponseRetry;
1035 case IDTRYAGAIN: return ResponseTryAgain;
1036 case IDCONTINUE: return ResponseContinue;
1037 default: return ResponseNotHandled;
1038 }
1039
1040 return ResponseNotHandled;
1041}
Type
Definition: Type.h:7
int WINAPI MessageBoxTimeoutW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType, WORD wLanguageId, DWORD dwTime)
@ ResponseNo
Definition: extypes.h:204
@ ResponseNotHandled
Definition: extypes.h:200
@ ResponseTryAgain
Definition: extypes.h:208
@ ResponseOk
Definition: extypes.h:205
@ ResponseRetry
Definition: extypes.h:206
@ ResponseIgnore
Definition: extypes.h:203
@ ResponseCancel
Definition: extypes.h:202
@ ResponseYes
Definition: extypes.h:207
@ ResponseAbort
Definition: extypes.h:201
@ ResponseContinue
Definition: extypes.h:209
static ULONG Timeout
Definition: ping.c:61
#define IDCONTINUE
Definition: vfdguiut.c:42
#define IDTRYAGAIN
Definition: vfdguiut.c:38
#define IDCANCEL
Definition: winuser.h:831
#define IDOK
Definition: winuser.h:830
#define IDIGNORE
Definition: winuser.h:834
#define IDNO
Definition: winuser.h:836
#define IDABORT
Definition: winuser.h:832
#define IDYES
Definition: winuser.h:835
#define IDRETRY
Definition: winuser.h:833

Referenced by UserServerHardError().

◆ UserpShowInformationBalloon()

static BOOL UserpShowInformationBalloon ( IN PUNICODE_STRING  TextStringU,
IN PUNICODE_STRING  CaptionStringU,
IN UINT  Type,
IN PHARDERROR_MSG  Message 
)
static

Definition at line 933 of file harderror.c.

938{
939 ULONG ShellErrorMode;
940 HWND hWndTaskman;
941 COPYDATASTRUCT CopyData;
943 DWORD dwSize, cbTextLen, cbTitleLen;
944 PWCHAR pText, pCaption;
945 DWORD ret;
946 DWORD_PTR dwResult;
947
948 /* Query the shell error mode value */
949 ShellErrorMode = GetRegInt(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Windows",
950 L"ShellErrorMode", 0);
951
952 /* Make the shell display the hard error message only if necessary */
953 if (ShellErrorMode != 1)
954 return FALSE;
955
956 /* Retrieve the shell task window */
957 hWndTaskman = GetTaskmanWindow();
958 if (!hWndTaskman)
959 {
960 DPRINT1("Failed to find shell task window (last error %lu)\n", GetLastError());
961 return FALSE;
962 }
963
964 cbTextLen = TextStringU->Length + sizeof(UNICODE_NULL);
965 cbTitleLen = CaptionStringU->Length + sizeof(UNICODE_NULL);
966
968 dwSize += cbTextLen + cbTitleLen;
969
970 /* Build the data buffer */
971 pdata = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);
972 if (!pdata)
973 {
974 DPRINT1("Failed to allocate balloon data\n");
975 return FALSE;
976 }
977
978 pdata->cbHeaderSize = sizeof(BALLOON_HARD_ERROR_DATA);
979 pdata->Status = Message->Status;
980 pdata->dwType = Type;
981
982 pdata->TitleOffset = pdata->cbHeaderSize;
983 pdata->MessageOffset = pdata->TitleOffset + cbTitleLen;
984 pCaption = (PWCHAR)((ULONG_PTR)pdata + pdata->TitleOffset);
985 pText = (PWCHAR)((ULONG_PTR)pdata + pdata->MessageOffset);
986 RtlStringCbCopyNW(pCaption, cbTitleLen, CaptionStringU->Buffer, CaptionStringU->Length);
987 RtlStringCbCopyNW(pText, cbTextLen, TextStringU->Buffer, TextStringU->Length);
988
989 /* Send the message */
990
991 /* Retrieve a unique system-wide message to communicate hard error data with the shell */
992 CopyData.dwData = RegisterWindowMessageW(L"HardError");
993 CopyData.cbData = dwSize;
994 CopyData.lpData = pdata;
995
996 dwResult = FALSE;
997 ret = SendMessageTimeoutW(hWndTaskman, WM_COPYDATA, 0, (LPARAM)&CopyData,
998 SMTO_NORMAL | SMTO_ABORTIFHUNG, 3000, &dwResult);
999
1000 /* Free the buffer */
1001 RtlFreeHeap(RtlGetProcessHeap(), 0, pdata);
1002
1003 return (ret && dwResult) ? TRUE : FALSE;
1004}
unsigned long DWORD
Definition: ntddk_ex.h:95
static ULONG GetRegInt(IN PCWSTR KeyName, IN PCWSTR ValueName, IN ULONG DefaultValue)
Definition: harderror.c:885
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
static PROTOCOLDATA * pdata
Definition: protocol.c:158
NTSTRSAFEAPI RtlStringCbCopyNW(_Out_writes_bytes_(cbDest) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_reads_bytes_(cbToCopy) STRSAFE_LPCWSTR pszSrc, _In_ size_t cbToCopy)
Definition: ntstrsafe.h:416
ULONG_PTR dwData
Definition: winuser.h:3001
LPCSTR pText
Definition: txtscale.cpp:79
uint32_t DWORD_PTR
Definition: typedefs.h:65
uint16_t * PWCHAR
Definition: typedefs.h:56
HWND WINAPI GetTaskmanWindow(VOID)
Definition: window.c:1935
struct _BALLOON_HARD_ERROR_DATA BALLOON_HARD_ERROR_DATA
int ret
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
LRESULT WINAPI SendMessageTimeoutW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM, _In_ UINT, _In_ UINT, _Out_opt_ PDWORD_PTR)
#define WM_COPYDATA
Definition: winuser.h:1664
UINT WINAPI RegisterWindowMessageW(_In_ LPCWSTR)
#define SMTO_ABORTIFHUNG
Definition: winuser.h:1223
#define SMTO_NORMAL
Definition: winuser.h:1225

Referenced by UserServerHardError().

◆ UserServerHardError()

VOID NTAPI UserServerHardError ( IN PCSR_THREAD  ThreadData,
IN PHARDERROR_MSG  Message 
)

Definition at line 1082 of file harderror.c.

1085{
1086 ULONG ErrorMode;
1087 UINT dwType = 0;
1089 UNICODE_STRING TextU, CaptionU;
1090 WCHAR LocalTextBuffer[256];
1091 WCHAR LocalCaptionBuffer[256];
1093
1094 ASSERT(ThreadData->Process != NULL);
1095
1096 /* Default to not handled */
1097 Message->Response = ResponseNotHandled;
1098
1099 /* Make sure we don't have too many parameters */
1100 if (Message->NumberOfParameters > MAXIMUM_HARDERROR_PARAMETERS)
1101 {
1102 // NOTE: Windows just fails (STATUS_INVALID_PARAMETER) & returns ResponseNotHandled.
1103 DPRINT1("Invalid NumberOfParameters = %d\n", Message->NumberOfParameters);
1104 Message->NumberOfParameters = MAXIMUM_HARDERROR_PARAMETERS;
1105 }
1106 if (Message->ValidResponseOptions > OptionCancelTryContinue)
1107 {
1108 DPRINT1("Unknown ValidResponseOptions = %d\n", Message->ValidResponseOptions);
1109 return; // STATUS_INVALID_PARAMETER;
1110 }
1111 if (Message->Status == STATUS_SERVICE_NOTIFICATION)
1112 {
1113 if (Message->NumberOfParameters < 3)
1114 {
1115 DPRINT1("Invalid NumberOfParameters = %d for STATUS_SERVICE_NOTIFICATION\n",
1116 Message->NumberOfParameters);
1117 return; // STATUS_INVALID_PARAMETER;
1118 }
1119 // (Message->UnicodeStringParameterMask & 0x3)
1120 }
1121
1124 NULL,
1125 0);
1126 if (!NT_SUCCESS(Status))
1127 {
1128 DPRINT1("Failed to set thread desktop!\n");
1129 return;
1130 }
1131
1132 /* Re-initialize the hard errors cache */
1134
1135 /* Format the message caption and text */
1136 RtlInitEmptyUnicodeString(&TextU, LocalTextBuffer, sizeof(LocalTextBuffer));
1137 RtlInitEmptyUnicodeString(&CaptionU, LocalCaptionBuffer, sizeof(LocalCaptionBuffer));
1138 UserpFormatMessages(&TextU, &CaptionU, &dwType, &Timeout, Message);
1139
1140 /* Log the hard error message */
1141 UserpLogHardError(&TextU, &CaptionU);
1142
1143 /* Display a hard error popup depending on the current ErrorMode */
1144
1145 /* Query the error mode value */
1146 ErrorMode = GetRegInt(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Windows",
1147 L"ErrorMode", 0);
1148
1149 if (Message->Status != STATUS_SERVICE_NOTIFICATION && ErrorMode != 0)
1150 {
1151 /* Returns OK for the hard error */
1152 Message->Response = ResponseOk;
1153 goto Quit;
1154 }
1155
1156 if (Message->ValidResponseOptions == OptionOkNoWait)
1157 {
1158 /* Display the balloon */
1159 Message->Response = ResponseOk;
1160 if (UserpShowInformationBalloon(&TextU,
1161 &CaptionU,
1162 dwType,
1163 Message))
1164 {
1165 Message->Response = ResponseOk;
1166 goto Quit;
1167 }
1168 }
1169
1170 /* Display the message box */
1171 Message->Response = UserpMessageBox(&TextU,
1172 &CaptionU,
1173 dwType,
1174 Timeout);
1175
1176Quit:
1177 /* Free the strings if they have been reallocated */
1178 if (TextU.Buffer != LocalTextBuffer)
1179 RtlFreeUnicodeString(&TextU);
1180 if (CaptionU.Buffer != LocalCaptionBuffer)
1181 RtlFreeUnicodeString(&CaptionU);
1182
1184
1185 return;
1186}
static BOOL UserpShowInformationBalloon(IN PUNICODE_STRING TextStringU, IN PUNICODE_STRING CaptionStringU, IN UINT Type, IN PHARDERROR_MSG Message)
Definition: harderror.c:933
static VOID UserpFormatMessages(IN OUT PUNICODE_STRING TextStringU, IN OUT PUNICODE_STRING CaptionStringU, OUT PUINT pdwType, OUT PULONG pdwTimeout, IN PHARDERROR_MSG Message)
Definition: harderror.c:367
static HARDERROR_RESPONSE UserpMessageBox(IN PUNICODE_STRING TextStringU, IN PUNICODE_STRING CaptionStringU, IN UINT Type, IN ULONG Timeout)
Definition: harderror.c:1008
static VOID UserpLogHardError(IN PUNICODE_STRING TextStringU, IN PUNICODE_STRING CaptionStringU)
Definition: harderror.c:1045
VOID UserInitHardErrorsCache(VOID)
Definition: harderror.c:1189
NTSTATUS NTAPI NtUserSetInformationThread(IN HANDLE ThreadHandle, IN USERTHREADINFOCLASS ThreadInformationClass, IN PVOID ThreadInformation, IN ULONG ThreadInformationLength)
Definition: ntstubs.c:673
@ UserThreadRestoreDesktop
Definition: ntuser.h:77
@ UserThreadUseActiveDesktop
Definition: ntuser.h:75
#define NtCurrentThread()

Referenced by CSR_SERVER_DLL_INIT().

Variable Documentation

◆ g_CancelDebugU

UNICODE_STRING g_CancelDebugU = {0, 0, NULL}

Definition at line 37 of file harderror.c.

Referenced by UserInitHardErrorsCache(), and UserpFormatMessages().

◆ g_CurrentUserLangId

LANGID g_CurrentUserLangId = 0

Definition at line 30 of file harderror.c.

Referenced by UserInitHardErrorsCache().

◆ g_ErrorU

UNICODE_STRING g_ErrorU = {0, 0, NULL}

Definition at line 34 of file harderror.c.

Referenced by UserInitHardErrorsCache(), and UserpFormatMessages().

◆ g_InformationU

UNICODE_STRING g_InformationU = {0, 0, NULL}

Definition at line 32 of file harderror.c.

Referenced by UserInitHardErrorsCache(), and UserpFormatMessages().

◆ g_OKTerminateU

UNICODE_STRING g_OKTerminateU = {0, 0, NULL}

Definition at line 36 of file harderror.c.

Referenced by UserInitHardErrorsCache(), and UserpFormatMessages().

◆ g_SuccessU

UNICODE_STRING g_SuccessU = {0, 0, NULL}

Definition at line 31 of file harderror.c.

Referenced by UserInitHardErrorsCache(), and UserpFormatMessages().

◆ g_SystemProcessU

UNICODE_STRING g_SystemProcessU = {0, 0, NULL}

Definition at line 35 of file harderror.c.

Referenced by UserInitHardErrorsCache(), and UserpFormatMessages().

◆ g_WarningU

UNICODE_STRING g_WarningU = {0, 0, NULL}

Definition at line 33 of file harderror.c.

Referenced by UserInitHardErrorsCache(), and UserpFormatMessages().