[NTDLL]
[reactos.git] / win32ss / user / winsrv / init.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS User API Server DLL
4 * FILE: win32ss/user/winsrv/init.c
5 * PURPOSE: Initialization
6 * PROGRAMMERS: Dmitry Philippov (shedon@mail.ru)
7 * Hermes Belusca-Maito (hermes.belusca@sfr.fr)
8 */
9
10 /* INCLUDES *******************************************************************/
11
12 #include "winsrv.h"
13
14 /* Public Win32K Headers */
15 // For calling NtUser...()
16 #include <ntuser.h>
17
18 #define NDEBUG
19 #include <debug.h>
20
21 /* GLOBALS ********************************************************************/
22
23 HINSTANCE UserServerDllInstance = NULL;
24
25 /* Memory */
26 HANDLE UserServerHeap = NULL; // Our own heap.
27
28 // Windows Server 2003 table from http://j00ru.vexillium.org/csrss_list/api_list.html#Windows_2k3
29 PCSR_API_ROUTINE UserServerApiDispatchTable[UserpMaxApiNumber] =
30 {
31 SrvExitWindowsEx,
32 // SrvEndTask,
33 // SrvLogon,
34 SrvRegisterServicesProcess, // Not present in Win7
35 // SrvActivateDebugger,
36 // SrvGetThreadConsoleDesktop, // Not present in Win7
37 // SrvDeviceEvent,
38 SrvRegisterLogonProcess, // Not present in Win7
39 // SrvCreateSystemThreads,
40 // SrvRecordShutdownReason,
41 // SrvCancelShutdown, // Added in Vista
42 // SrvConsoleHandleOperation, // Added in Win7
43 // SrvGetSetShutdownBlockReason, // Added in Vista
44
45 /// HACK: ReactOS-specific
46 RosSetLogonNotifyWindow,
47 };
48
49 BOOLEAN UserServerApiServerValidTable[UserpMaxApiNumber] =
50 {
51 FALSE, // SrvExitWindowsEx
52 // FALSE, // SrvEndTask
53 // FALSE, // SrvLogon
54 FALSE, // SrvRegisterServicesProcess
55 // FALSE, // SrvActivateDebugger
56 // TRUE, // SrvGetThreadConsoleDesktop
57 // FALSE, // SrvDeviceEvent
58 FALSE, // SrvRegisterLogonProcess
59 // FALSE, // SrvCreateSystemThreads
60 // FALSE, // SrvRecordShutdownReason
61 // FALSE, // SrvCancelShutdown
62 // FALSE, // SrvConsoleHandleOperation
63 // FALSE, // SrvGetSetShutdownBlockReason
64
65 /// HACK: ReactOS-specific
66 FALSE, // RosSetLogonNotifyWindow
67 };
68
69 PCHAR UserServerApiNameTable[UserpMaxApiNumber] =
70 {
71 "SrvExitWindowsEx",
72 // "SrvEndTask",
73 // "SrvLogon",
74 "SrvRegisterServicesProcess",
75 // "SrvActivateDebugger",
76 // "SrvGetThreadConsoleDesktop",
77 // "SrvDeviceEvent",
78 "SrvRegisterLogonProcess",
79 // "SrvCreateSystemThreads",
80 // "SrvRecordShutdownReason",
81 // "SrvCancelShutdown",
82 // "SrvConsoleHandleOperation",
83 // "SrvGetSetShutdownBlockReason",
84
85 /// HACK: ReactOS-specific
86 "RosSetLogonNotifyWindow",
87 };
88
89
90 /* FUNCTIONS ******************************************************************/
91
92 // PUSER_SOUND_SENTRY. Used in basesrv.dll
93 BOOL WINAPI _UserSoundSentry(VOID)
94 {
95 // TODO: Do something.
96 return TRUE;
97 }
98
99 ULONG
100 InitializeVideoAddressSpace(VOID)
101 {
102 OBJECT_ATTRIBUTES ObjectAttributes;
103 UNICODE_STRING PhysMemName = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory");
104 NTSTATUS Status;
105 HANDLE PhysMemHandle;
106 PVOID BaseAddress;
107 LARGE_INTEGER Offset;
108 SIZE_T ViewSize;
109 CHAR IVTAndBda[1024+256];
110
111 /* Free the 1MB pre-reserved region. In reality, ReactOS should simply support us mapping the view into the reserved area, but it doesn't. */
112 BaseAddress = 0;
113 ViewSize = 1024 * 1024;
114 Status = ZwFreeVirtualMemory(NtCurrentProcess(),
115 &BaseAddress,
116 &ViewSize,
117 MEM_RELEASE);
118 if (!NT_SUCCESS(Status))
119 {
120 DPRINT1("Couldn't unmap reserved memory (%x)\n", Status);
121 return 0;
122 }
123
124 /* Open the physical memory section */
125 InitializeObjectAttributes(&ObjectAttributes,
126 &PhysMemName,
127 0,
128 NULL,
129 NULL);
130 Status = ZwOpenSection(&PhysMemHandle,
131 SECTION_ALL_ACCESS,
132 &ObjectAttributes);
133 if (!NT_SUCCESS(Status))
134 {
135 DPRINT1("Couldn't open \\Device\\PhysicalMemory\n");
136 return 0;
137 }
138
139 /* Map the BIOS and device registers into the address space */
140 Offset.QuadPart = 0xa0000;
141 ViewSize = 0x100000 - 0xa0000;
142 BaseAddress = (PVOID)0xa0000;
143 Status = ZwMapViewOfSection(PhysMemHandle,
144 NtCurrentProcess(),
145 &BaseAddress,
146 0,
147 ViewSize,
148 &Offset,
149 &ViewSize,
150 ViewUnmap,
151 0,
152 PAGE_EXECUTE_READWRITE);
153 if (!NT_SUCCESS(Status))
154 {
155 DPRINT1("Couldn't map physical memory (%x)\n", Status);
156 ZwClose(PhysMemHandle);
157 return 0;
158 }
159
160 /* Close physical memory section handle */
161 ZwClose(PhysMemHandle);
162
163 if (BaseAddress != (PVOID)0xa0000)
164 {
165 DPRINT1("Couldn't map physical memory at the right address (was %x)\n",
166 BaseAddress);
167 return 0;
168 }
169
170 /* Allocate some low memory to use for the non-BIOS
171 * parts of the v86 mode address space
172 */
173 BaseAddress = (PVOID)0x1;
174 ViewSize = 0xa0000 - 0x1000;
175 Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
176 &BaseAddress,
177 0,
178 &ViewSize,
179 MEM_RESERVE | MEM_COMMIT,
180 PAGE_EXECUTE_READWRITE);
181 if (!NT_SUCCESS(Status))
182 {
183 DPRINT1("Failed to allocate virtual memory (Status %x)\n", Status);
184 return 0;
185 }
186 if (BaseAddress != (PVOID)0x0)
187 {
188 DPRINT1("Failed to allocate virtual memory at right address (was %x)\n",
189 BaseAddress);
190 return 0;
191 }
192
193 /* Get the real mode IVT and BDA from the kernel */
194 Status = NtVdmControl(VdmInitialize, IVTAndBda);
195 if (!NT_SUCCESS(Status))
196 {
197 DPRINT1("NtVdmControl failed (status %x)\n", Status);
198 return 0;
199 }
200
201 /* Return success */
202 return 1;
203 }
204
205 /**********************************************************************
206 * CsrpInitVideo/3
207 *
208 * TODO: we need a virtual device for sessions other than
209 * TODO: the console one
210 */
211 NTSTATUS
212 CsrpInitVideo(VOID)
213 {
214 OBJECT_ATTRIBUTES ObjectAttributes;
215 UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\??\\DISPLAY1");
216 IO_STATUS_BLOCK Iosb;
217 HANDLE VideoHandle = (HANDLE) 0;
218 NTSTATUS Status = STATUS_SUCCESS;
219
220 DPRINT("CSR: %s called\n", __FUNCTION__);
221
222 InitializeVideoAddressSpace();
223
224 InitializeObjectAttributes(&ObjectAttributes,
225 &DeviceName,
226 0,
227 NULL,
228 NULL);
229 Status = NtOpenFile(&VideoHandle,
230 FILE_ALL_ACCESS,
231 &ObjectAttributes,
232 &Iosb,
233 0,
234 0);
235 if (NT_SUCCESS(Status))
236 {
237 NtClose(VideoHandle);
238 }
239
240 return Status;
241 }
242
243 VOID
244 WINAPI
245 PrivateCsrssManualGuiCheck(LONG Check)
246 {
247 NtUserCallOneParam(Check, ONEPARAM_ROUTINE_CSRSS_GUICHECK);
248 }
249
250 /*** HACK from win32csr... ***/
251 static HHOOK hhk = NULL;
252
253 LRESULT
254 CALLBACK
255 KeyboardHookProc(int nCode,
256 WPARAM wParam,
257 LPARAM lParam)
258 {
259 return CallNextHookEx(hhk, nCode, wParam, lParam);
260 }
261 /*** END - HACK from win32csr... ***/
262
263 DWORD
264 WINAPI
265 CreateSystemThreads(PVOID pParam)
266 {
267 NtUserCallOneParam((DWORD)pParam, ONEPARAM_ROUTINE_CREATESYSTEMTHREADS);
268 DPRINT1("This thread should not terminate!\n");
269 return 0;
270 }
271
272 CSR_SERVER_DLL_INIT(UserServerDllInitialization)
273 {
274 /*** From win32csr... ***/
275 HANDLE ServerThread;
276 CLIENT_ID ClientId;
277 NTSTATUS Status;
278 UINT i;
279 /*** END - From win32csr... ***/
280
281 /* Initialize the memory */
282 UserServerHeap = RtlGetProcessHeap();
283
284 /* Initialize the video */
285 CsrpInitVideo();
286 NtUserInitialize(0, NULL, NULL);
287 PrivateCsrssManualGuiCheck(0);
288
289 /* Setup the DLL Object */
290 LoadedServerDll->ApiBase = USERSRV_FIRST_API_NUMBER;
291 LoadedServerDll->HighestApiSupported = UserpMaxApiNumber;
292 LoadedServerDll->DispatchTable = UserServerApiDispatchTable;
293 LoadedServerDll->ValidTable = UserServerApiServerValidTable;
294 LoadedServerDll->NameTable = UserServerApiNameTable;
295 LoadedServerDll->SizeOfProcessData = 0;
296 LoadedServerDll->ConnectCallback = NULL;
297 LoadedServerDll->DisconnectCallback = NULL;
298 LoadedServerDll->HardErrorCallback = UserServerHardError;
299 LoadedServerDll->ShutdownProcessCallback = NULL;
300
301 UserServerDllInstance = LoadedServerDll->ServerHandle;
302
303 /*** From win32csr... See r54125 ***/
304 /* Start the Raw Input Thread and the Desktop Thread */
305 for (i = 0; i < 2; ++i)
306 {
307 Status = RtlCreateUserThread(NtCurrentProcess(), NULL, TRUE, 0, 0, 0, (PTHREAD_START_ROUTINE)CreateSystemThreads, (PVOID)i, &ServerThread, &ClientId);
308 if (NT_SUCCESS(Status))
309 {
310 NtResumeThread(ServerThread, NULL);
311 NtClose(ServerThread);
312 }
313 else
314 DPRINT1("Cannot start Raw Input Thread!\n");
315 }
316 /*** END - From win32csr... ***/
317
318 /* All done */
319 return STATUS_SUCCESS;
320 }
321
322 BOOL
323 WINAPI
324 DllMain(IN HINSTANCE hInstanceDll,
325 IN DWORD dwReason,
326 IN LPVOID lpReserved)
327 {
328 UNREFERENCED_PARAMETER(hInstanceDll);
329 UNREFERENCED_PARAMETER(dwReason);
330 UNREFERENCED_PARAMETER(lpReserved);
331
332 if (DLL_PROCESS_ATTACH == dwReason)
333 {
334 DPRINT1("WINSRV - HACK: Use keyboard hook hack\n");
335 /*** HACK from win32csr... ***/
336 //
337 // HACK HACK HACK ReactOS to BOOT! Initialization BUG ALERT! See bug 5655.
338 //
339 hhk = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProc, NULL, 0);
340 // BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT!
341 // BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT!
342 // BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT!
343
344 /*** END - HACK from win32csr... ***/
345 }
346
347 return TRUE;
348 }
349
350 /* EOF */