2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS CSR Sub System
4 * FILE: subsystems/win32/csrss/csrsrv/init.c
5 * PURPOSE: CSR Server DLL Initialization
6 * PROGRAMMERS: ReactOS Portable Systems Group
9 /* INCLUDES *******************************************************************/
15 /* DATA ***********************************************************************/
17 HANDLE CsrHeap
= (HANDLE
) 0;
18 HANDLE CsrObjectDirectory
= (HANDLE
) 0;
19 UNICODE_STRING CsrDirectoryName
;
20 extern HANDLE CsrssApiHeap
;
21 static unsigned ServerProcCount
;
22 static CSRPLUGIN_SERVER_PROCS
*ServerProcs
= NULL
;
23 HANDLE hSbApiPort
= (HANDLE
) 0;
24 HANDLE hBootstrapOk
= (HANDLE
) 0;
25 HANDLE hSmApiPort
= (HANDLE
) 0;
26 HANDLE hApiPort
= (HANDLE
) 0;
28 /* PRIVATE FUNCTIONS **********************************************************/
31 InitializeVideoAddressSpace(VOID
)
33 OBJECT_ATTRIBUTES ObjectAttributes
;
34 UNICODE_STRING PhysMemName
= RTL_CONSTANT_STRING(L
"\\Device\\PhysicalMemory");
40 CHAR IVTAndBda
[1024+256];
42 /* Free the 1MB pre-reserved region. In reality, ReactOS should simply support us mapping the view into the reserved area, but it doesn't. */
44 ViewSize
= 1024 * 1024;
45 Status
= ZwFreeVirtualMemory(NtCurrentProcess(),
49 if (!NT_SUCCESS(Status
))
51 DPRINT1("Couldn't unmap reserved memory (%x)\n", Status
);
55 /* Open the physical memory section */
56 InitializeObjectAttributes(&ObjectAttributes
,
61 Status
= ZwOpenSection(&PhysMemHandle
,
64 if (!NT_SUCCESS(Status
))
66 DPRINT1("Couldn't open \\Device\\PhysicalMemory\n");
70 /* Map the BIOS and device registers into the address space */
71 Offset
.QuadPart
= 0xa0000;
72 ViewSize
= 0x100000 - 0xa0000;
73 BaseAddress
= (PVOID
)0xa0000;
74 Status
= ZwMapViewOfSection(PhysMemHandle
,
83 PAGE_EXECUTE_READWRITE
);
84 if (!NT_SUCCESS(Status
))
86 DPRINT1("Couldn't map physical memory (%x)\n", Status
);
87 ZwClose(PhysMemHandle
);
91 /* Close physical memory section handle */
92 ZwClose(PhysMemHandle
);
94 if (BaseAddress
!= (PVOID
)0xa0000)
96 DPRINT1("Couldn't map physical memory at the right address (was %x)\n",
101 /* Allocate some low memory to use for the non-BIOS
102 * parts of the v86 mode address space
104 BaseAddress
= (PVOID
)0x1;
105 ViewSize
= 0xa0000 - 0x1000;
106 Status
= ZwAllocateVirtualMemory(NtCurrentProcess(),
110 MEM_RESERVE
| MEM_COMMIT
,
111 PAGE_EXECUTE_READWRITE
);
112 if (!NT_SUCCESS(Status
))
114 DPRINT1("Failed to allocate virtual memory (Status %x)\n", Status
);
117 if (BaseAddress
!= (PVOID
)0x0)
119 DPRINT1("Failed to allocate virtual memory at right address (was %x)\n",
124 /* Get the real mode IVT and BDA from the kernel */
125 Status
= NtVdmControl(VdmInitialize
, IVTAndBda
);
126 if (!NT_SUCCESS(Status
))
128 DPRINT1("NtVdmControl failed (status %x)\n", Status
);
137 static NTSTATUS FASTCALL
138 CsrpAddServerProcs(CSRPLUGIN_SERVER_PROCS
*Procs
)
140 CSRPLUGIN_SERVER_PROCS
*NewProcs
;
142 DPRINT("CSR: %s called\n", __FUNCTION__
);
144 NewProcs
= RtlAllocateHeap(CsrssApiHeap
, 0,
145 (ServerProcCount
+ 1)
146 * sizeof(CSRPLUGIN_SERVER_PROCS
));
147 if (NULL
== NewProcs
)
149 return STATUS_NO_MEMORY
;
151 if (0 != ServerProcCount
)
153 RtlCopyMemory(NewProcs
, ServerProcs
,
154 ServerProcCount
* sizeof(CSRPLUGIN_SERVER_PROCS
));
155 RtlFreeHeap(CsrssApiHeap
, 0, ServerProcs
);
157 NewProcs
[ServerProcCount
] = *Procs
;
158 ServerProcs
= NewProcs
;
161 return STATUS_SUCCESS
;
164 /**********************************************************************
168 CallInitComplete(void)
173 DPRINT("CSR: %s called\n", __FUNCTION__
);
176 for (i
= 0; i
< ServerProcCount
&& Ok
; i
++)
178 Ok
= (*ServerProcs
[i
].InitCompleteProc
)();
185 CallHardError(IN PCSRSS_PROCESS_DATA ProcessData
,
186 IN PHARDERROR_MSG HardErrorMessage
)
191 DPRINT("CSR: %s called\n", __FUNCTION__
);
194 for (i
= 0; i
< ServerProcCount
&& Ok
; i
++)
196 Ok
= (*ServerProcs
[i
].HardErrorProc
)(ProcessData
, HardErrorMessage
);
203 CallProcessInherit(IN PCSRSS_PROCESS_DATA SourceProcessData
,
204 IN PCSRSS_PROCESS_DATA TargetProcessData
)
206 NTSTATUS Status
= STATUS_SUCCESS
;
209 DPRINT("CSR: %s called\n", __FUNCTION__
);
211 for (i
= 0; i
< ServerProcCount
&& NT_SUCCESS(Status
); i
++)
212 Status
= (*ServerProcs
[i
].ProcessInheritProc
)(SourceProcessData
, TargetProcessData
);
218 CallProcessDeleted(IN PCSRSS_PROCESS_DATA ProcessData
)
220 NTSTATUS Status
= STATUS_SUCCESS
;
223 DPRINT("CSR: %s called\n", __FUNCTION__
);
225 for (i
= 0; i
< ServerProcCount
&& NT_SUCCESS(Status
); i
++)
226 Status
= (*ServerProcs
[i
].ProcessDeletedProc
)(ProcessData
);
233 InitializeVideoAddressSpace(VOID
);
235 /**********************************************************************
236 * CsrpCreateObjectDirectory/3
239 CsrpCreateObjectDirectory (int argc
, char ** argv
, char ** envp
)
242 OBJECT_ATTRIBUTES Attributes
;
244 DPRINT("CSR: %s called\n", __FUNCTION__
);
247 /* create object directory ('\Windows') */
248 RtlCreateUnicodeString (&CsrDirectoryName
,
251 InitializeObjectAttributes (&Attributes
,
257 Status
= NtOpenDirectoryObject(&CsrObjectDirectory
,
258 DIRECTORY_ALL_ACCESS
,
263 /**********************************************************************
266 * TODO: we need a virtual device for sessions other than
267 * TODO: the console one
270 CsrpInitVideo (int argc
, char ** argv
, char ** envp
)
272 OBJECT_ATTRIBUTES ObjectAttributes
;
273 UNICODE_STRING DeviceName
= RTL_CONSTANT_STRING(L
"\\??\\DISPLAY1");
274 IO_STATUS_BLOCK Iosb
;
275 HANDLE VideoHandle
= (HANDLE
) 0;
276 NTSTATUS Status
= STATUS_SUCCESS
;
278 DPRINT("CSR: %s called\n", __FUNCTION__
);
280 InitializeVideoAddressSpace();
282 InitializeObjectAttributes(&ObjectAttributes
,
287 Status
= NtOpenFile(&VideoHandle
,
293 if (NT_SUCCESS(Status
))
295 NtClose(VideoHandle
);
300 /**********************************************************************
303 * TODO: this function should be turned more general to load an
304 * TODO: hosted server DLL as received from the command line;
305 * TODO: for instance: ServerDll=winsrv:ConServerDllInitialization,2
306 * TODO: ^method ^dll ^api ^sid
308 * TODO: CsrpHostServerDll (LPWSTR DllName,
309 * TODO: LPWSTR ApiName,
310 * TODO: DWORD ServerId)
313 CsrpInitWin32Csr (int argc
, char ** argv
, char ** envp
)
316 UNICODE_STRING DllName
;
318 ANSI_STRING ProcName
;
319 CSRPLUGIN_INITIALIZE_PROC InitProc
;
320 CSRSS_EXPORTED_FUNCS Exports
;
321 PCSRSS_API_DEFINITION ApiDefinitions
;
322 CSRPLUGIN_SERVER_PROCS ServerProcs
;
324 DPRINT("CSR: %s called\n", __FUNCTION__
);
326 RtlInitUnicodeString(&DllName
, L
"win32csr.dll");
327 Status
= LdrLoadDll(NULL
, 0, &DllName
, (PVOID
*) &hInst
);
328 if (! NT_SUCCESS(Status
))
332 RtlInitAnsiString(&ProcName
, "Win32CsrInitialization");
333 Status
= LdrGetProcedureAddress(hInst
, &ProcName
, 0, (PVOID
*) &InitProc
);
334 if (! NT_SUCCESS(Status
))
338 Exports
.CsrEnumProcessesProc
= CsrEnumProcesses
;
339 if (! (*InitProc
)(&ApiDefinitions
, &ServerProcs
, &Exports
, CsrssApiHeap
))
341 return STATUS_UNSUCCESSFUL
;
344 Status
= CsrApiRegisterDefinitions(ApiDefinitions
);
345 if (! NT_SUCCESS(Status
))
349 Status
= CsrpAddServerProcs(&ServerProcs
);
353 CSRSS_API_DEFINITION NativeDefinitions
[] =
355 CSRSS_DEFINE_API(CREATE_PROCESS
, CsrCreateProcess
),
356 CSRSS_DEFINE_API(CREATE_THREAD
, CsrSrvCreateThread
),
357 CSRSS_DEFINE_API(TERMINATE_PROCESS
, CsrTerminateProcess
),
358 CSRSS_DEFINE_API(CONNECT_PROCESS
, CsrConnectProcess
),
359 CSRSS_DEFINE_API(REGISTER_SERVICES_PROCESS
, CsrRegisterServicesProcess
),
360 CSRSS_DEFINE_API(GET_SHUTDOWN_PARAMETERS
, CsrGetShutdownParameters
),
361 CSRSS_DEFINE_API(SET_SHUTDOWN_PARAMETERS
, CsrSetShutdownParameters
),
365 static NTSTATUS WINAPI
366 CsrpCreateListenPort (IN LPWSTR Name
,
368 IN PTHREAD_START_ROUTINE ListenThread
)
370 NTSTATUS Status
= STATUS_SUCCESS
;
371 OBJECT_ATTRIBUTES PortAttributes
;
372 UNICODE_STRING PortName
;
376 DPRINT("CSR: %s called\n", __FUNCTION__
);
378 RtlInitUnicodeString (& PortName
, Name
);
379 InitializeObjectAttributes (& PortAttributes
,
384 Status
= NtCreatePort ( Port
,
386 sizeof(SB_CONNECTION_INFO
),
388 32 * sizeof(SB_API_MSG
));
389 if(!NT_SUCCESS(Status
))
391 DPRINT1("CSR: %s: NtCreatePort failed (Status=%08lx)\n",
392 __FUNCTION__
, Status
);
395 Status
= RtlCreateUserThread(NtCurrentProcess(),
401 (PTHREAD_START_ROUTINE
) ListenThread
,
406 if (ListenThread
== (PVOID
)ClientConnectionThread
)
408 CsrAddStaticServerThread(ServerThread
, &ClientId
, 0);
411 NtResumeThread(ServerThread
, NULL
);
412 NtClose(ServerThread
);
416 /* === INIT ROUTINES === */
418 /**********************************************************************
419 * CsrpCreateBNODirectory/3
421 * These used to be part of kernel32 startup, but that clearly wasn't a good
422 * idea, as races were definately possible. These are moved (as in the
426 CsrpCreateBNODirectory (int argc
, char ** argv
, char ** envp
)
429 OBJECT_ATTRIBUTES ObjectAttributes
;
430 UNICODE_STRING Name
= RTL_CONSTANT_STRING(L
"\\BaseNamedObjects");
431 UNICODE_STRING SymName
= RTL_CONSTANT_STRING(L
"Local");
432 UNICODE_STRING SymName2
= RTL_CONSTANT_STRING(L
"Global");
433 HANDLE DirHandle
, SymHandle
;
435 /* Seems like a good place to create these objects which are needed by
437 InitializeObjectAttributes(&ObjectAttributes
,
439 OBJ_CASE_INSENSITIVE
,
443 Status
= NtCreateDirectoryObject(&DirHandle
,
444 DIRECTORY_ALL_ACCESS
,
446 if (!NT_SUCCESS(Status
))
448 DPRINT1("NtCreateDirectoryObject() failed %08x\n", Status
);
451 /* Create the "local" Symbolic Link.
452 * FIXME: CSR should do this -- Fixed */
453 InitializeObjectAttributes(&ObjectAttributes
,
455 OBJ_CASE_INSENSITIVE
,
458 Status
= NtCreateSymbolicLinkObject(&SymHandle
,
459 SYMBOLIC_LINK_ALL_ACCESS
,
462 if (!NT_SUCCESS(Status
))
464 DPRINT1("NtCreateDirectoryObject() failed %08x\n", Status
);
467 /* Create the "global" Symbolic Link. */
468 InitializeObjectAttributes(&ObjectAttributes
,
470 OBJ_CASE_INSENSITIVE
,
473 Status
= NtCreateSymbolicLinkObject(&SymHandle
,
474 SYMBOLIC_LINK_ALL_ACCESS
,
477 if (!NT_SUCCESS(Status
))
479 DPRINT1("NtCreateDirectoryObject() failed %08x\n", Status
);
488 BasepFakeStaticServerData(VOID
);
492 CsrSrvCreateSharedSection(IN PCHAR ParameterValue
);
494 /**********************************************************************
498 CsrpCreateHeap (int argc
, char ** argv
, char ** envp
)
500 CHAR Value
[] = "1024,3072,512";
502 DPRINT("CSR: %s called\n", __FUNCTION__
);
504 CsrssApiHeap
= RtlCreateHeap(HEAP_GROWABLE
,
510 if (CsrssApiHeap
== NULL
)
512 return STATUS_UNSUCCESSFUL
;
516 Status
= CsrSrvCreateSharedSection(Value
);
517 if (Status
!= STATUS_SUCCESS
)
519 DPRINT1("CsrSrvCreateSharedSection failed with status 0x%08lx\n", Status
);
523 BasepFakeStaticServerData();
524 return STATUS_SUCCESS
;
527 /**********************************************************************
528 * CsrpCreateCallbackPort/3
531 CsrpCreateCallbackPort (int argc
, char ** argv
, char ** envp
)
533 DPRINT("CSR: %s called\n", __FUNCTION__
);
535 return CsrpCreateListenPort (L
"\\Windows\\SbApiPort",
537 ServerSbApiPortThread
);
540 /**********************************************************************
541 * CsrpRegisterSubsystem/3
545 CsrpRegisterSubsystem (int argc
, char ** argv
, char ** envp
)
547 NTSTATUS Status
= STATUS_SUCCESS
;
548 OBJECT_ATTRIBUTES BootstrapOkAttributes
;
551 DPRINT("CSR: %s called\n", __FUNCTION__
);
554 * Create the event object the callback port
555 * thread will signal *if* the SM will
556 * authorize us to bootstrap.
558 RtlInitUnicodeString (& Name
, L
"\\CsrssBooting");
559 InitializeObjectAttributes(& BootstrapOkAttributes
,
562 Status
= NtCreateEvent (& hBootstrapOk
,
564 & BootstrapOkAttributes
,
565 SynchronizationEvent
,
567 if(!NT_SUCCESS(Status
))
569 DPRINT("CSR: %s: NtCreateEvent failed (Status=0x%08lx)\n",
570 __FUNCTION__
, Status
);
574 * Let's tell the SM a new environment
575 * subsystem server is in the system.
577 RtlInitUnicodeString (& Name
, L
"\\Windows\\SbApiPort");
578 DPRINT("CSR: %s: registering with SM for\n IMAGE_SUBSYSTEM_WINDOWS_CUI == 3\n", __FUNCTION__
);
579 Status
= SmConnectApiPort (& Name
,
581 IMAGE_SUBSYSTEM_WINDOWS_CUI
,
583 if (!NT_SUCCESS(Status
))
585 Status
= SmConnectToSm(&Name
, hSbApiPort
, IMAGE_SUBSYSTEM_WINDOWS_GUI
, &hSmApiPort
);
588 if(!NT_SUCCESS(Status
))
590 DPRINT("CSR: %s unable to connect to the SM (Status=0x%08lx)\n",
591 __FUNCTION__
, Status
);
592 NtClose (hBootstrapOk
);
596 * Wait for SM to reply OK... If the SM
597 * won't answer, we hang here forever!
599 DPRINT("CSR: %s: waiting for SM to OK boot...\n", __FUNCTION__
);
600 Status
= NtWaitForSingleObject (hBootstrapOk
,
603 NtClose (hBootstrapOk
);
608 /**********************************************************************
609 * CsrpLoadKernelModeDriver/3
612 CsrpLoadKernelModeDriver (int argc
, char ** argv
, char ** envp
)
614 NTSTATUS Status
= STATUS_SUCCESS
;
615 WCHAR Data
[MAX_PATH
+ 1];
616 ULONG DataLength
= sizeof Data
;
618 //UNICODE_STRING Environment;
621 DPRINT1("SM: %s called\n", __FUNCTION__
);
624 //EnvpToUnicodeString (envp, & Environment);
625 Status
= SmLookupSubsystem (L
"Kmode",
630 //RtlFreeUnicodeString (& Environment);
631 if((STATUS_SUCCESS
== Status
) && (DataLength
> sizeof Data
[0]))
633 WCHAR ImagePath
[MAX_PATH
+ 1] = {0};
634 UNICODE_STRING ModuleName
;
636 wcscpy (ImagePath
, L
"\\SYSTEMROOT\\system32\\win32k.sys");
637 // wcscat (ImagePath, Data);
638 RtlInitUnicodeString (& ModuleName
, ImagePath
);
639 Status
= NtSetSystemInformation(/* FIXME: SystemLoadAndCallImage */
640 SystemExtendServiceTableInformation
,
643 if(!NT_SUCCESS(Status
))
645 DPRINT1("WIN: %s: loading Kmode failed (Status=0x%08lx)\n",
646 __FUNCTION__
, Status
);
653 /**********************************************************************
654 * CsrpCreateApiPort/2
657 CsrpCreateApiPort (int argc
, char ** argv
, char ** envp
)
659 DPRINT("CSR: %s called\n", __FUNCTION__
);
661 CsrInitProcessData();
663 return CsrpCreateListenPort(L
"\\Windows\\ApiPort", &hApiPort
,
664 (PTHREAD_START_ROUTINE
)ClientConnectionThread
);
667 /**********************************************************************
668 * CsrpApiRegisterDef/0
671 CsrpApiRegisterDef (int argc
, char ** argv
, char ** envp
)
673 return CsrApiRegisterDefinitions(NativeDefinitions
);
676 /**********************************************************************
680 CsrpCCTS (int argc
, char ** argv
, char ** envp
)
683 ULONG DummyLength
= sizeof(Dummy
);
684 return CsrClientConnectToServer(L
"\\Windows",
685 0, &Dummy
, &DummyLength
, NULL
);
688 /**********************************************************************
691 * Start the logon process (winlogon.exe).
693 * TODO: this should be moved in CsrpCreateSession/x (one per session)
694 * TODO: in its own desktop (one logon desktop per winstation).
697 CsrpRunWinlogon (int argc
, char ** argv
, char ** envp
)
699 NTSTATUS Status
= STATUS_SUCCESS
;
700 UNICODE_STRING ImagePath
;
701 UNICODE_STRING CommandLine
;
702 PRTL_USER_PROCESS_PARAMETERS ProcessParameters
= NULL
;
703 RTL_USER_PROCESS_INFORMATION ProcessInfo
;
706 DPRINT("CSR: %s called\n", __FUNCTION__
);
707 if (g_ModernSm
) return STATUS_SUCCESS
;
709 /* initialize the process parameters */
710 RtlInitUnicodeString (& ImagePath
, L
"\\SystemRoot\\system32\\winlogon.exe");
711 RtlInitUnicodeString (& CommandLine
, L
"");
712 RtlCreateProcessParameters(& ProcessParameters
,
722 /* Create the winlogon process */
723 Status
= RtlCreateUserProcess (& ImagePath
,
724 OBJ_CASE_INSENSITIVE
,
734 RtlDestroyProcessParameters (ProcessParameters
);
735 if (!NT_SUCCESS(Status
))
737 DPRINT1("SM: %s: loading winlogon.exe failed (Status=%08lx)\n",
738 __FUNCTION__
, Status
);
741 ZwResumeThread(ProcessInfo
.ThreadHandle
, NULL
);
746 CsrpCreateHardErrorPort (int argc
, char ** argv
, char ** envp
)
748 return NtSetDefaultHardErrorPort(hApiPort
);
751 typedef NTSTATUS (* CSR_INIT_ROUTINE
)(int,char**,char**);
755 CSR_INIT_ROUTINE EntryPoint
;
758 {TRUE
, CsrpCreateBNODirectory
, "create base named objects directory"},
759 {TRUE
, CsrpCreateHeap
, "create the CSR heap"},
760 {TRUE
, CsrpCreateApiPort
, "create the api port \\Windows\\ApiPort"},
761 {TRUE
, CsrpCreateHardErrorPort
, "create the hard error port"},
762 {TRUE
, CsrpCreateObjectDirectory
,"create the object directory \\Windows"},
763 // {TRUE, CsrpLoadKernelModeDriver, "load Kmode driver"},
764 {TRUE
, CsrpInitVideo
, "initialize video"},
765 {TRUE
, CsrpApiRegisterDef
, "initialize api definitions"},
766 {TRUE
, CsrpCCTS
, "connect client to server"},
767 {TRUE
, CsrpInitWin32Csr
, "load usermode dll"},
768 {TRUE
, CsrpCreateCallbackPort
, "create the callback port \\Windows\\SbApiPort"},
769 {TRUE
, CsrpRegisterSubsystem
, "register with SM"},
770 {TRUE
, CsrpRunWinlogon
, "run WinLogon"},
773 /* PUBLIC FUNCTIONS ***********************************************************/
777 CsrServerInitialization(ULONG ArgumentCount
,
781 NTSTATUS Status
= STATUS_SUCCESS
;
783 DPRINT("CSR: %s called\n", __FUNCTION__
);
785 for (i
=0; i
< (sizeof InitRoutine
/ sizeof InitRoutine
[0]); i
++)
787 Status
= InitRoutine
[i
].EntryPoint(ArgumentCount
,Arguments
,NULL
);
788 if(!NT_SUCCESS(Status
))
790 DPRINT1("CSR: %s: failed to %s (Status=%08lx)\n",
792 InitRoutine
[i
].ErrorMessage
,
794 if (InitRoutine
[i
].Required
)
800 if (CallInitComplete())
802 Status
= SmCompleteSession (hSmApiPort
,hSbApiPort
,hApiPort
);
803 return STATUS_SUCCESS
;
806 return STATUS_UNSUCCESSFUL
;
815 /* We don't do much */
816 UNREFERENCED_PARAMETER(hDll
);
817 UNREFERENCED_PARAMETER(dwReason
);
818 UNREFERENCED_PARAMETER(lpReserved
);