- Rewrite NtUserCreateDesktop and move the desktop thread completely in win32k like...
[reactos.git] / reactos / win32ss / user / 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 #define NDEBUG
11 #include "w32csr.h"
12 #include "file.h"
13 #include <debug.h>
14
15 /* Not defined in any header file */
16 extern VOID WINAPI PrivateCsrssManualGuiCheck(LONG Check);
17 extern LIST_ENTRY DosDeviceHistory;
18 extern RTL_CRITICAL_SECTION Win32CsrDefineDosDeviceCritSec;
19
20 /* GLOBALS *******************************************************************/
21
22 HANDLE Win32CsrApiHeap;
23 HINSTANCE Win32CsrDllHandle = NULL;
24
25 static CSRSS_API_DEFINITION Win32CsrApiDefinitions[] =
26 {
27 CSRSS_DEFINE_API(GET_INPUT_HANDLE, CsrGetHandle),
28 CSRSS_DEFINE_API(GET_OUTPUT_HANDLE, CsrGetHandle),
29 CSRSS_DEFINE_API(CLOSE_HANDLE, CsrCloseHandle),
30 CSRSS_DEFINE_API(VERIFY_HANDLE, CsrVerifyHandle),
31 CSRSS_DEFINE_API(DUPLICATE_HANDLE, CsrDuplicateHandle),
32 CSRSS_DEFINE_API(GET_INPUT_WAIT_HANDLE, CsrGetInputWaitHandle),
33 CSRSS_DEFINE_API(WRITE_CONSOLE, CsrWriteConsole),
34 CSRSS_DEFINE_API(READ_CONSOLE, CsrReadConsole),
35 CSRSS_DEFINE_API(ALLOC_CONSOLE, CsrAllocConsole),
36 CSRSS_DEFINE_API(FREE_CONSOLE, CsrFreeConsole),
37 CSRSS_DEFINE_API(SCREEN_BUFFER_INFO, CsrGetScreenBufferInfo),
38 CSRSS_DEFINE_API(SET_CURSOR, CsrSetCursor),
39 CSRSS_DEFINE_API(FILL_OUTPUT, CsrFillOutputChar),
40 CSRSS_DEFINE_API(READ_INPUT, CsrReadInputEvent),
41 CSRSS_DEFINE_API(WRITE_CONSOLE_OUTPUT_CHAR, CsrWriteConsoleOutputChar),
42 CSRSS_DEFINE_API(WRITE_CONSOLE_OUTPUT_ATTRIB, CsrWriteConsoleOutputAttrib),
43 CSRSS_DEFINE_API(FILL_OUTPUT_ATTRIB, CsrFillOutputAttrib),
44 CSRSS_DEFINE_API(GET_CURSOR_INFO, CsrGetCursorInfo),
45 CSRSS_DEFINE_API(SET_CURSOR_INFO, CsrSetCursorInfo),
46 CSRSS_DEFINE_API(SET_ATTRIB, CsrSetTextAttrib),
47 CSRSS_DEFINE_API(GET_CONSOLE_MODE, CsrGetConsoleMode),
48 CSRSS_DEFINE_API(SET_CONSOLE_MODE, CsrSetConsoleMode),
49 CSRSS_DEFINE_API(CREATE_SCREEN_BUFFER, CsrCreateScreenBuffer),
50 CSRSS_DEFINE_API(SET_SCREEN_BUFFER, CsrSetScreenBuffer),
51 CSRSS_DEFINE_API(SET_TITLE, CsrSetTitle),
52 CSRSS_DEFINE_API(GET_TITLE, CsrGetTitle),
53 CSRSS_DEFINE_API(WRITE_CONSOLE_OUTPUT, CsrWriteConsoleOutput),
54 CSRSS_DEFINE_API(FLUSH_INPUT_BUFFER, CsrFlushInputBuffer),
55 CSRSS_DEFINE_API(SCROLL_CONSOLE_SCREEN_BUFFER, CsrScrollConsoleScreenBuffer),
56 CSRSS_DEFINE_API(READ_CONSOLE_OUTPUT_CHAR, CsrReadConsoleOutputChar),
57 CSRSS_DEFINE_API(READ_CONSOLE_OUTPUT_ATTRIB, CsrReadConsoleOutputAttrib),
58 CSRSS_DEFINE_API(GET_NUM_INPUT_EVENTS, CsrGetNumberOfConsoleInputEvents),
59 CSRSS_DEFINE_API(EXIT_REACTOS, CsrExitReactos),
60 CSRSS_DEFINE_API(PEEK_CONSOLE_INPUT, CsrPeekConsoleInput),
61 CSRSS_DEFINE_API(READ_CONSOLE_OUTPUT, CsrReadConsoleOutput),
62 CSRSS_DEFINE_API(WRITE_CONSOLE_INPUT, CsrWriteConsoleInput),
63 CSRSS_DEFINE_API(SETGET_CONSOLE_HW_STATE, CsrHardwareStateProperty),
64 CSRSS_DEFINE_API(GET_CONSOLE_WINDOW, CsrGetConsoleWindow),
65 CSRSS_DEFINE_API(CREATE_DESKTOP, CsrCreateDesktop),
66 CSRSS_DEFINE_API(SHOW_DESKTOP, CsrShowDesktop),
67 CSRSS_DEFINE_API(HIDE_DESKTOP, CsrHideDesktop),
68 CSRSS_DEFINE_API(SET_CONSOLE_ICON, CsrSetConsoleIcon),
69 CSRSS_DEFINE_API(SET_LOGON_NOTIFY_WINDOW, CsrSetLogonNotifyWindow),
70 CSRSS_DEFINE_API(REGISTER_LOGON_PROCESS, CsrRegisterLogonProcess),
71 CSRSS_DEFINE_API(GET_CONSOLE_CP, CsrGetConsoleCodePage),
72 CSRSS_DEFINE_API(SET_CONSOLE_CP, CsrSetConsoleCodePage),
73 CSRSS_DEFINE_API(GET_CONSOLE_OUTPUT_CP, CsrGetConsoleOutputCodePage),
74 CSRSS_DEFINE_API(SET_CONSOLE_OUTPUT_CP, CsrSetConsoleOutputCodePage),
75 CSRSS_DEFINE_API(GET_PROCESS_LIST, CsrGetProcessList),
76 CSRSS_DEFINE_API(ADD_CONSOLE_ALIAS, CsrAddConsoleAlias),
77 CSRSS_DEFINE_API(GET_CONSOLE_ALIAS, CsrGetConsoleAlias),
78 CSRSS_DEFINE_API(GET_ALL_CONSOLE_ALIASES, CsrGetAllConsoleAliases),
79 CSRSS_DEFINE_API(GET_ALL_CONSOLE_ALIASES_LENGTH, CsrGetAllConsoleAliasesLength),
80 CSRSS_DEFINE_API(GET_CONSOLE_ALIASES_EXES, CsrGetConsoleAliasesExes),
81 CSRSS_DEFINE_API(GET_CONSOLE_ALIASES_EXES_LENGTH, CsrGetConsoleAliasesExesLength),
82 CSRSS_DEFINE_API(GENERATE_CTRL_EVENT, CsrGenerateCtrlEvent),
83 CSRSS_DEFINE_API(SET_SCREEN_BUFFER_SIZE, CsrSetScreenBufferSize),
84 CSRSS_DEFINE_API(GET_CONSOLE_SELECTION_INFO, CsrGetConsoleSelectionInfo),
85 CSRSS_DEFINE_API(GET_COMMAND_HISTORY_LENGTH, CsrGetCommandHistoryLength),
86 CSRSS_DEFINE_API(GET_COMMAND_HISTORY, CsrGetCommandHistory),
87 CSRSS_DEFINE_API(EXPUNGE_COMMAND_HISTORY, CsrExpungeCommandHistory),
88 CSRSS_DEFINE_API(SET_HISTORY_NUMBER_COMMANDS, CsrSetHistoryNumberCommands),
89 CSRSS_DEFINE_API(GET_HISTORY_INFO, CsrGetHistoryInfo),
90 CSRSS_DEFINE_API(SET_HISTORY_INFO, CsrSetHistoryInfo),
91 CSRSS_DEFINE_API(GET_TEMP_FILE, CsrGetTempFile),
92 CSRSS_DEFINE_API(DEFINE_DOS_DEVICE, CsrDefineDosDevice),
93 CSRSS_DEFINE_API(SOUND_SENTRY, CsrSoundSentry),
94 { 0, 0, NULL }
95 };
96
97 static HHOOK hhk = NULL;
98
99 /* FUNCTIONS *****************************************************************/
100
101 LRESULT
102 CALLBACK
103 KeyboardHookProc(
104 int nCode,
105 WPARAM wParam,
106 LPARAM lParam)
107 {
108 return CallNextHookEx(hhk, nCode, wParam, lParam);
109 }
110
111 ULONG
112 InitializeVideoAddressSpace(VOID)
113 {
114 OBJECT_ATTRIBUTES ObjectAttributes;
115 UNICODE_STRING PhysMemName = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory");
116 NTSTATUS Status;
117 HANDLE PhysMemHandle;
118 PVOID BaseAddress;
119 LARGE_INTEGER Offset;
120 SIZE_T ViewSize;
121 CHAR IVTAndBda[1024+256];
122
123 /* Free the 1MB pre-reserved region. In reality, ReactOS should simply support us mapping the view into the reserved area, but it doesn't. */
124 BaseAddress = 0;
125 ViewSize = 1024 * 1024;
126 Status = ZwFreeVirtualMemory(NtCurrentProcess(),
127 &BaseAddress,
128 &ViewSize,
129 MEM_RELEASE);
130 if (!NT_SUCCESS(Status))
131 {
132 DPRINT1("Couldn't unmap reserved memory (%x)\n", Status);
133 return 0;
134 }
135
136 /* Open the physical memory section */
137 InitializeObjectAttributes(&ObjectAttributes,
138 &PhysMemName,
139 0,
140 NULL,
141 NULL);
142 Status = ZwOpenSection(&PhysMemHandle,
143 SECTION_ALL_ACCESS,
144 &ObjectAttributes);
145 if (!NT_SUCCESS(Status))
146 {
147 DPRINT1("Couldn't open \\Device\\PhysicalMemory\n");
148 return 0;
149 }
150
151 /* Map the BIOS and device registers into the address space */
152 Offset.QuadPart = 0xa0000;
153 ViewSize = 0x100000 - 0xa0000;
154 BaseAddress = (PVOID)0xa0000;
155 Status = ZwMapViewOfSection(PhysMemHandle,
156 NtCurrentProcess(),
157 &BaseAddress,
158 0,
159 ViewSize,
160 &Offset,
161 &ViewSize,
162 ViewUnmap,
163 0,
164 PAGE_EXECUTE_READWRITE);
165 if (!NT_SUCCESS(Status))
166 {
167 DPRINT1("Couldn't map physical memory (%x)\n", Status);
168 ZwClose(PhysMemHandle);
169 return 0;
170 }
171
172 /* Close physical memory section handle */
173 ZwClose(PhysMemHandle);
174
175 if (BaseAddress != (PVOID)0xa0000)
176 {
177 DPRINT1("Couldn't map physical memory at the right address (was %x)\n",
178 BaseAddress);
179 return 0;
180 }
181
182 /* Allocate some low memory to use for the non-BIOS
183 * parts of the v86 mode address space
184 */
185 BaseAddress = (PVOID)0x1;
186 ViewSize = 0xa0000 - 0x1000;
187 Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
188 &BaseAddress,
189 0,
190 &ViewSize,
191 MEM_RESERVE | MEM_COMMIT,
192 PAGE_EXECUTE_READWRITE);
193 if (!NT_SUCCESS(Status))
194 {
195 DPRINT1("Failed to allocate virtual memory (Status %x)\n", Status);
196 return 0;
197 }
198 if (BaseAddress != (PVOID)0x0)
199 {
200 DPRINT1("Failed to allocate virtual memory at right address (was %x)\n",
201 BaseAddress);
202 return 0;
203 }
204
205 /* Get the real mode IVT and BDA from the kernel */
206 Status = NtVdmControl(VdmInitialize, IVTAndBda);
207 if (!NT_SUCCESS(Status))
208 {
209 DPRINT1("NtVdmControl failed (status %x)\n", Status);
210 return 0;
211 }
212
213 /* Return success */
214 return 1;
215 }
216
217 /**********************************************************************
218 * CsrpInitVideo/3
219 *
220 * TODO: we need a virtual device for sessions other than
221 * TODO: the console one
222 */
223 NTSTATUS
224 CsrpInitVideo (VOID)
225 {
226 OBJECT_ATTRIBUTES ObjectAttributes;
227 UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\??\\DISPLAY1");
228 IO_STATUS_BLOCK Iosb;
229 HANDLE VideoHandle = (HANDLE) 0;
230 NTSTATUS Status = STATUS_SUCCESS;
231
232 DPRINT("CSR: %s called\n", __FUNCTION__);
233
234 InitializeVideoAddressSpace();
235
236 InitializeObjectAttributes(&ObjectAttributes,
237 &DeviceName,
238 0,
239 NULL,
240 NULL);
241 Status = NtOpenFile(&VideoHandle,
242 FILE_ALL_ACCESS,
243 &ObjectAttributes,
244 &Iosb,
245 0,
246 0);
247 if (NT_SUCCESS(Status))
248 {
249 NtClose(VideoHandle);
250 }
251 return Status;
252 }
253
254 BOOL WINAPI
255 DllMain(HANDLE hDll,
256 DWORD dwReason,
257 LPVOID lpReserved)
258 {
259 if (DLL_PROCESS_ATTACH == dwReason)
260 {
261 Win32CsrDllHandle = hDll;
262 //
263 // HACK HACK HACK ReactOS to BOOT! Initialization BUG ALERT! See bug 5655.
264 //
265 hhk = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProc, NULL, 0);
266 // BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT!
267 // BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT!
268 // BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT!
269 }
270
271 if (DLL_PROCESS_DETACH == dwReason)
272 {
273 CsrCleanupDefineDosDevice();
274 }
275 return TRUE;
276 }
277
278 /* Ensure that a captured buffer is safe to access */
279 BOOL FASTCALL
280 Win32CsrValidateBuffer(PCSR_PROCESS ProcessData, PVOID Buffer,
281 SIZE_T NumElements, SIZE_T ElementSize)
282 {
283 /* Check that the following conditions are true:
284 * 1. The start of the buffer is somewhere within the process's
285 * shared memory section view.
286 * 2. The remaining space in the view is at least as large as the buffer.
287 * (NB: Please don't try to "optimize" this by using multiplication
288 * instead of division; remember that 2147483648 * 2 = 0.)
289 * 3. The buffer is DWORD-aligned.
290 */
291 ULONG_PTR Offset = (BYTE *)Buffer - (BYTE *)ProcessData->ClientViewBase;
292 if (Offset >= ProcessData->ClientViewBounds
293 || NumElements > (ProcessData->ClientViewBounds - Offset) / ElementSize
294 || (Offset & (sizeof(DWORD) - 1)) != 0)
295 {
296 DPRINT1("Invalid buffer %p(%u*%u); section view is %p(%u)\n",
297 Buffer, NumElements, ElementSize,
298 ProcessData->ClientViewBase, ProcessData->ClientViewBounds);
299 return FALSE;
300 }
301 return TRUE;
302 }
303
304 NTSTATUS FASTCALL
305 Win32CsrEnumProcesses(CSRSS_ENUM_PROCESS_PROC EnumProc,
306 PVOID Context)
307 {
308 return CsrEnumProcesses(EnumProc, Context);
309 }
310
311 VOID
312 WINAPI
313 PrivateCsrssManualGuiCheck(LONG Check)
314 {
315 NtUserCallOneParam(Check, ONEPARAM_ROUTINE_CSRSS_GUICHECK);
316 }
317
318 DWORD
319 WINAPI
320 CreateSystemThreads(PVOID pParam)
321 {
322 NtUserCallOneParam((DWORD)pParam, ONEPARAM_ROUTINE_CREATESYSTEMTHREADS);
323 DPRINT1("This thread should not terminate!\n");
324 return 0;
325 }
326
327 NTSTATUS
328 WINAPI
329 Win32CsrInitialization(IN PCSR_SERVER_DLL ServerDll)
330 {
331 HANDLE ServerThread;
332 CLIENT_ID ClientId;
333 NTSTATUS Status;
334 UINT i;
335
336 Win32CsrApiHeap = RtlGetProcessHeap();
337
338 CsrpInitVideo();
339
340 NtUserInitialize(0, NULL, NULL);
341
342 PrivateCsrssManualGuiCheck(0);
343 CsrInitConsoleSupport();
344
345 /* HACK */
346 ServerDll->DispatchTable = (PVOID)Win32CsrApiDefinitions;
347 ServerDll->HighestApiSupported = 0xDEADBABE;
348
349 ServerDll->HardErrorCallback = Win32CsrHardError;
350 ServerDll->NewProcessCallback = Win32CsrDuplicateHandleTable;
351 ServerDll->DisconnectCallback = Win32CsrReleaseConsole;
352
353 RtlInitializeCriticalSection(&Win32CsrDefineDosDeviceCritSec);
354 InitializeListHead(&DosDeviceHistory);
355
356 /* Start the Raw Input Thread and the Desktop Thread */
357 for (i = 0; i < 2; ++i)
358 {
359 Status = RtlCreateUserThread(NtCurrentProcess(), NULL, TRUE, 0, 0, 0, (PTHREAD_START_ROUTINE)CreateSystemThreads, (PVOID)i, &ServerThread, &ClientId);
360 if (NT_SUCCESS(Status))
361 {
362 NtResumeThread(ServerThread, NULL);
363 NtClose(ServerThread);
364 }
365 else
366 DPRINT1("Cannot start Raw Input Thread!\n");
367 }
368
369 return STATUS_SUCCESS;
370 }
371
372 /* EOF */