3 * subsys/csr/csrsrv/init.c - CSR server - initialization
5 * ReactOS Operating System
7 * --------------------------------------------------------------------
9 * This software is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
14 * This software is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this software; see the file COPYING.LIB. If not, write
21 * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
24 * --------------------------------------------------------------------
35 CSRAT_OBJECT_DIRECTORY
,
37 CSRAT_REQUEST_THREADS
, /* ReactOS extension */
38 CSRAT_REQUEST_THREADS_MAX
,
39 CSRAT_PROFILE_CONTROL
,
43 CSRAT_SESSIONS
, /* ReactOS extension */
45 } CSR_ARGUMENT_TYPE
, *PCSR_ARGUMENT_TYPE
;
47 typedef struct _CSR_ARGUMENT_ITEM
49 CSR_ARGUMENT_TYPE Type
;
52 UNICODE_STRING ObjectDirectory
;
53 CSR_SUBSYSTEM_TYPE SubSystemType
;
54 USHORT RequestThreads
;
55 USHORT MaxRequestThreads
;
59 CSR_SERVER_DLL ServerDll
;
61 USHORT PortSectionSize
; // 1024k; 128k..?
62 USHORT InteractiveDesktopHeapSize
; // 3072k; 128k..
63 USHORT NonInteractiveDesktopHeapSize
; // (InteractiveDesktopHeapSize); 128k..
64 USHORT Reserved
; /* unused */
68 } CSR_ARGUMENT_ITEM
, * PCSR_ARGUMENT_ITEM
;
70 /**********************************************************************
71 * CsrpStringToBool/3 PRIVATE
73 static BOOL STDCALL
CsrpStringToBool (LPWSTR TestString
, LPWSTR TrueString
, LPWSTR FalseString
)
75 if((0 == wcscmp(TestString
, TrueString
)))
79 if((0 == wcscmp(TestString
, FalseString
)))
83 DPRINT1("CSRSRV:%s: replacing invalid value '%S' with '%S'!\n",
84 __FUNCTION__
, TestString
, FalseString
);
87 /**********************************************************************
88 * CsrpSplitServerDll/2 PRIVATE
92 * 2: ServerDll=="basesrv,1"
93 * 3: ServerDll=="winsrv:UserServerDllInitialization,3"
95 static INT STDCALL
CsrpSplitServerDll (LPWSTR ServerDll
, PCSR_ARGUMENT_ITEM pItem
)
97 LPWSTR DllName
= NULL
;
98 LPWSTR DllEntryPoint
= NULL
;
100 static LPWSTR DefaultDllEntryPoint
= L
"ServerDllInitialization";
103 PCSR_SERVER_DLL pCsrServerDll
= & pItem
->Item
.ServerDll
;
105 if (L
'\0' == *ServerDll
)
118 * DllEntryPoint (optional)
120 DllEntryPoint
= wcschr (ServerDll
, L
':');
121 if (NULL
== DllEntryPoint
)
123 DllEntryPoint
= DefaultDllEntryPoint
;
127 tmp
= ++DllEntryPoint
;
133 DllId
= wcschr (tmp
, L
',');
140 pCsrServerDll
->ServerIndex
= wcstoul (DllId
, NULL
, 10);
141 pCsrServerDll
->Unused
= 0;
142 RtlInitUnicodeString (& pCsrServerDll
->DllName
, DllName
);
143 RtlInitUnicodeString (& pCsrServerDll
->DllEntryPoint
, DllEntryPoint
);
146 /**********************************************************************
147 * CsrpSplitSharedSection/2 PRIVATE
151 * 1: PortSectionSize (required)
152 * 2: PortSection,InteractiveDesktopHeap
153 * 3: PortSection,InteractiveDesktopHeap,NonInteractiveDesktopHeap
155 static INT STDCALL
CsrpSplitSharedSection (LPWSTR SharedSection
, PCSR_ARGUMENT_ITEM pItem
)
157 LPWSTR PortSectionSize
= NULL
;
158 LPWSTR InteractiveDesktopHeapSize
= NULL
;
159 LPWSTR NonInteractiveDesktopHeapSize
= NULL
;
162 DPRINT("CSRSRV:%s(%S) called\n", __FUNCTION__
, SharedSection
);
164 if(L
'\0' == *SharedSection
)
166 DPRINT("CSRSRV:%s(%S): *SharedSection == L'\\0'\n", __FUNCTION__
, SharedSection
);
170 // PortSectionSize (required)
171 PortSectionSize
= SharedSection
;
172 // InteractiveDesktopHeapSize (optional)
173 InteractiveDesktopHeapSize
= wcschr (PortSectionSize
, L
',');
174 if (NULL
== InteractiveDesktopHeapSize
)
176 // Default value is 128k
177 InteractiveDesktopHeapSize
= L
"128";
181 // NonInteractiveDesktopHeapSize (optional)
182 NonInteractiveDesktopHeapSize
= wcschr (InteractiveDesktopHeapSize
, L
',');
183 if (NULL
== NonInteractiveDesktopHeapSize
)
185 // Default value equals interactive one
186 NonInteractiveDesktopHeapSize
= InteractiveDesktopHeapSize
;
190 // OK - normalization
191 pItem
->Item
.SharedSection
.PortSectionSize
= wcstoul (PortSectionSize
, NULL
, 10);
192 if (pItem
->Item
.SharedSection
.PortSectionSize
< 64)
194 pItem
->Item
.SharedSection
.PortSectionSize
= 64;
196 pItem
->Item
.SharedSection
.InteractiveDesktopHeapSize
= wcstoul (InteractiveDesktopHeapSize
, NULL
, 10);
197 if (pItem
->Item
.SharedSection
.InteractiveDesktopHeapSize
< 128)
199 pItem
->Item
.SharedSection
.InteractiveDesktopHeapSize
= 128;
201 pItem
->Item
.SharedSection
.NonInteractiveDesktopHeapSize
= wcstoul (NonInteractiveDesktopHeapSize
, NULL
, 10);
202 if (pItem
->Item
.SharedSection
.NonInteractiveDesktopHeapSize
< 128)
204 pItem
->Item
.SharedSection
.NonInteractiveDesktopHeapSize
= 128;
209 /**********************************************************************
210 * CsrpParseArgumentItem/1 PRIVATE
215 * Argument: argument to decode;
218 * STATUS_SUCCESS; otherwise, STATUS_UNSUCCESSFUL and
219 * pItem->Type = CSRAT_UNKNOWN.
222 * The command line could be as complex as the following one,
223 * which is the original command line for the Win32 subsystem
226 * %SystemRoot%\system32\csrss.exe
227 * ObjectDirectory=\Windows
228 * SharedSection=1024,3072,512
230 * SubSystemType=Windows
231 * ServerDll=basesrv,1
232 * ServerDll=winsrv:UserServerDllInitialization,3
233 * ServerDll=winsrv:ConServerDllInitialization,2
235 * MaxRequestThreads=16
237 static NTSTATUS FASTCALL
CsrpParseArgumentItem (IN OUT PCSR_ARGUMENT_ITEM pItem
)
239 NTSTATUS Status
= STATUS_SUCCESS
;
240 LPWSTR ParameterName
= NULL
;
241 LPWSTR ParameterValue
= NULL
;
243 pItem
->Type
= CSRAT_UNKNOWN
;
245 if(0 == pItem
->Data
.Length
)
247 DPRINT1("CSRSRV:%s: (0 == Data.Length)!\n", __FUNCTION__
);
248 return STATUS_INVALID_PARAMETER
;
250 //--- Seek '=' to split name and value
251 ParameterName
= pItem
->Data
.Buffer
;
252 ParameterValue
= wcschr (ParameterName
, L
'=');
253 if (NULL
== ParameterValue
)
255 DPRINT1("CSRSRV:%s: (NULL == ParameterValue)!\n", __FUNCTION__
);
256 return STATUS_INVALID_PARAMETER
;
258 *ParameterValue
++ = L
'\0';
259 DPRINT("Name=%S, Value=%S\n", ParameterName
, ParameterValue
);
261 if(0 == wcscmp(ParameterName
, L
"ObjectDirectory"))
263 RtlInitUnicodeString (& pItem
->Item
.ObjectDirectory
, ParameterValue
);
264 pItem
->Type
= CSRAT_OBJECT_DIRECTORY
;
266 else if(0 == wcscmp(ParameterName
, L
"SubSystemType"))
268 pItem
->Type
= CSRAT_SUBSYSTEM_TYPE
;
269 pItem
->Item
.Windows
= CsrpStringToBool (ParameterValue
, L
"Windows", L
"Text");
271 else if(0 == wcscmp(ParameterName
, L
"MaxRequestThreads"))
273 pItem
->Item
.MaxRequestThreads
= (USHORT
) wcstoul (ParameterValue
, NULL
, 10);
274 pItem
->Type
= CSRAT_REQUEST_THREADS_MAX
;
276 else if(0 == wcscmp(ParameterName
, L
"RequestThreads"))
279 pItem
->Item
.RequestThreads
= (USHORT
) wcstoul (ParameterValue
, NULL
, 10);
280 pItem
->Type
= CSRAT_REQUEST_THREADS
;
282 else if(0 == wcscmp(ParameterName
, L
"ProfileControl"))
284 pItem
->Item
.ProfileControl
= CsrpStringToBool (ParameterValue
, L
"On", L
"Off");
285 pItem
->Type
= CSRAT_PROFILE_CONTROL
;
287 else if(0 == wcscmp(ParameterName
, L
"SharedSection"))
289 if (0 != CsrpSplitSharedSection(ParameterValue
, pItem
))
291 pItem
->Type
= CSRAT_SHARED_SECTION
;
293 pItem
->Type
= CSRAT_UNKNOWN
;
294 return STATUS_INVALID_PARAMETER
;
297 else if(0 == wcscmp(ParameterName
, L
"ServerDll"))
299 if (0 != CsrpSplitServerDll(ParameterValue
, pItem
))
301 pItem
->Type
= CSRAT_SERVER_DLL
;
303 pItem
->Type
= CSRAT_UNKNOWN
;
304 return STATUS_INVALID_PARAMETER
;
307 else if(0 == wcscmp(ParameterName
, L
"Windows"))
309 pItem
->Item
.Windows
= CsrpStringToBool (ParameterValue
, L
"On", L
"Off");
310 pItem
->Type
= CSRAT_WINDOWS
;
312 else if(0 == wcscmp(ParameterName
, L
"Sessions"))
315 pItem
->Item
.Sessions
= CsrpStringToBool (ParameterValue
, L
"On", L
"Off");
316 pItem
->Type
= CSRAT_SESSIONS
;
320 DPRINT1("CSRSRV:%s: unknown parameter '%S'!\n", __FUNCTION__
, ParameterName
);
321 pItem
->Type
= CSRAT_UNKNOWN
;
322 Status
= STATUS_INVALID_PARAMETER
;
326 /**********************************************************************
327 * CsrServerInitialization/2
330 * Every environment subsystem implicitly starts where this
331 * routines stops. This routine is called by CSR on startup
332 * and then it calls the entry points in the following server
333 * DLLs, as per command line.
340 * STATUS_SUCCESS if it succeeds. Otherwise a status code.
343 * This is the only function explicitly called by csr.exe.
345 NTSTATUS STDCALL
CsrServerInitialization (ULONG ArgumentCount
,
348 NTSTATUS Status
= STATUS_SUCCESS
;
349 ULONG ArgumentIndex
= 0;
350 CSR_ARGUMENT_ITEM ArgumentItem
= {CSRAT_UNKNOWN
,};
352 // get registry bootstrap options
353 for (ArgumentIndex
= 0; ArgumentIndex
< ArgumentCount
; ArgumentIndex
++)
355 RtlInitUnicodeString (& ArgumentItem
.Data
, Argument
[ArgumentIndex
]);
356 Status
= CsrpParseArgumentItem (& ArgumentItem
);
357 if (NT_SUCCESS(Status
))
359 switch (ArgumentItem
.Type
)
362 // ignore unknown parameters
363 DPRINT1("CSRSRV: ignoring param '%s'\n", Argument
[ArgumentIndex
]);
365 case CSRAT_OBJECT_DIRECTORY
:
366 RtlDuplicateUnicodeString (1, & ArgumentItem
.Item
.ObjectDirectory
, & CsrSrvOption
.NameSpace
.Root
);
367 DPRINT("ObjectDirectory: '%S'\n", CsrSrvOption
.NameSpace
.Root
.Buffer
);
369 case CSRAT_SUBSYSTEM_TYPE
:
370 CsrSrvOption
.SubSystemType
= ArgumentItem
.Item
.SubSystemType
;
371 DPRINT("SubSystemType: %u\n", CsrSrvOption
.SubSystemType
);
373 case CSRAT_REQUEST_THREADS
:
374 CsrSrvOption
.Threads
.RequestCount
= ArgumentItem
.Item
.RequestThreads
;
375 DPRINT("RequestThreads: %u\n", CsrSrvOption
.Threads
.RequestCount
);
377 case CSRAT_REQUEST_THREADS_MAX
:
378 CsrSrvOption
.Threads
.MaxRequestCount
= ArgumentItem
.Item
.MaxRequestThreads
;
379 DPRINT("MaxRequestThreads: %u\n", CsrSrvOption
.Threads
.MaxRequestCount
);
381 case CSRAT_PROFILE_CONTROL
:
382 CsrSrvOption
.Flag
.ProfileControl
= ArgumentItem
.Item
.ProfileControl
;
383 DPRINT("ProfileControl: %u \n", CsrSrvOption
.Flag
.ProfileControl
);
385 case CSRAT_SHARED_SECTION
:
386 CsrSrvOption
.PortSharedSectionSize
= ArgumentItem
.Item
.SharedSection
.PortSectionSize
;
387 CsrSrvOption
.Heap
.InteractiveDesktopHeapSize
= ArgumentItem
.Item
.SharedSection
.InteractiveDesktopHeapSize
;
388 CsrSrvOption
.Heap
.NonInteractiveDesktopHeapSize
= ArgumentItem
.Item
.SharedSection
.NonInteractiveDesktopHeapSize
;
389 DPRINT("SharedSection: %u-%u-%u\n",
390 CsrSrvOption
.PortSharedSectionSize
,
391 CsrSrvOption
.Heap
.InteractiveDesktopHeapSize
,
392 CsrSrvOption
.Heap
.NonInteractiveDesktopHeapSize
);
394 case CSRAT_SERVER_DLL
:
395 Status
= CsrSrvRegisterServerDll (& ArgumentItem
.Item
.ServerDll
);
396 if(!NT_SUCCESS(Status
))
398 DPRINT1("CSRSRV: CsrSrvRegisterServerDll(%S) failed!\n",
399 Argument
[ArgumentIndex
]);
401 DPRINT("ServerDll: DLL='%S' Entrypoint='%S' ID=%u\n",
402 ArgumentItem
.Item
.ServerDll
.DllName
.Buffer
,
403 ArgumentItem
.Item
.ServerDll
.DllEntryPoint
.Buffer
,
404 ArgumentItem
.Item
.ServerDll
.ServerIndex
);
408 CsrSrvOption
.Flag
.Windows
= ArgumentItem
.Item
.Windows
;
409 DPRINT("Windows: %d\n", CsrSrvOption
.Flag
.Windows
);
412 CsrSrvOption
.Flag
.Sessions
= ArgumentItem
.Item
.Sessions
;
413 DPRINT("Sessions: %d\n", CsrSrvOption
.Flag
.Sessions
);
416 DPRINT("CSRSRV: unknown ArgumentItem->Type=%ld!\n", ArgumentItem
.Type
);
419 DPRINT1("CSRSRV:%s: CsrpParseArgumentItem(%S) failed with Status = %08lx\n",
420 __FUNCTION__
, Argument
[ArgumentIndex
], Status
);
423 // TODO: verify required
424 Status
= CsrSrvBootstrap ();