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