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