xref: /reactos/win32ss/user/winsrv/consrv/init.c (revision c05df38e)
1 /*
2  * COPYRIGHT:       See COPYING in the top level directory
3  * PROJECT:         ReactOS Console Server DLL
4  * FILE:            win32ss/user/winsrv/consrv/init.c
5  * PURPOSE:         Initialization
6  * PROGRAMMERS:     Hermes Belusca-Maito (hermes.belusca@sfr.fr)
7  */
8 
9 /* INCLUDES *******************************************************************/
10 
11 #include "consrv.h"
12 
13 #include "api.h"
14 #include "procinit.h"
15 
16 #define NDEBUG
17 #include <debug.h>
18 
19 /* GLOBALS ********************************************************************/
20 
21 HINSTANCE ConSrvDllInstance = NULL;
22 
23 /* Memory */
24 HANDLE ConSrvHeap = NULL;   // Our own heap.
25 
26 // Windows Server 2003 table from http://j00ru.vexillium.org/csrss_list/api_list.html#Windows_2k3
27 PCSR_API_ROUTINE ConsoleServerApiDispatchTable[ConsolepMaxApiNumber - CONSRV_FIRST_API_NUMBER] =
28 {
29     SrvOpenConsole,
30     SrvGetConsoleInput,
31     SrvWriteConsoleInput,
32     SrvReadConsoleOutput,
33     SrvWriteConsoleOutput,
34     SrvReadConsoleOutputString,
35     SrvWriteConsoleOutputString,
36     SrvFillConsoleOutput,
37     SrvGetConsoleMode,
38     SrvGetConsoleNumberOfFonts,
39     SrvGetConsoleNumberOfInputEvents,
40     SrvGetConsoleScreenBufferInfo,
41     SrvGetConsoleCursorInfo,
42     SrvGetConsoleMouseInfo,
43     SrvGetConsoleFontInfo,
44     SrvGetConsoleFontSize,
45     SrvGetConsoleCurrentFont,
46     SrvSetConsoleMode,
47     SrvSetConsoleActiveScreenBuffer,
48     SrvFlushConsoleInputBuffer,
49     SrvGetLargestConsoleWindowSize,
50     SrvSetConsoleScreenBufferSize,
51     SrvSetConsoleCursorPosition,
52     SrvSetConsoleCursorInfo,
53     SrvSetConsoleWindowInfo,
54     SrvScrollConsoleScreenBuffer,
55     SrvSetConsoleTextAttribute,
56     SrvSetConsoleFont,
57     SrvSetConsoleIcon,
58     SrvReadConsole,
59     SrvWriteConsole,
60     SrvDuplicateHandle,
61     SrvGetHandleInformation,
62     SrvSetHandleInformation,
63     SrvCloseHandle,
64     SrvVerifyConsoleIoHandle,
65     SrvAllocConsole,                        // Not present in Win7
66     SrvFreeConsole,                         // Not present in Win7
67     SrvGetConsoleTitle,
68     SrvSetConsoleTitle,
69     SrvCreateConsoleScreenBuffer,
70     SrvInvalidateBitMapRect,
71     SrvVDMConsoleOperation,
72     SrvSetConsoleCursor,
73     SrvShowConsoleCursor,
74     SrvConsoleMenuControl,
75     SrvSetConsolePalette,
76     SrvSetConsoleDisplayMode,
77     SrvRegisterConsoleVDM,
78     SrvGetConsoleHardwareState,
79     SrvSetConsoleHardwareState,
80     SrvGetConsoleDisplayMode,
81     SrvAddConsoleAlias,
82     SrvGetConsoleAlias,
83     SrvGetConsoleAliasesLength,
84     SrvGetConsoleAliasExesLength,
85     SrvGetConsoleAliases,
86     SrvGetConsoleAliasExes,
87     SrvExpungeConsoleCommandHistory,
88     SrvSetConsoleNumberOfCommands,
89     SrvGetConsoleCommandHistoryLength,
90     SrvGetConsoleCommandHistory,
91     SrvSetConsoleCommandHistoryMode,     // Not present in Vista+
92     SrvGetConsoleCP,
93     SrvSetConsoleCP,
94     SrvSetConsoleKeyShortcuts,
95     SrvSetConsoleMenuClose,
96     SrvConsoleNotifyLastClose,
97     SrvGenerateConsoleCtrlEvent,
98     SrvGetConsoleKeyboardLayoutName,
99     SrvGetConsoleWindow,
100     SrvGetConsoleCharType,
101     SrvSetConsoleLocalEUDC,
102     SrvSetConsoleCursorMode,
103     SrvGetConsoleCursorMode,
104     SrvRegisterConsoleOS2,
105     SrvSetConsoleOS2OemFormat,
106     SrvGetConsoleNlsMode,
107     SrvSetConsoleNlsMode,
108     SrvRegisterConsoleIME,                  // Not present in Win7
109     SrvUnregisterConsoleIME,                // Not present in Win7
110     // SrvQueryConsoleIME,                     // Added only in Vista and Win2k8, not present in Win7
111     SrvGetConsoleLangId,
112     SrvAttachConsole,                       // Not present in Win7
113     SrvGetConsoleSelectionInfo,
114     SrvGetConsoleProcessList,
115 
116     SrvGetConsoleHistory,                   // Added in Vista+
117     SrvSetConsoleHistory,                   // Added in Vista+
118     // SrvSetConsoleCurrentFont,               // Added in Vista+
119     // SrvSetScreenBufferInfo,                 // Added in Vista+
120     // SrvConsoleClientConnect,                // Added in Win7
121 };
122 
123 BOOLEAN ConsoleServerApiServerValidTable[ConsolepMaxApiNumber - CONSRV_FIRST_API_NUMBER] =
124 {
125     FALSE,   // SrvOpenConsole,
126     FALSE,   // SrvGetConsoleInput,
127     FALSE,   // SrvWriteConsoleInput,
128     FALSE,   // SrvReadConsoleOutput,
129     FALSE,   // SrvWriteConsoleOutput,
130     FALSE,   // SrvReadConsoleOutputString,
131     FALSE,   // SrvWriteConsoleOutputString,
132     FALSE,   // SrvFillConsoleOutput,
133     FALSE,   // SrvGetConsoleMode,
134     FALSE,   // SrvGetConsoleNumberOfFonts,
135     FALSE,   // SrvGetConsoleNumberOfInputEvents,
136     FALSE,   // SrvGetConsoleScreenBufferInfo,
137     FALSE,   // SrvGetConsoleCursorInfo,
138     FALSE,   // SrvGetConsoleMouseInfo,
139     FALSE,   // SrvGetConsoleFontInfo,
140     FALSE,   // SrvGetConsoleFontSize,
141     FALSE,   // SrvGetConsoleCurrentFont,
142     FALSE,   // SrvSetConsoleMode,
143     FALSE,   // SrvSetConsoleActiveScreenBuffer,
144     FALSE,   // SrvFlushConsoleInputBuffer,
145     FALSE,   // SrvGetLargestConsoleWindowSize,
146     FALSE,   // SrvSetConsoleScreenBufferSize,
147     FALSE,   // SrvSetConsoleCursorPosition,
148     FALSE,   // SrvSetConsoleCursorInfo,
149     FALSE,   // SrvSetConsoleWindowInfo,
150     FALSE,   // SrvScrollConsoleScreenBuffer,
151     FALSE,   // SrvSetConsoleTextAttribute,
152     FALSE,   // SrvSetConsoleFont,
153     FALSE,   // SrvSetConsoleIcon,
154     FALSE,   // SrvReadConsole,
155     FALSE,   // SrvWriteConsole,
156     FALSE,   // SrvDuplicateHandle,
157     FALSE,   // SrvGetHandleInformation,
158     FALSE,   // SrvSetHandleInformation,
159     FALSE,   // SrvCloseHandle,
160     FALSE,   // SrvVerifyConsoleIoHandle,
161     FALSE,   // SrvAllocConsole,
162     FALSE,   // SrvFreeConsole,
163     FALSE,   // SrvGetConsoleTitle,
164     FALSE,   // SrvSetConsoleTitle,
165     FALSE,   // SrvCreateConsoleScreenBuffer,
166     FALSE,   // SrvInvalidateBitMapRect,
167     FALSE,   // SrvVDMConsoleOperation,
168     FALSE,   // SrvSetConsoleCursor,
169     FALSE,   // SrvShowConsoleCursor,
170     FALSE,   // SrvConsoleMenuControl,
171     FALSE,   // SrvSetConsolePalette,
172     FALSE,   // SrvSetConsoleDisplayMode,
173     FALSE,   // SrvRegisterConsoleVDM,
174     FALSE,   // SrvGetConsoleHardwareState,
175     FALSE,   // SrvSetConsoleHardwareState,
176     TRUE,    // SrvGetConsoleDisplayMode,
177     FALSE,   // SrvAddConsoleAlias,
178     FALSE,   // SrvGetConsoleAlias,
179     FALSE,   // SrvGetConsoleAliasesLength,
180     FALSE,   // SrvGetConsoleAliasExesLength,
181     FALSE,   // SrvGetConsoleAliases,
182     FALSE,   // SrvGetConsoleAliasExes,
183     FALSE,   // SrvExpungeConsoleCommandHistory,
184     FALSE,   // SrvSetConsoleNumberOfCommands,
185     FALSE,   // SrvGetConsoleCommandHistoryLength,
186     FALSE,   // SrvGetConsoleCommandHistory,
187     FALSE,   // SrvSetConsoleCommandHistoryMode,
188     FALSE,   // SrvGetConsoleCP,
189     FALSE,   // SrvSetConsoleCP,
190     FALSE,   // SrvSetConsoleKeyShortcuts,
191     FALSE,   // SrvSetConsoleMenuClose,
192     FALSE,   // SrvConsoleNotifyLastClose,
193     FALSE,   // SrvGenerateConsoleCtrlEvent,
194     FALSE,   // SrvGetConsoleKeyboardLayoutName,
195     FALSE,   // SrvGetConsoleWindow,
196     FALSE,   // SrvGetConsoleCharType,
197     FALSE,   // SrvSetConsoleLocalEUDC,
198     FALSE,   // SrvSetConsoleCursorMode,
199     FALSE,   // SrvGetConsoleCursorMode,
200     FALSE,   // SrvRegisterConsoleOS2,
201     FALSE,   // SrvSetConsoleOS2OemFormat,
202     FALSE,   // SrvGetConsoleNlsMode,
203     FALSE,   // SrvSetConsoleNlsMode,
204     FALSE,   // SrvRegisterConsoleIME,
205     FALSE,   // SrvUnregisterConsoleIME,
206     // FALSE,   // SrvQueryConsoleIME,
207     FALSE,   // SrvGetConsoleLangId,
208     FALSE,   // SrvAttachConsole,
209     FALSE,   // SrvGetConsoleSelectionInfo,
210     FALSE,   // SrvGetConsoleProcessList,
211 
212     FALSE,   // SrvGetConsoleHistory,
213     FALSE,   // SrvSetConsoleHistory
214     // FALSE,   // SrvSetConsoleCurrentFont,
215     // FALSE,   // SrvSetScreenBufferInfo,
216     // FALSE,   // SrvConsoleClientConnect,
217 };
218 
219 /*
220  * On Windows Server 2003, CSR Servers contain
221  * the API Names Table only in Debug Builds.
222  */
223 #ifdef CSR_DBG
224 PCHAR ConsoleServerApiNameTable[ConsolepMaxApiNumber - CONSRV_FIRST_API_NUMBER] =
225 {
226     "OpenConsole",
227     "GetConsoleInput",
228     "WriteConsoleInput",
229     "ReadConsoleOutput",
230     "WriteConsoleOutput",
231     "ReadConsoleOutputString",
232     "WriteConsoleOutputString",
233     "FillConsoleOutput",
234     "GetConsoleMode",
235     "GetConsoleNumberOfFonts",
236     "GetConsoleNumberOfInputEvents",
237     "GetConsoleScreenBufferInfo",
238     "GetConsoleCursorInfo",
239     "GetConsoleMouseInfo",
240     "GetConsoleFontInfo",
241     "GetConsoleFontSize",
242     "GetConsoleCurrentFont",
243     "SetConsoleMode",
244     "SetConsoleActiveScreenBuffer",
245     "FlushConsoleInputBuffer",
246     "GetLargestConsoleWindowSize",
247     "SetConsoleScreenBufferSize",
248     "SetConsoleCursorPosition",
249     "SetConsoleCursorInfo",
250     "SetConsoleWindowInfo",
251     "ScrollConsoleScreenBuffer",
252     "SetConsoleTextAttribute",
253     "SetConsoleFont",
254     "SetConsoleIcon",
255     "ReadConsole",
256     "WriteConsole",
257     "DuplicateHandle",
258     "GetHandleInformation",
259     "SetHandleInformation",
260     "CloseHandle",
261     "VerifyConsoleIoHandle",
262     "AllocConsole",
263     "FreeConsole",
264     "GetConsoleTitle",
265     "SetConsoleTitle",
266     "CreateConsoleScreenBuffer",
267     "InvalidateBitMapRect",
268     "VDMConsoleOperation",
269     "SetConsoleCursor",
270     "ShowConsoleCursor",
271     "ConsoleMenuControl",
272     "SetConsolePalette",
273     "SetConsoleDisplayMode",
274     "RegisterConsoleVDM",
275     "GetConsoleHardwareState",
276     "SetConsoleHardwareState",
277     "GetConsoleDisplayMode",
278     "AddConsoleAlias",
279     "GetConsoleAlias",
280     "GetConsoleAliasesLength",
281     "GetConsoleAliasExesLength",
282     "GetConsoleAliases",
283     "GetConsoleAliasExes",
284     "ExpungeConsoleCommandHistory",
285     "SetConsoleNumberOfCommands",
286     "GetConsoleCommandHistoryLength",
287     "GetConsoleCommandHistory",
288     "SetConsoleCommandHistoryMode",
289     "GetConsoleCP",
290     "SetConsoleCP",
291     "SetConsoleKeyShortcuts",
292     "SetConsoleMenuClose",
293     "ConsoleNotifyLastClose",
294     "GenerateConsoleCtrlEvent",
295     "GetConsoleKeyboardLayoutName",
296     "GetConsoleWindow",
297     "GetConsoleCharType",
298     "SetConsoleLocalEUDC",
299     "SetConsoleCursorMode",
300     "GetConsoleCursorMode",
301     "RegisterConsoleOS2",
302     "SetConsoleOS2OemFormat",
303     "GetConsoleNlsMode",
304     "SetConsoleNlsMode",
305     "RegisterConsoleIME",
306     "UnregisterConsoleIME",
307     // "QueryConsoleIME",
308     "GetConsoleLangId",
309     "AttachConsole",
310     "GetConsoleSelectionInfo",
311     "GetConsoleProcessList",
312 
313     "GetConsoleHistory",
314     "SetConsoleHistory",
315     // "SetConsoleCurrentFont",
316     // "SetScreenBufferInfo",
317     // "ConsoleClientConnect",
318 };
319 #endif
320 
321 /* FUNCTIONS ******************************************************************/
322 
323 NTSTATUS
324 NTAPI
ConSrvNewProcess(PCSR_PROCESS SourceProcess,PCSR_PROCESS TargetProcess)325 ConSrvNewProcess(PCSR_PROCESS SourceProcess,
326                  PCSR_PROCESS TargetProcess)
327 {
328     /**************************************************************************
329      * This function is called whenever a new process (GUI or CUI) is created.
330      *
331      * Copy the parent's handles table here if both the parent and the child
332      * processes are CUI. If we must actually create our proper console (and
333      * thus do not inherit from the console handles of the parent's), then we
334      * will clean this table in the next ConSrvConnect call. Why we are doing
335      * this? It's because here, we still don't know whether or not we must create
336      * a new console instead of inherit it from the parent, and, because in
337      * ConSrvConnect we don't have any reference to the parent process anymore.
338      **************************************************************************/
339 
340     NTSTATUS Status = STATUS_SUCCESS;
341     PCONSOLE_PROCESS_DATA TargetProcessData;
342 
343     /* An empty target process is invalid */
344     if (!TargetProcess) return STATUS_INVALID_PARAMETER;
345 
346     TargetProcessData = ConsoleGetPerProcessData(TargetProcess);
347 
348     /* Initialize the new (target) process */
349     RtlZeroMemory(TargetProcessData, sizeof(*TargetProcessData));
350     TargetProcessData->Process = TargetProcess;
351     TargetProcessData->ConsoleHandle = NULL;
352     TargetProcessData->ConsoleApp = FALSE;
353 
354     /*
355      * The handles table gets initialized either when inheriting from
356      * another console process, or when creating a new console.
357      */
358     TargetProcessData->HandleTableSize = 0;
359     TargetProcessData->HandleTable = NULL;
360 
361     RtlInitializeCriticalSection(&TargetProcessData->HandleTableLock);
362 
363     /* Do nothing if the source process is NULL */
364     if (!SourceProcess) return STATUS_SUCCESS;
365 
366     // SourceProcessData = ConsoleGetPerProcessData(SourceProcess);
367 
368     /*
369      * If the child process is a console application and the parent process is
370      * either a console application or just has a valid console (with a valid
371      * handles table: this can happen if it is a GUI application having called
372      * AllocConsole), then try to inherit handles from the parent process.
373      */
374     if (TargetProcess->Flags & CsrProcessIsConsoleApp /* && SourceProcessData->ConsoleHandle != NULL */)
375     {
376         PCONSOLE_PROCESS_DATA SourceProcessData = ConsoleGetPerProcessData(SourceProcess);
377         PCONSRV_CONSOLE SourceConsole;
378 
379         /* Validate and lock the parent's console */
380         if (ConSrvValidateConsole(&SourceConsole,
381                                   SourceProcessData->ConsoleHandle,
382                                   CONSOLE_RUNNING, TRUE))
383         {
384             /* Inherit the parent's handles table */
385             Status = ConSrvInheritHandlesTable(SourceProcessData, TargetProcessData);
386             if (!NT_SUCCESS(Status))
387             {
388                 DPRINT1("Inheriting handles table failed\n");
389             }
390 
391             /* Unlock the parent's console */
392             LeaveCriticalSection(&SourceConsole->Lock);
393         }
394     }
395 
396     return Status;
397 }
398 
399 NTSTATUS
400 NTAPI
ConSrvConnect(IN PCSR_PROCESS CsrProcess,IN OUT PVOID ConnectionInfo,IN OUT PULONG ConnectionInfoLength)401 ConSrvConnect(IN PCSR_PROCESS CsrProcess,
402               IN OUT PVOID ConnectionInfo,
403               IN OUT PULONG ConnectionInfoLength)
404 {
405     /**************************************************************************
406      * This function is called whenever a CUI new process is created.
407      **************************************************************************/
408 
409     NTSTATUS Status = STATUS_SUCCESS;
410     PCONSRV_API_CONNECTINFO ConnectInfo = (PCONSRV_API_CONNECTINFO)ConnectionInfo;
411     PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrProcess);
412 
413     if ( ConnectionInfo       == NULL ||
414          ConnectionInfoLength == NULL ||
415         *ConnectionInfoLength != sizeof(*ConnectInfo) )
416     {
417         DPRINT1("CONSRV: Connection failed - ConnectionInfo = 0x%p ; ConnectionInfoLength = 0x%p (%lu), expected %lu\n",
418                 ConnectionInfo,
419                 ConnectionInfoLength,
420                 ConnectionInfoLength ? *ConnectionInfoLength : (ULONG)-1,
421                 sizeof(*ConnectInfo));
422 
423         return STATUS_UNSUCCESSFUL;
424     }
425 
426     /* Set Control-Dispatcher handler */
427     ProcessData->CtrlRoutine = ConnectInfo->CtrlRoutine;
428 
429     /* If we don't need a console, then get out of here */
430     DPRINT("ConnectInfo->IsConsoleApp = %s\n", ConnectInfo->IsConsoleApp ? "True" : "False");
431     if (!ConnectInfo->IsConsoleApp) return STATUS_SUCCESS;
432 
433     /* If we don't inherit from an existing console, then create a new one... */
434     if (ConnectInfo->ConsoleStartInfo.ConsoleHandle == NULL)
435     {
436         CONSOLE_INIT_INFO ConsoleInitInfo;
437 
438         DPRINT("ConSrvConnect - Allocate a new console\n");
439 
440         /* Initialize the console initialization info structure */
441         ConsoleInitInfo.ConsoleStartInfo = &ConnectInfo->ConsoleStartInfo;
442         ConsoleInitInfo.IsWindowVisible  = ConnectInfo->IsWindowVisible;
443         ConsoleInitInfo.TitleLength      = ConnectInfo->TitleLength;
444         ConsoleInitInfo.ConsoleTitle     = ConnectInfo->ConsoleTitle;
445         ConsoleInitInfo.DesktopLength    = 0;
446         ConsoleInitInfo.Desktop          = NULL;
447         ConsoleInitInfo.AppNameLength    = ConnectInfo->AppNameLength;
448         ConsoleInitInfo.AppName          = ConnectInfo->AppName;
449         ConsoleInitInfo.CurDirLength     = ConnectInfo->CurDirLength;
450         ConsoleInitInfo.CurDir           = ConnectInfo->CurDir;
451 
452         /*
453          * Contrary to the case of SrvAllocConsole, the desktop string is
454          * allocated in the process' heap, so we need to retrieve it by
455          * using NtReadVirtualMemory.
456          */
457         if (ConnectInfo->DesktopLength)
458         {
459             ConsoleInitInfo.DesktopLength = ConnectInfo->DesktopLength;
460 
461             ConsoleInitInfo.Desktop = ConsoleAllocHeap(HEAP_ZERO_MEMORY,
462                                                        ConsoleInitInfo.DesktopLength);
463             if (ConsoleInitInfo.Desktop == NULL)
464                 return STATUS_NO_MEMORY;
465 
466             Status = NtReadVirtualMemory(ProcessData->Process->ProcessHandle,
467                                          ConnectInfo->Desktop,
468                                          ConsoleInitInfo.Desktop,
469                                          ConsoleInitInfo.DesktopLength,
470                                          NULL);
471             if (!NT_SUCCESS(Status))
472             {
473                 ConsoleFreeHeap(ConsoleInitInfo.Desktop);
474                 return Status;
475             }
476         }
477 
478         /*
479          * We are about to create a new console. However when ConSrvNewProcess
480          * was called, we didn't know that we wanted to create a new console and
481          * therefore, we by default inherited the handles table from our parent
482          * process. It's only now that we notice that in fact we do not need
483          * them, because we've created a new console and thus we must use it.
484          *
485          * ConSrvAllocateConsole will free our old handles table
486          * and recreate a new valid one.
487          */
488 
489         /* Initialize a new Console owned by the Console Leader Process */
490         Status = ConSrvAllocateConsole(ProcessData,
491                                        &ConnectInfo->ConsoleStartInfo.InputHandle,
492                                        &ConnectInfo->ConsoleStartInfo.OutputHandle,
493                                        &ConnectInfo->ConsoleStartInfo.ErrorHandle,
494                                        &ConsoleInitInfo);
495 
496         /* Free our local desktop string if any */
497         if (ConsoleInitInfo.DesktopLength)
498             ConsoleFreeHeap(ConsoleInitInfo.Desktop);
499 
500         /* Check for success */
501         if (!NT_SUCCESS(Status))
502         {
503             DPRINT1("Console allocation failed\n");
504             return Status;
505         }
506     }
507     else /* We inherit it from the parent */
508     {
509         DPRINT("ConSrvConnect - Reuse current (parent's) console\n");
510 
511         /* Reuse our current console */
512         Status = ConSrvInheritConsole(ProcessData,
513                                       ConnectInfo->ConsoleStartInfo.ConsoleHandle,
514                                       FALSE,
515                                       NULL, // &ConnectInfo->ConsoleStartInfo.InputHandle,
516                                       NULL, // &ConnectInfo->ConsoleStartInfo.OutputHandle,
517                                       NULL, // &ConnectInfo->ConsoleStartInfo.ErrorHandle,
518                                       &ConnectInfo->ConsoleStartInfo);
519         if (!NT_SUCCESS(Status))
520         {
521             DPRINT1("Console inheritance failed\n");
522             return Status;
523         }
524     }
525 
526     /* Set the Property-Dialog handler */
527     ProcessData->PropRoutine = ConnectInfo->PropRoutine;
528 
529     return STATUS_SUCCESS;
530 }
531 
532 VOID
533 NTAPI
ConSrvDisconnect(IN PCSR_PROCESS CsrProcess)534 ConSrvDisconnect(IN PCSR_PROCESS CsrProcess)
535 {
536     PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrProcess);
537 
538     /**************************************************************************
539      * This function is called whenever a new process (GUI or CUI) is destroyed.
540      **************************************************************************/
541 
542     if ( ProcessData->ConsoleHandle != NULL ||
543          ProcessData->HandleTable   != NULL )
544     {
545         DPRINT("ConSrvDisconnect - calling ConSrvRemoveConsole\n");
546         ConSrvRemoveConsole(ProcessData);
547     }
548 
549     RtlDeleteCriticalSection(&ProcessData->HandleTableLock);
550 }
551 
CSR_SERVER_DLL_INIT(ConServerDllInitialization)552 CSR_SERVER_DLL_INIT(ConServerDllInitialization)
553 {
554     /* Initialize the memory */
555     ConSrvHeap = RtlGetProcessHeap();
556 /*
557     // We can use our own heap instead of the CSR heap to investigate heap corruptions :)
558     ConSrvHeap = RtlCreateHeap(HEAP_GROWABLE                |
559                                HEAP_PROTECTION_ENABLED      |
560                                HEAP_FREE_CHECKING_ENABLED   |
561                                HEAP_TAIL_CHECKING_ENABLED   |
562                                HEAP_VALIDATE_ALL_ENABLED,
563                                NULL, 0, 0, NULL, NULL);
564     if (!ConSrvHeap) return STATUS_NO_MEMORY;
565 */
566 
567     ConSrvInitConsoleSupport();
568 
569     /* Setup the DLL Object */
570     LoadedServerDll->ApiBase = CONSRV_FIRST_API_NUMBER;
571     LoadedServerDll->HighestApiSupported = ConsolepMaxApiNumber;
572     LoadedServerDll->DispatchTable = ConsoleServerApiDispatchTable;
573     LoadedServerDll->ValidTable = ConsoleServerApiServerValidTable;
574 #ifdef CSR_DBG
575     LoadedServerDll->NameTable = ConsoleServerApiNameTable;
576 #endif
577     LoadedServerDll->SizeOfProcessData = sizeof(CONSOLE_PROCESS_DATA);
578     LoadedServerDll->ConnectCallback = ConSrvConnect;
579     LoadedServerDll->DisconnectCallback = ConSrvDisconnect;
580     LoadedServerDll->NewProcessCallback = ConSrvNewProcess;
581     // LoadedServerDll->HardErrorCallback = ConSrvHardError;
582     LoadedServerDll->ShutdownProcessCallback = ConsoleClientShutdown;
583 
584     ConSrvDllInstance = LoadedServerDll->ServerHandle;
585 
586     /* All done */
587     return STATUS_SUCCESS;
588 }
589 
590 /* EOF */
591