- Implement GenerateConsoleCtrlEvent.
[reactos.git] / reactos / subsystems / win32 / csrss / win32csr / dllmain.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: subsys/csrss/win32csr/dllmain.c
5 * PURPOSE: Initialization
6 * PROGRAMMERS: Dmitry Philippov (shedon@mail.ru)
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include "w32csr.h"
12
13 #define NDEBUG
14 #include <debug.h>
15
16 /* Not defined in any header file */
17 extern VOID STDCALL PrivateCsrssManualGuiCheck(LONG Check);
18 extern VOID STDCALL PrivateCsrssInitialized();
19
20 /* GLOBALS *******************************************************************/
21
22 HANDLE Win32CsrApiHeap;
23 HINSTANCE Win32CsrDllHandle = NULL;
24 static CSRSS_EXPORTED_FUNCS CsrExports;
25
26 static CSRSS_API_DEFINITION Win32CsrApiDefinitions[] =
27 {
28 CSRSS_DEFINE_API(WRITE_CONSOLE, CsrWriteConsole),
29 CSRSS_DEFINE_API(READ_CONSOLE, CsrReadConsole),
30 CSRSS_DEFINE_API(ALLOC_CONSOLE, CsrAllocConsole),
31 CSRSS_DEFINE_API(FREE_CONSOLE, CsrFreeConsole),
32 CSRSS_DEFINE_API(SCREEN_BUFFER_INFO, CsrGetScreenBufferInfo),
33 CSRSS_DEFINE_API(SET_CURSOR, CsrSetCursor),
34 CSRSS_DEFINE_API(FILL_OUTPUT, CsrFillOutputChar),
35 CSRSS_DEFINE_API(READ_INPUT, CsrReadInputEvent),
36 CSRSS_DEFINE_API(WRITE_CONSOLE_OUTPUT_CHAR, CsrWriteConsoleOutputChar),
37 CSRSS_DEFINE_API(WRITE_CONSOLE_OUTPUT_ATTRIB, CsrWriteConsoleOutputAttrib),
38 CSRSS_DEFINE_API(FILL_OUTPUT_ATTRIB, CsrFillOutputAttrib),
39 CSRSS_DEFINE_API(GET_CURSOR_INFO, CsrGetCursorInfo),
40 CSRSS_DEFINE_API(SET_CURSOR_INFO, CsrSetCursorInfo),
41 CSRSS_DEFINE_API(SET_ATTRIB, CsrSetTextAttrib),
42 CSRSS_DEFINE_API(GET_CONSOLE_MODE, CsrGetConsoleMode),
43 CSRSS_DEFINE_API(SET_CONSOLE_MODE, CsrSetConsoleMode),
44 CSRSS_DEFINE_API(CREATE_SCREEN_BUFFER, CsrCreateScreenBuffer),
45 CSRSS_DEFINE_API(SET_SCREEN_BUFFER, CsrSetScreenBuffer),
46 CSRSS_DEFINE_API(SET_TITLE, CsrSetTitle),
47 CSRSS_DEFINE_API(GET_TITLE, CsrGetTitle),
48 CSRSS_DEFINE_API(WRITE_CONSOLE_OUTPUT, CsrWriteConsoleOutput),
49 CSRSS_DEFINE_API(FLUSH_INPUT_BUFFER, CsrFlushInputBuffer),
50 CSRSS_DEFINE_API(SCROLL_CONSOLE_SCREEN_BUFFER, CsrScrollConsoleScreenBuffer),
51 CSRSS_DEFINE_API(READ_CONSOLE_OUTPUT_CHAR, CsrReadConsoleOutputChar),
52 CSRSS_DEFINE_API(READ_CONSOLE_OUTPUT_ATTRIB, CsrReadConsoleOutputAttrib),
53 CSRSS_DEFINE_API(GET_NUM_INPUT_EVENTS, CsrGetNumberOfConsoleInputEvents),
54 CSRSS_DEFINE_API(EXIT_REACTOS, CsrExitReactos),
55 CSRSS_DEFINE_API(PEEK_CONSOLE_INPUT, CsrPeekConsoleInput),
56 CSRSS_DEFINE_API(READ_CONSOLE_OUTPUT, CsrReadConsoleOutput),
57 CSRSS_DEFINE_API(WRITE_CONSOLE_INPUT, CsrWriteConsoleInput),
58 CSRSS_DEFINE_API(SETGET_CONSOLE_HW_STATE, CsrHardwareStateProperty),
59 CSRSS_DEFINE_API(GET_CONSOLE_WINDOW, CsrGetConsoleWindow),
60 CSRSS_DEFINE_API(CREATE_DESKTOP, CsrCreateDesktop),
61 CSRSS_DEFINE_API(SHOW_DESKTOP, CsrShowDesktop),
62 CSRSS_DEFINE_API(HIDE_DESKTOP, CsrHideDesktop),
63 CSRSS_DEFINE_API(SET_CONSOLE_ICON, CsrSetConsoleIcon),
64 CSRSS_DEFINE_API(SET_LOGON_NOTIFY_WINDOW, CsrSetLogonNotifyWindow),
65 CSRSS_DEFINE_API(REGISTER_LOGON_PROCESS, CsrRegisterLogonProcess),
66 CSRSS_DEFINE_API(GET_CONSOLE_CP, CsrGetConsoleCodePage),
67 CSRSS_DEFINE_API(SET_CONSOLE_CP, CsrSetConsoleCodePage),
68 CSRSS_DEFINE_API(GET_CONSOLE_OUTPUT_CP, CsrGetConsoleOutputCodePage),
69 CSRSS_DEFINE_API(SET_CONSOLE_OUTPUT_CP, CsrSetConsoleOutputCodePage),
70 CSRSS_DEFINE_API(GET_PROCESS_LIST, CsrGetProcessList),
71 CSRSS_DEFINE_API(ADD_CONSOLE_ALIAS, CsrAddConsoleAlias),
72 CSRSS_DEFINE_API(GET_CONSOLE_ALIAS, CsrGetConsoleAlias),
73 CSRSS_DEFINE_API(GET_ALL_CONSOLE_ALIASES, CsrGetAllConsoleAliases),
74 CSRSS_DEFINE_API(GET_ALL_CONSOLE_ALIASES_LENGTH, CsrGetAllConsoleAliasesLength),
75 CSRSS_DEFINE_API(GET_CONSOLE_ALIASES_EXES, CsrGetConsoleAliasesExes),
76 CSRSS_DEFINE_API(GET_CONSOLE_ALIASES_EXES_LENGTH, CsrGetConsoleAliasesExesLength),
77 CSRSS_DEFINE_API(GENERATE_CTRL_EVENT, CsrGenerateCtrlEvent),
78 { 0, 0, NULL }
79 };
80
81 static CSRSS_OBJECT_DEFINITION Win32CsrObjectDefinitions[] =
82 {
83 { CONIO_CONSOLE_MAGIC, ConioDeleteConsole },
84 { CONIO_SCREEN_BUFFER_MAGIC, ConioDeleteScreenBuffer },
85 { 0, NULL }
86 };
87
88 /* FUNCTIONS *****************************************************************/
89
90 BOOL STDCALL
91 DllMain(HANDLE hDll,
92 DWORD dwReason,
93 LPVOID lpReserved)
94 {
95 if (DLL_PROCESS_ATTACH == dwReason)
96 {
97 Win32CsrDllHandle = hDll;
98 }
99
100 return TRUE;
101 }
102
103 NTSTATUS FASTCALL
104 Win32CsrInsertObject(PCSRSS_PROCESS_DATA ProcessData,
105 PHANDLE Handle,
106 Object_t *Object,
107 DWORD Access,
108 BOOL Inheritable)
109 {
110 return (CsrExports.CsrInsertObjectProc)(ProcessData, Handle, Object, Access, Inheritable);
111 }
112
113 NTSTATUS FASTCALL
114 Win32CsrGetObject(PCSRSS_PROCESS_DATA ProcessData,
115 HANDLE Handle,
116 Object_t **Object,
117 DWORD Access)
118 {
119 return (CsrExports.CsrGetObjectProc)(ProcessData, Handle, Object, Access);
120 }
121
122 NTSTATUS FASTCALL
123 Win32CsrLockObject(PCSRSS_PROCESS_DATA ProcessData,
124 HANDLE Handle,
125 Object_t **Object,
126 DWORD Access,
127 LONG Type)
128 {
129 NTSTATUS Status;
130
131 Status = (CsrExports.CsrGetObjectProc)(ProcessData, Handle, Object, Access);
132 if (! NT_SUCCESS(Status))
133 {
134 return Status;
135 }
136
137 if ((*Object)->Type != Type)
138 {
139 (CsrExports.CsrReleaseObjectByPointerProc)(*Object);
140 return STATUS_INVALID_HANDLE;
141 }
142
143 EnterCriticalSection(&((*Object)->Lock));
144
145 return STATUS_SUCCESS;
146 }
147
148 VOID FASTCALL
149 Win32CsrUnlockObject(Object_t *Object)
150 {
151 LeaveCriticalSection(&(Object->Lock));
152 (CsrExports.CsrReleaseObjectByPointerProc)(Object);
153 }
154
155 NTSTATUS FASTCALL
156 Win32CsrReleaseObjectByPointer(Object_t *Object)
157 {
158 return (CsrExports.CsrReleaseObjectByPointerProc)(Object);
159 }
160
161 NTSTATUS FASTCALL
162 Win32CsrReleaseObject(PCSRSS_PROCESS_DATA ProcessData,
163 HANDLE Object)
164 {
165 return (CsrExports.CsrReleaseObjectProc)(ProcessData, Object);
166 }
167
168 NTSTATUS FASTCALL
169 Win32CsrEnumProcesses(CSRSS_ENUM_PROCESS_PROC EnumProc,
170 PVOID Context)
171 {
172 return (CsrExports.CsrEnumProcessesProc)(EnumProc, Context);
173 }
174
175 static BOOL STDCALL
176 Win32CsrInitComplete(void)
177 {
178 PrivateCsrssInitialized();
179
180 return TRUE;
181 }
182
183 static BOOL STDCALL
184 Win32CsrHardError(IN PCSRSS_PROCESS_DATA ProcessData,
185 IN PHARDERROR_MSG HardErrorMessage)
186 {
187 UINT responce = MB_OK;
188 NTSTATUS Status;
189 HANDLE hProcess;
190 OBJECT_ATTRIBUTES ObjectAttributes;
191 ULONG nParam = 0;
192 PRTL_MESSAGE_RESOURCE_ENTRY MessageResource;
193 ULONG ParameterList[MAXIMUM_HARDERROR_PARAMETERS];
194 LPSTR CaptionText, MessageBody;
195 LPWSTR szxCaptionText, szxMessageBody;
196 DWORD SizeOfAllUnicodeStrings = 0;
197 PROCESS_BASIC_INFORMATION ClientBasicInfo;
198 UNICODE_STRING ClientFileNameU;
199 UNICODE_STRING TempStringU;
200 UNICODE_STRING ParameterStringU;
201 ANSI_STRING ParamStringA;
202 ULONG UnicodeStringParameterMask = HardErrorMessage->UnicodeStringParameterMask;
203 int MessageBoxResponse;
204
205 HardErrorMessage->Response = ResponseNotHandled;
206
207 DPRINT("NumberOfParameters = %d\n", HardErrorMessage->NumberOfParameters);
208 DPRINT("Status = %lx\n", HardErrorMessage->Status);
209
210 // open client process
211 InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
212 Status = NtOpenProcess(&hProcess, PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, &ObjectAttributes, &HardErrorMessage->h.ClientId);
213 if( !NT_SUCCESS(Status) ) {
214 DPRINT1("NtOpenProcess failed with code: %lx\n", Status);
215 return FALSE;
216 }
217
218 // let's get a name of the client process to display it in the caption of a message box
219
220 ClientFileNameU.MaximumLength = 0;
221 ClientFileNameU.Length = 0;
222 ClientFileNameU.Buffer = NULL;
223 Status = NtQueryInformationProcess(hProcess,
224 ProcessBasicInformation,
225 &ClientBasicInfo,
226 sizeof(ClientBasicInfo),
227 NULL);
228 if( NT_SUCCESS(Status) ) {
229 PLIST_ENTRY ModuleListHead;
230 PLIST_ENTRY Entry;
231 PLDR_DATA_TABLE_ENTRY Module;
232 PPEB_LDR_DATA Ldr;
233 PPEB Peb = ClientBasicInfo.PebBaseAddress;
234
235 if( Peb )
236 {
237 Status = NtReadVirtualMemory(hProcess, &Peb->Ldr, &Ldr, sizeof(Ldr), NULL);
238 if( NT_SUCCESS(Status) ) {
239 ModuleListHead = &Ldr->InLoadOrderModuleList;
240 Status = NtReadVirtualMemory(
241 hProcess,
242 &ModuleListHead->Flink,
243 &Entry,
244 sizeof(Entry),
245 NULL
246 );
247
248 if( NT_SUCCESS(Status) )
249 {
250 if (Entry != ModuleListHead)
251 {
252 LDR_DATA_TABLE_ENTRY ModuleData;
253 Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
254
255 Status = NtReadVirtualMemory(hProcess, Module, &ModuleData, sizeof(ModuleData), NULL);
256 if( NT_SUCCESS(Status) ) {
257 PVOID ClientDllBase;
258
259 Status = NtReadVirtualMemory(
260 hProcess,
261 &Peb->ImageBaseAddress,
262 &ClientDllBase,
263 sizeof(ClientDllBase),
264 NULL
265 );
266 if( NT_SUCCESS(Status) && (ClientDllBase == ModuleData.DllBase) ) {
267
268 ClientFileNameU.MaximumLength = ModuleData.BaseDllName.MaximumLength;
269 ClientFileNameU.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, ClientFileNameU.MaximumLength);
270 Status = NtReadVirtualMemory(
271 hProcess,
272 ModuleData.BaseDllName.Buffer,
273 ClientFileNameU.Buffer,
274 ClientFileNameU.MaximumLength,
275 NULL
276 );
277 if( NT_SUCCESS(Status) ) {
278 ClientFileNameU.Length = wcslen(ClientFileNameU.Buffer)*sizeof(wchar_t);
279 }
280 else {
281 RtlFreeHeap (RtlGetProcessHeap(), 0, ClientFileNameU.Buffer);
282 ClientFileNameU.Buffer = NULL;
283 }
284
285 DPRINT("ClientFileNameU=\'%wZ\'\n", &ClientFileNameU);
286 }
287 }
288 }
289 }
290 }
291 }
292 }
293
294 // read all unicode strings from client space
295 for(nParam = 0; nParam < HardErrorMessage->NumberOfParameters; nParam++, UnicodeStringParameterMask >>= 1)
296 {
297 if( UnicodeStringParameterMask & 0x01 ) {
298 Status = NtReadVirtualMemory(hProcess,
299 (PVOID)HardErrorMessage->Parameters[nParam],
300 (PVOID)&TempStringU,
301 sizeof(TempStringU),
302 NULL);
303
304 if( NT_SUCCESS(Status) ) {
305 ParameterStringU.Buffer = (PWSTR)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, TempStringU.MaximumLength);
306 if( !ParameterStringU.Buffer ) {
307 DPRINT1("Cannot allocate memory %d\n", TempStringU.MaximumLength);
308 NtClose(hProcess);
309 if( ClientFileNameU.Buffer ) {
310 RtlFreeHeap (RtlGetProcessHeap(), 0, ClientFileNameU.Buffer);
311 }
312 return FALSE;
313 }
314
315 Status = NtReadVirtualMemory(hProcess,
316 (PVOID)TempStringU.Buffer,
317 (PVOID)ParameterStringU.Buffer,
318 TempStringU.MaximumLength,
319 NULL);
320 if( !NT_SUCCESS(Status) ) {
321 DPRINT1("NtReadVirtualMemory failed with code: %lx\n", Status);
322 RtlFreeHeap (RtlGetProcessHeap(), 0, ParameterStringU.Buffer);
323 if( ClientFileNameU.Buffer ) {
324 RtlFreeHeap (RtlGetProcessHeap(), 0, ClientFileNameU.Buffer);
325 }
326 NtClose(hProcess);
327 return FALSE;
328 }
329 ParameterStringU.Length = TempStringU.Length;
330 ParameterStringU.MaximumLength = TempStringU.MaximumLength;
331 DPRINT("ParameterStringU=\'%wZ\'\n", &ParameterStringU);
332 RtlUnicodeStringToAnsiString(&ParamStringA, &ParameterStringU, TRUE);
333 ParameterList[nParam] = (ULONG)ParamStringA.Buffer;
334 SizeOfAllUnicodeStrings += ParamStringA.MaximumLength;
335 }
336 }
337 else {
338 // it's not a unicode string
339 ParameterList[nParam] = HardErrorMessage->Parameters[nParam];
340 }
341 }
342
343 NtClose(hProcess);
344
345 // get text string of the error code
346 Status = RtlFindMessage(
347 (PVOID)GetModuleHandle(TEXT("ntdll")),
348 (ULONG)RT_MESSAGETABLE,
349 LANG_NEUTRAL,
350 HardErrorMessage->Status,
351 &MessageResource );
352 if( !NT_SUCCESS(Status) ) {
353 // WE HAVE TO DISPLAY HERE: "Unknown hard error"
354 if( ClientFileNameU.Buffer ) {
355 szxCaptionText = (LPWSTR)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, ClientFileNameU.MaximumLength+64);
356 wsprintfW(szxCaptionText, L"%s - %hs", ClientFileNameU.Buffer, "Application Error");
357 } else {
358 szxCaptionText = (LPWSTR)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, 64);
359 wsprintfW(szxCaptionText, L"System - Application Error");
360 }
361 MessageBody = (LPSTR)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, 38);
362 wsprintfA(MessageBody, "Unknown hard error");
363 }
364 else {
365 LPSTR NtStatusString;
366 UNICODE_STRING MessageU;
367 ANSI_STRING MessageA;
368 USHORT CaptionSize = 0;
369
370 if( !MessageResource->Flags ) {
371 /* we've got an ansi string */
372 DPRINT("MessageResource->Text=%s\n", (PSTR)MessageResource->Text);
373 RtlInitAnsiString(&MessageA, MessageResource->Text);
374 }
375 else {
376 /* we've got a unicode string */
377 DPRINT("MessageResource->Text=%S\n", (PWSTR)MessageResource->Text);
378 RtlInitUnicodeString(&MessageU, (PWSTR)MessageResource->Text);
379 RtlUnicodeStringToAnsiString(&MessageA, &MessageU, TRUE);
380 }
381
382 // check whether a caption exists
383 if( *MessageA.Buffer == '{' ) {
384 // get size of the caption
385 for( CaptionSize = 0; (CaptionSize < MessageA.Length) && ('}' != MessageA.Buffer[CaptionSize]); CaptionSize++);
386
387 CaptionText = (LPSTR)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, CaptionSize);
388 RtlCopyMemory(CaptionText, MessageA.Buffer+1, CaptionSize-1);
389 CaptionSize += 3; // "}\r\n" - 3
390
391 szxCaptionText = (LPWSTR)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(wchar_t)*CaptionSize+ClientFileNameU.MaximumLength+128);
392 if( ClientFileNameU.Buffer ) {
393 wsprintfW(szxCaptionText, L"%s - %hs", ClientFileNameU.Buffer, CaptionText);
394 } else {
395 wsprintfW(szxCaptionText, L"System - %hs", CaptionText);
396 }
397 RtlFreeHeap (RtlGetProcessHeap(), 0, CaptionText);
398 }
399 else {
400 if( ClientFileNameU.Buffer ) {
401 szxCaptionText = (LPWSTR)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, ClientFileNameU.MaximumLength);
402 wsprintfW(szxCaptionText, L"%s", ClientFileNameU.Buffer);
403 } else {
404 szxCaptionText = (LPWSTR)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, 14); // 14 - "System\0\0"
405 wsprintfW(szxCaptionText, L"System");
406 }
407 }
408 DPRINT("ParameterList[0]=0x%lx\n", ParameterList[0]);
409 if( STATUS_UNHANDLED_EXCEPTION == HardErrorMessage->Status )
410 {
411 PRTL_MESSAGE_RESOURCE_ENTRY MsgResException;
412 MessageBody = NULL;
413 Status = RtlFindMessage(
414 (PVOID)GetModuleHandle(TEXT("ntdll")),
415 (ULONG)RT_MESSAGETABLE,
416 LANG_NEUTRAL,
417 ParameterList[0],
418 &MsgResException);
419
420 if( NT_SUCCESS(Status) )
421 {
422 UNICODE_STRING ExcMessageU;
423 ANSI_STRING ExcMessageA;
424 if( !MsgResException->Flags ) {
425 /* we've got an ansi string */
426 DPRINT("MsgResException->Text=%s\n", (PSTR)MsgResException->Text);
427 RtlInitAnsiString(&ExcMessageA, MsgResException->Text);
428 }
429 else {
430 /* we've got a unicode string */
431 DPRINT("MsgResException->Text=%S\n", (PWSTR)MsgResException->Text);
432 RtlInitUnicodeString(&ExcMessageU, (PWSTR)MsgResException->Text);
433 RtlUnicodeStringToAnsiString(&ExcMessageA, &ExcMessageU, TRUE);
434 }
435
436 MessageBody = (LPSTR)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, MsgResException->Length+SizeOfAllUnicodeStrings+1024); // 1024 is a magic number I think it should be enough
437 if( STATUS_ACCESS_VIOLATION == ParameterList[0] ) {
438 LPSTR pOperationType;
439 if( ParameterList[2] ) pOperationType = "written";
440 else pOperationType = "read";
441 wsprintfA(MessageBody, ExcMessageA.Buffer, ParameterList[1], ParameterList[3], pOperationType);
442 }
443 else if( STATUS_IN_PAGE_ERROR == ParameterList[0] ) {
444 wsprintfA(MessageBody, ExcMessageA.Buffer, ParameterList[1], ParameterList[3], ParameterList[2]);
445 }
446 }
447 if( !MessageBody ) {
448 NtStatusString = (LPSTR)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, MessageResource->Length-CaptionSize);
449 RtlCopyMemory(NtStatusString, MessageA.Buffer+CaptionSize, (MessageResource->Length-CaptionSize)-1);
450
451 MessageBody = (LPSTR)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, MessageResource->Length+SizeOfAllUnicodeStrings+1024); // 1024 is a magic number I think it should be enough
452
453 wsprintfA(MessageBody, NtStatusString,
454 L"Unknown software exception",
455 ParameterList[0],
456 ParameterList[1]);
457
458 RtlFreeHeap (RtlGetProcessHeap(), 0, NtStatusString);
459 }
460 }
461 else
462 {
463 NtStatusString = (LPSTR)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, MessageResource->Length-CaptionSize);
464 RtlCopyMemory(NtStatusString, MessageA.Buffer+CaptionSize, (MessageResource->Length-CaptionSize)-1);
465
466 MessageBody = (LPSTR)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, MessageResource->Length+SizeOfAllUnicodeStrings+1024); // 1024 is a magic number I think it should be enough
467
468 wsprintfA(MessageBody, NtStatusString,
469 ParameterList[0],
470 ParameterList[1],
471 ParameterList[2],
472 ParameterList[3]);
473
474 RtlFreeHeap (RtlGetProcessHeap(), 0, NtStatusString);
475 }
476 if( MessageResource->Flags ) {
477 /* we've got a unicode string */
478 RtlFreeAnsiString(&MessageA);
479 }
480 }
481 if( ClientFileNameU.Buffer ) {
482 RtlFreeHeap (RtlGetProcessHeap(), 0, ClientFileNameU.Buffer);
483 }
484
485 szxMessageBody = (LPWSTR)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(wchar_t)*(strlen(MessageBody)+1));
486 wsprintfW(szxMessageBody, L"%hs", MessageBody);
487 RtlFreeHeap (RtlGetProcessHeap(), 0, MessageBody);
488
489 switch ( HardErrorMessage->ValidResponseOptions )
490 {
491 case OptionAbortRetryIgnore:
492 responce = MB_ABORTRETRYIGNORE;
493 break;
494
495 case OptionOk:
496 responce = MB_OK;
497 break;
498
499 case OptionOkCancel:
500 responce = MB_OKCANCEL;
501 break;
502
503 case OptionRetryCancel:
504 responce = MB_RETRYCANCEL;
505 break;
506
507 case OptionYesNo:
508 responce = MB_YESNO;
509 break;
510
511 case OptionYesNoCancel:
512 responce = MB_YESNOCANCEL;
513 break;
514
515 case OptionShutdownSystem:
516 // XZ??
517 break;
518
519 default:
520 DPRINT1("Wrong option: ValidResponseOptions = %d\n", HardErrorMessage->ValidResponseOptions);
521 ASSERT(FALSE);
522 break;
523 }
524
525 // FIXME: We should not use MessageBox !!!!
526 DPRINT1("%S\n", szxMessageBody);
527 MessageBoxResponse = MessageBoxW(0, szxMessageBody, szxCaptionText, responce|MB_ICONERROR|MB_SYSTEMMODAL|MB_SETFOREGROUND);
528
529 RtlFreeHeap (RtlGetProcessHeap(), 0, szxMessageBody);
530 RtlFreeHeap (RtlGetProcessHeap(), 0, szxCaptionText);
531
532 switch( MessageBoxResponse )
533 {
534 case IDOK:
535 HardErrorMessage->Response = ResponseOk;
536 break;
537
538 case IDCANCEL:
539 HardErrorMessage->Response = ResponseCancel;
540 break;
541
542 case IDYES:
543 HardErrorMessage->Response = ResponseYes;
544 break;
545
546 case IDNO:
547 HardErrorMessage->Response = ResponseNo;
548 break;
549
550 case IDABORT:
551 HardErrorMessage->Response = ResponseAbort;
552 break;
553
554 case IDIGNORE:
555 HardErrorMessage->Response = ResponseIgnore;
556 break;
557
558 case IDRETRY:
559 HardErrorMessage->Response = ResponseRetry;
560 break;
561
562 case 10://IDTRYAGAIN:
563 HardErrorMessage->Response = ResponseTryAgain;
564 break;
565
566 case 11://IDCONTINUE:
567 HardErrorMessage->Response = ResponseContinue;
568 break;
569
570 default:
571 ASSERT(FALSE);
572 break;
573 }
574
575 return TRUE;
576 }
577
578
579 BOOL STDCALL
580 Win32CsrInitialization(PCSRSS_API_DEFINITION *ApiDefinitions,
581 PCSRSS_OBJECT_DEFINITION *ObjectDefinitions,
582 CSRPLUGIN_INIT_COMPLETE_PROC *InitComplete,
583 CSRPLUGIN_HARDERROR_PROC *HardError,
584 PCSRSS_EXPORTED_FUNCS Exports,
585 HANDLE CsrssApiHeap)
586 {
587 CsrExports = *Exports;
588 Win32CsrApiHeap = CsrssApiHeap;
589
590 PrivateCsrssManualGuiCheck(0);
591 CsrInitConsoleSupport();
592
593 *ApiDefinitions = Win32CsrApiDefinitions;
594 *ObjectDefinitions = Win32CsrObjectDefinitions;
595 *InitComplete = Win32CsrInitComplete;
596 *HardError = Win32CsrHardError;
597
598 return TRUE;
599 }
600
601 /* EOF */