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