2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Console Server DLL
4 * FILE: win32ss/user/consrv/init.c
5 * PURPOSE: Initialization
6 * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
9 /* INCLUDES *******************************************************************/
19 /* GLOBALS ********************************************************************/
21 HINSTANCE ConSrvDllInstance
= NULL
;
24 HANDLE ConSrvHeap
= NULL
; // Our own heap.
26 // Windows Server 2003 table from http://j00ru.vexillium.org/csrss_list/api_list.html#Windows_2k3
27 // plus a little bit of Windows 7.
28 PCSR_API_ROUTINE ConsoleServerApiDispatchTable
[ConsolepMaxApiNumber
- CONSRV_FIRST_API_NUMBER
] =
34 SrvWriteConsoleOutput
,
35 SrvReadConsoleOutputString
,
36 SrvWriteConsoleOutputString
,
39 // SrvGetConsoleNumberOfFonts,
40 SrvGetConsoleNumberOfInputEvents
,
41 SrvGetConsoleScreenBufferInfo
,
42 SrvGetConsoleCursorInfo
,
43 // SrvGetConsoleMouseInfo,
44 // SrvGetConsoleFontInfo,
45 // SrvGetConsoleFontSize,
46 // SrvGetConsoleCurrentFont,
48 SrvSetConsoleActiveScreenBuffer
,
49 SrvFlushConsoleInputBuffer
,
50 SrvGetLargestConsoleWindowSize
,
51 SrvSetConsoleScreenBufferSize
,
52 SrvSetConsoleCursorPosition
,
53 SrvSetConsoleCursorInfo
,
54 SrvSetConsoleWindowInfo
,
55 SrvScrollConsoleScreenBuffer
,
56 SrvSetConsoleTextAttribute
,
62 // SrvGetHandleInformation,
63 // SrvSetHandleInformation,
65 SrvVerifyConsoleIoHandle
,
70 SrvCreateConsoleScreenBuffer
,
71 // SrvInvalidateBitMapRect,
72 // SrvVDMConsoleOperation,
73 // SrvSetConsoleCursor,
74 // SrvShowConsoleCursor,
75 // SrvConsoleMenuControl,
76 // SrvSetConsolePalette,
77 SrvSetConsoleDisplayMode
,
78 // SrvRegisterConsoleVDM,
79 SrvGetConsoleHardwareState
,
80 SrvSetConsoleHardwareState
,
81 SrvGetConsoleDisplayMode
,
84 SrvGetConsoleAliasesLength
,
85 SrvGetConsoleAliasExesLength
,
87 SrvGetConsoleAliasExes
,
88 SrvExpungeConsoleCommandHistory
,
89 SrvSetConsoleNumberOfCommands
,
90 SrvGetConsoleCommandHistoryLength
,
91 SrvGetConsoleCommandHistory
,
92 // SrvSetConsoleCommandHistoryMode,
95 // SrvSetConsoleKeyShortcuts,
96 // SrvSetConsoleMenuClose,
97 // SrvConsoleNotifyLastClose,
98 SrvGenerateConsoleCtrlEvent
,
99 // SrvGetConsoleKeyboardLayoutName,
101 // SrvGetConsoleCharType,
102 // SrvSetConsoleLocalEUDC,
103 // SrvSetConsoleCursorMode,
104 // SrvGetConsoleCursorMode,
105 // SrvRegisterConsoleOS2,
106 // SrvSetConsoleOS2OemFormat,
107 // SrvGetConsoleNlsMode,
108 // SrvSetConsoleNlsMode,
109 // SrvRegisterConsoleIME,
110 // SrvUnregisterConsoleIME,
111 // SrvGetConsoleLangId,
113 SrvGetConsoleSelectionInfo
,
114 SrvGetConsoleProcessList
,
115 SrvGetConsoleHistory
,
116 SrvSetConsoleHistory
,
119 BOOLEAN ConsoleServerApiServerValidTable
[ConsolepMaxApiNumber
- CONSRV_FIRST_API_NUMBER
] =
121 FALSE
, // SrvOpenConsole,
122 FALSE
, // SrvGetConsoleInput,
123 FALSE
, // SrvWriteConsoleInput,
124 FALSE
, // SrvReadConsoleOutput,
125 FALSE
, // SrvWriteConsoleOutput,
126 FALSE
, // SrvReadConsoleOutputString,
127 FALSE
, // SrvWriteConsoleOutputString,
128 FALSE
, // SrvFillConsoleOutput,
129 FALSE
, // SrvGetConsoleMode,
130 // FALSE, // SrvGetConsoleNumberOfFonts,
131 FALSE
, // SrvGetConsoleNumberOfInputEvents,
132 FALSE
, // SrvGetConsoleScreenBufferInfo,
133 FALSE
, // SrvGetConsoleCursorInfo,
134 // FALSE, // SrvGetConsoleMouseInfo,
135 // FALSE, // SrvGetConsoleFontInfo,
136 // FALSE, // SrvGetConsoleFontSize,
137 // FALSE, // SrvGetConsoleCurrentFont,
138 FALSE
, // SrvSetConsoleMode,
139 FALSE
, // SrvSetConsoleActiveScreenBuffer,
140 FALSE
, // SrvFlushConsoleInputBuffer,
141 FALSE
, // SrvGetLargestConsoleWindowSize,
142 FALSE
, // SrvSetConsoleScreenBufferSize,
143 FALSE
, // SrvSetConsoleCursorPosition,
144 FALSE
, // SrvSetConsoleCursorInfo,
145 FALSE
, // SrvSetConsoleWindowInfo,
146 FALSE
, // SrvScrollConsoleScreenBuffer,
147 FALSE
, // SrvSetConsoleTextAttribute,
148 // FALSE, // SrvSetConsoleFont,
149 FALSE
, // SrvSetConsoleIcon,
150 FALSE
, // SrvReadConsole,
151 FALSE
, // SrvWriteConsole,
152 FALSE
, // SrvDuplicateHandle,
153 // FALSE, // SrvGetHandleInformation,
154 // FALSE, // SrvSetHandleInformation,
155 FALSE
, // SrvCloseHandle,
156 FALSE
, // SrvVerifyConsoleIoHandle,
157 FALSE
, // SrvAllocConsole,
158 FALSE
, // SrvFreeConsole,
159 FALSE
, // SrvGetConsoleTitle,
160 FALSE
, // SrvSetConsoleTitle,
161 FALSE
, // SrvCreateConsoleScreenBuffer,
162 // FALSE, // SrvInvalidateBitMapRect,
163 // FALSE, // SrvVDMConsoleOperation,
164 // FALSE, // SrvSetConsoleCursor,
165 // FALSE, // SrvShowConsoleCursor,
166 // FALSE, // SrvConsoleMenuControl,
167 // FALSE, // SrvSetConsolePalette,
168 FALSE
, // SrvSetConsoleDisplayMode,
169 // FALSE, // SrvRegisterConsoleVDM,
170 FALSE
, // SrvGetConsoleHardwareState,
171 FALSE
, // SrvSetConsoleHardwareState,
172 TRUE
, // SrvGetConsoleDisplayMode,
173 FALSE
, // SrvAddConsoleAlias,
174 FALSE
, // SrvGetConsoleAlias,
175 FALSE
, // SrvGetConsoleAliasesLength,
176 FALSE
, // SrvGetConsoleAliasExesLength,
177 FALSE
, // SrvGetConsoleAliases,
178 FALSE
, // SrvGetConsoleAliasExes,
179 FALSE
, // SrvExpungeConsoleCommandHistory,
180 FALSE
, // SrvSetConsoleNumberOfCommands,
181 FALSE
, // SrvGetConsoleCommandHistoryLength,
182 FALSE
, // SrvGetConsoleCommandHistory,
183 // FALSE, // SrvSetConsoleCommandHistoryMode,
184 FALSE
, // SrvGetConsoleCP,
185 FALSE
, // SrvSetConsoleCP,
186 // FALSE, // SrvSetConsoleKeyShortcuts,
187 // FALSE, // SrvSetConsoleMenuClose,
188 // FALSE, // SrvConsoleNotifyLastClose,
189 FALSE
, // SrvGenerateConsoleCtrlEvent,
190 // FALSE, // SrvGetConsoleKeyboardLayoutName,
191 FALSE
, // SrvGetConsoleWindow,
192 // FALSE, // SrvGetConsoleCharType,
193 // FALSE, // SrvSetConsoleLocalEUDC,
194 // FALSE, // SrvSetConsoleCursorMode,
195 // FALSE, // SrvGetConsoleCursorMode,
196 // FALSE, // SrvRegisterConsoleOS2,
197 // FALSE, // SrvSetConsoleOS2OemFormat,
198 // FALSE, // SrvGetConsoleNlsMode,
199 // FALSE, // SrvSetConsoleNlsMode,
200 // FALSE, // SrvRegisterConsoleIME,
201 // FALSE, // SrvUnregisterConsoleIME,
202 // FALSE, // SrvGetConsoleLangId,
203 FALSE
, // SrvAttachConsole,
204 FALSE
, // SrvGetConsoleSelectionInfo,
205 FALSE
, // SrvGetConsoleProcessList,
206 FALSE
, // SrvGetConsoleHistory,
207 FALSE
, // SrvSetConsoleHistory
210 PCHAR ConsoleServerApiNameTable
[ConsolepMaxApiNumber
- CONSRV_FIRST_API_NUMBER
] =
216 "WriteConsoleOutput",
217 "ReadConsoleOutputString",
218 "WriteConsoleOutputString",
221 // "GetConsoleNumberOfFonts",
222 "GetConsoleNumberOfInputEvents",
223 "GetConsoleScreenBufferInfo",
224 "GetConsoleCursorInfo",
225 // "GetConsoleMouseInfo",
226 // "GetConsoleFontInfo",
227 // "GetConsoleFontSize",
228 // "GetConsoleCurrentFont",
230 "SetConsoleActiveScreenBuffer",
231 "FlushConsoleInputBuffer",
232 "GetLargestConsoleWindowSize",
233 "SetConsoleScreenBufferSize",
234 "SetConsoleCursorPosition",
235 "SetConsoleCursorInfo",
236 "SetConsoleWindowInfo",
237 "ScrollConsoleScreenBuffer",
238 "SetConsoleTextAttribute",
244 // "GetHandleInformation",
245 // "SetHandleInformation",
247 "VerifyConsoleIoHandle",
252 "CreateConsoleScreenBuffer",
253 // "InvalidateBitMapRect",
254 // "VDMConsoleOperation",
255 // "SetConsoleCursor",
256 // "ShowConsoleCursor",
257 // "ConsoleMenuControl",
258 // "SetConsolePalette",
259 "SetConsoleDisplayMode",
260 // "RegisterConsoleVDM",
261 "GetConsoleHardwareState",
262 "SetConsoleHardwareState",
263 "GetConsoleDisplayMode",
266 "GetConsoleAliasesLength",
267 "GetConsoleAliasExesLength",
269 "GetConsoleAliasExes",
270 "ExpungeConsoleCommandHistory",
271 "SetConsoleNumberOfCommands",
272 "GetConsoleCommandHistoryLength",
273 "GetConsoleCommandHistory",
274 // "SetConsoleCommandHistoryMode",
277 // "SetConsoleKeyShortcuts",
278 // "SetConsoleMenuClose",
279 // "ConsoleNotifyLastClose",
280 "GenerateConsoleCtrlEvent",
281 // "GetConsoleKeyboardLayoutName",
283 // "GetConsoleCharType",
284 // "SetConsoleLocalEUDC",
285 // "SetConsoleCursorMode",
286 // "GetConsoleCursorMode",
287 // "RegisterConsoleOS2",
288 // "SetConsoleOS2OemFormat",
289 // "GetConsoleNlsMode",
290 // "SetConsoleNlsMode",
291 // "RegisterConsoleIME",
292 // "UnregisterConsoleIME",
293 // "GetConsoleLangId",
295 "GetConsoleSelectionInfo",
296 "GetConsoleProcessList",
302 /* FUNCTIONS ******************************************************************/
305 ConSrvInheritHandlesTable(IN PCONSOLE_PROCESS_DATA SourceProcessData
,
306 IN PCONSOLE_PROCESS_DATA TargetProcessData
);
310 ConSrvNewProcess(PCSR_PROCESS SourceProcess
,
311 PCSR_PROCESS TargetProcess
)
313 /**************************************************************************
314 * This function is called whenever a new process (GUI or CUI) is created.
316 * Copy the parent's handles table here if both the parent and the child
317 * processes are CUI. If we must actually create our proper console (and
318 * thus do not inherit from the console handles of the parent's), then we
319 * will clean this table in the next ConSrvConnect call. Why we are doing
320 * this? It's because here, we still don't know whether or not we must create
321 * a new console instead of inherit it from the parent, and, because in
322 * ConSrvConnect we don't have any reference to the parent process anymore.
323 **************************************************************************/
325 PCONSOLE_PROCESS_DATA SourceProcessData
, TargetProcessData
;
327 /* An empty target process is invalid */
328 if (!TargetProcess
) return STATUS_INVALID_PARAMETER
;
330 TargetProcessData
= ConsoleGetPerProcessData(TargetProcess
);
332 /**** HACK !!!! ****/ RtlZeroMemory(TargetProcessData
, sizeof(*TargetProcessData
));
334 /* Initialize the new (target) process */
335 TargetProcessData
->Process
= TargetProcess
;
336 TargetProcessData
->ConsoleEvent
= NULL
;
337 TargetProcessData
->Console
= TargetProcessData
->ParentConsole
= NULL
;
338 TargetProcessData
->ConsoleApp
= ((TargetProcess
->Flags
& CsrProcessIsConsoleApp
) ? TRUE
: FALSE
);
341 TargetProcessData
->HandleTableSize
= 0;
342 TargetProcessData
->HandleTable
= NULL
;
344 RtlInitializeCriticalSection(&TargetProcessData
->HandleTableLock
);
346 /* Do nothing if the source process is NULL */
347 if (!SourceProcess
) return STATUS_SUCCESS
;
349 SourceProcessData
= ConsoleGetPerProcessData(SourceProcess
);
352 * If both of the processes (parent and new child) are console applications,
353 * then try to inherit handles from the parent process.
355 if ( SourceProcessData
->Console
!= NULL
&& /* SourceProcessData->ConsoleApp */
356 TargetProcessData
->ConsoleApp
)
360 Status
= ConSrvInheritHandlesTable(SourceProcessData
, TargetProcessData
);
361 if (!NT_SUCCESS(Status
)) return Status
;
363 /* Temporary save the parent's console */
364 TargetProcessData
->ParentConsole
= SourceProcessData
->Console
;
367 return STATUS_SUCCESS
;
372 ConSrvConnect(IN PCSR_PROCESS CsrProcess
,
373 IN OUT PVOID ConnectionInfo
,
374 IN OUT PULONG ConnectionInfoLength
)
376 /**************************************************************************
377 * This function is called whenever a CUI new process is created.
378 **************************************************************************/
380 NTSTATUS Status
= STATUS_SUCCESS
;
381 PCONSOLE_CONNECTION_INFO ConnectInfo
= (PCONSOLE_CONNECTION_INFO
)ConnectionInfo
;
382 PCONSOLE_PROCESS_DATA ProcessData
= ConsoleGetPerProcessData(CsrProcess
);
384 if ( ConnectionInfo
== NULL
||
385 ConnectionInfoLength
== NULL
||
386 *ConnectionInfoLength
!= sizeof(CONSOLE_CONNECTION_INFO
) )
388 DPRINT1("CONSRV: Connection failed\n");
389 return STATUS_UNSUCCESSFUL
;
392 /* If we don't need a console, then get out of here */
393 if (!ConnectInfo
->ConsoleNeeded
|| !ProcessData
->ConsoleApp
) // In fact, it is for GUI apps.
395 return STATUS_SUCCESS
;
398 /* If we don't have a console, then create a new one... */
399 if (!ConnectInfo
->Console
||
400 ConnectInfo
->Console
!= ProcessData
->ParentConsole
)
402 DPRINT("ConSrvConnect - Allocate a new console\n");
405 * We are about to create a new console. However when ConSrvNewProcess
406 * was called, we didn't know that we wanted to create a new console and
407 * therefore, we by default inherited the handles table from our parent
408 * process. It's only now that we notice that in fact we do not need
409 * them, because we've created a new console and thus we must use it.
411 * Therefore, free the console we can have and our handles table,
412 * and recreate a new one later on.
414 ConSrvRemoveConsole(ProcessData
);
416 /* Initialize a new Console owned by the Console Leader Process */
417 Status
= ConSrvAllocateConsole(ProcessData
,
418 &ConnectInfo
->InputHandle
,
419 &ConnectInfo
->OutputHandle
,
420 &ConnectInfo
->ErrorHandle
,
421 &ConnectInfo
->ConsoleStartInfo
);
422 if (!NT_SUCCESS(Status
))
424 DPRINT1("Console allocation failed\n");
428 else /* We inherit it from the parent */
430 DPRINT("ConSrvConnect - Reuse current (parent's) console\n");
432 /* Reuse our current console */
433 Status
= ConSrvInheritConsole(ProcessData
,
434 ConnectInfo
->Console
,
436 NULL
, // &ConnectInfo->InputHandle,
437 NULL
, // &ConnectInfo->OutputHandle,
438 NULL
); // &ConnectInfo->ErrorHandle);
439 if (!NT_SUCCESS(Status
))
441 DPRINT1("Console inheritance failed\n");
446 /* Return it to the caller */
447 ConnectInfo
->Console
= ProcessData
->Console
;
449 /* Input Wait Handle */
450 ConnectInfo
->InputWaitHandle
= ProcessData
->ConsoleEvent
;
452 /* Set the Property Dialog Handler */
453 ProcessData
->PropDispatcher
= ConnectInfo
->PropDispatcher
;
455 /* Set the Ctrl Dispatcher */
456 ProcessData
->CtrlDispatcher
= ConnectInfo
->CtrlDispatcher
;
458 return STATUS_SUCCESS
;
463 ConSrvDisconnect(PCSR_PROCESS Process
)
465 PCONSOLE_PROCESS_DATA ProcessData
= ConsoleGetPerProcessData(Process
);
467 /**************************************************************************
468 * This function is called whenever a new process (GUI or CUI) is destroyed.
469 **************************************************************************/
471 if ( ProcessData
->Console
!= NULL
||
472 ProcessData
->HandleTable
!= NULL
)
474 DPRINT("ConSrvDisconnect - calling ConSrvRemoveConsole\n");
475 ConSrvRemoveConsole(ProcessData
);
478 RtlDeleteCriticalSection(&ProcessData
->HandleTableLock
);
481 CSR_SERVER_DLL_INIT(ConServerDllInitialization
)
483 /* Initialize the memory */
484 ConSrvHeap
= RtlGetProcessHeap();
486 ConSrvInitConsoleSupport();
488 /* Setup the DLL Object */
489 LoadedServerDll
->ApiBase
= CONSRV_FIRST_API_NUMBER
;
490 LoadedServerDll
->HighestApiSupported
= ConsolepMaxApiNumber
;
491 LoadedServerDll
->DispatchTable
= ConsoleServerApiDispatchTable
;
492 LoadedServerDll
->ValidTable
= ConsoleServerApiServerValidTable
;
493 LoadedServerDll
->NameTable
= ConsoleServerApiNameTable
;
494 LoadedServerDll
->SizeOfProcessData
= sizeof(CONSOLE_PROCESS_DATA
);
495 LoadedServerDll
->ConnectCallback
= ConSrvConnect
;
496 LoadedServerDll
->DisconnectCallback
= ConSrvDisconnect
;
497 LoadedServerDll
->NewProcessCallback
= ConSrvNewProcess
;
498 // LoadedServerDll->HardErrorCallback = ConSrvHardError;
499 LoadedServerDll
->ShutdownProcessCallback
= NULL
;
501 ConSrvDllInstance
= LoadedServerDll
->ServerHandle
;
504 return STATUS_SUCCESS
;
509 DllMain(IN HINSTANCE hInstanceDll
,
511 IN LPVOID lpReserved
)
513 UNREFERENCED_PARAMETER(hInstanceDll
);
514 UNREFERENCED_PARAMETER(dwReason
);
515 UNREFERENCED_PARAMETER(lpReserved
);