Win32 utility to bootstrap the PSX subsystem (it is an optional subsystem, therefore...
[reactos.git] / posix / server / misc / init.c
1 /* $Id: init.c,v 1.3 2002/10/29 04:45:54 rex Exp $
2 *
3 * PROJECT : ReactOS / POSIX+ Environment Subsystem Server
4 * FILE : reactos/subsys/psx/server/srv/init.c
5 * DESCRIPTION: POSIX+ server initialization.
6 * DATE : 2001-05-05
7 * AUTHOR : Emanuele Aliberti <eal@users.sf.net>
8 *
9 * --------------------------------------------------------------------
10 *
11 * This software is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; either version 2 of the
14 * License, or (at your option) any later version.
15 *
16 * This software is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this software; see the file COPYING. If not, write
23 * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
24 * MA 02139, USA.
25 *
26 * --------------------------------------------------------------------
27 */
28 #include <psxss.h>
29 #include <napi/teb.h>
30
31 #ifdef __PSXSS_ON_W32__
32 #include <windows.h>
33 #endif
34
35 /*** GLOBALS *********************************************************/
36
37 SERVER Server =
38 {
39 /* .Heap */
40 INVALID_HANDLE_VALUE,
41 /* .Directory */
42 {
43 { INVALID_HANDLE_VALUE,
44 L"\\"PSX_NS_SUBSYSTEM_DIRECTORY_NAME,
45 {0,0,NULL}
46 },
47 { INVALID_HANDLE_VALUE,
48 L"\\"PSX_NS_SUBSYSTEM_DIRECTORY_NAME"\\"PSX_NS_SESSION_DIRECTORY_NAME,
49 {0,0,NULL}
50 },
51 { INVALID_HANDLE_VALUE,
52 L"\\"PSX_NS_SUBSYSTEM_DIRECTORY_NAME"\\"PSX_NS_SYSTEM_DIRECTORY_NAME,
53 {0,0,NULL}
54 },
55 },
56 /* .Port */
57 {
58 { INVALID_HANDLE_VALUE,
59 L"\\"PSX_NS_SUBSYSTEM_DIRECTORY_NAME"\\"PSX_NS_API_PORT_NAME,
60 {0,0,NULL},
61 ApiPortListener
62 },
63 { INVALID_HANDLE_VALUE,
64 L"\\"PSX_NS_SUBSYSTEM_DIRECTORY_NAME"\\"PSX_NS_SBAPI_PORT_NAME,
65 {0,0,NULL},
66 SbApiPortListener
67 },
68 { INVALID_HANDLE_VALUE,
69 L"\\"PSX_NS_SUBSYSTEM_DIRECTORY_NAME"\\"PSX_NS_SESSIONAPI_PORT_NAME,
70 {0,0,NULL},
71 SessionPortListener
72 }
73 }
74 };
75
76 /*** FUNCTIONS *******************************************************/
77
78 /**********************************************************************
79 * PdxInitializeHeap/0 PRIVATE
80 *
81 * DESCRIPTION
82 * Initialize the PSX server process' heap.
83 */
84 PRIVATE HANDLE STDCALL
85 PdxInitializeHeap (VOID)
86 {
87 return Server.Heap = (HANDLE)NtCurrentPeb()->ProcessHeap;
88 }
89 /**********************************************************************
90 * PdxCreateDirectory/1 PRIVATE
91 *
92 * DESCRIPTION
93 * Create a directory in the system name space.
94 */
95 PRIVATE NTSTATUS STDCALL
96 PdxCreateDirectory (
97 IN ULONG ulIndex
98 )
99 {
100 OBJECT_ATTRIBUTES ObjectAttributes;
101 NTSTATUS Status;
102
103 RtlCreateUnicodeString (
104 & Server.Directory[ulIndex].usName,
105 Server.Directory[ulIndex].wsName
106 );
107 InitializeObjectAttributes (
108 & ObjectAttributes,
109 & Server.Directory[ulIndex].usName,
110 0,
111 NULL,
112 NULL
113 );
114 Status = NtCreateDirectoryObject(
115 & Server.Directory[ulIndex].hObject,
116 DIRECTORY_ALL_ACCESS,
117 & ObjectAttributes
118 );
119 if (!NT_SUCCESS(Status))
120 {
121 debug_print(
122 L"PSXSS: %s directory creation failed (Status = %08x)",
123 Server.Directory[ulIndex].wsName,
124 Status
125 );
126
127 }
128 return Status;
129 }
130 /**********************************************************************
131 * PdxInitializeDirectories/0 PRIVATE
132 *
133 * DESCRIPTION
134 * Create the directories used by the POSIX+ subsystem
135 * components in the system name space.
136 */
137 PRIVATE NTSTATUS STDCALL
138 PdxInitializeDirectories (VOID)
139 {
140 NTSTATUS Status;
141 ULONG ulIndex;
142
143 for ( ulIndex = 0;
144 (ulIndex < (sizeof Server.Directory / sizeof Server.Directory[0]));
145 ulIndex ++)
146 {
147 Status = PdxCreateDirectory (ulIndex);
148 if (!NT_SUCCESS(Status)) return Status;
149 }
150 return STATUS_SUCCESS;
151 }
152 /**********************************************************************
153 * PdxInitializeListener/1 PRIVATE
154 *
155 * DESCRIPTION
156 * Initialize a thread to make an LPC port listen.
157 */
158 PRIVATE NTSTATUS STDCALL
159 PdxInitializeListener (ULONG ulIndex)
160 {
161 NTSTATUS Status;
162 OBJECT_ATTRIBUTES Oa;
163 ULONG ulThreadIndex;
164
165 RtlInitUnicodeString (
166 & Server.Port[ulIndex].usName,
167 Server.Port[ulIndex].wsName
168 );
169 InitializeObjectAttributes(
170 & Oa,
171 & Server.Port[ulIndex].usName,
172 0,
173 NULL,
174 NULL
175 );
176 /* Create the listening LPC port */
177 Status = NtCreatePort (
178 & Server.Port[ulIndex].hObject,
179 & Oa,
180 260,
181 328,
182 0
183 );
184 if (!NT_SUCCESS(Status))
185 {
186 debug_print(
187 L"PSXSS: Unable to create port \"%s\": Status %08x\n",
188 Server.Port[ulIndex].wsName,
189 Status);
190 return Status;
191 }
192 /*
193 * Create the server thread that will process
194 * messages sent to this port.
195 */
196 for ( ulThreadIndex = 0;
197 (ulThreadIndex < PSXSS_THREADS_PER_PORT);
198 ulThreadIndex ++
199 )
200 {
201 #ifdef __PSXSS_ON_W32__
202 Server.Port[ulIndex].ThreadInfo[ulThreadIndex].hObject =
203 CreateThread (
204 NULL,
205 0,
206 (PTHREAD_START_ROUTINE) Server.Port[ulIndex].EntryPoint,
207 (PVOID) ulIndex,
208 CREATE_SUSPENDED,
209 & Server.Port[ulIndex].ThreadInfo[ulThreadIndex].Id
210 );
211 if (NULL == Server.Port[ulIndex].ThreadInfo[ulThreadIndex].hObject)
212 #else
213 if (!NT_SUCCESS(Status))
214 #endif
215 {
216 debug_print(
217 L"PSXSS: Unable to create a server thread for port \"%s\": Status %08x\n",
218 Server.Port[ulIndex].wsName,
219 Status
220 );
221 NtClose (Server.Port[ulIndex].hObject);
222 return Status;
223 }
224 }
225 return STATUS_SUCCESS;
226 }
227 /**********************************************************************
228 * PsxInitializeListeners/0 PRIVATE
229 *
230 * DESCRIPTION
231 * Initialize the LPC ports and associate threads.
232 */
233 PRIVATE NTSTATUS STDCALL
234 PdxInitializeListeners (VOID)
235 {
236 NTSTATUS Status;
237 ULONG ulIndex;
238
239 for ( ulIndex = 0;
240 (ulIndex < (sizeof Server.Port / sizeof Server.Port[0]));
241 ulIndex ++)
242 {
243 Status = PdxInitializeListener (ulIndex);
244 if (!NT_SUCCESS(Status)) return Status;
245 }
246 return STATUS_SUCCESS;
247 }
248 /**********************************************************************
249 * PdxRunServer/0 PRIVATE
250 *
251 * DESCRIPTION
252 * Wake up all suspended threads.
253 */
254 PRIVATE NTSTATUS STDCALL
255 PdxRunServer (VOID)
256 {
257 NTSTATUS Status;
258 ULONG ulIndex;
259 ULONG ulThreadIndex;
260
261 for ( ulIndex = 0;
262 (ulIndex < (sizeof Server.Port / sizeof Server.Port[0]));
263 ulIndex ++)
264 {
265 for (ulThreadIndex = 0;
266 (ulThreadIndex < PSXSS_THREADS_PER_PORT);
267 ulThreadIndex ++
268 )
269 {
270 #ifdef __PSXSS_ON_W32__
271 if (0xFFFFFFFF == ResumeThread (Server.Port[ulIndex].ThreadInfo[ulThreadIndex].hObject))
272 #else
273 Status = NtResumeThread (Server.Port[ulIndex].ThreadInfo[ulThreadIndex].hObject, NULL);
274 if (!NT_SUCCESS(Status))
275 #endif
276 {
277 debug_print(
278 L"PSXSS: "__FUNCTION__": NtResumeThread failed with Status = %08x",
279 Status
280 );
281 return Status;
282 }
283 }
284 }
285 return STATUS_SUCCESS;
286 }
287 /**********************************************************************
288 * PsxServerInitialization/2
289 *
290 * DESCRIPTION
291 * Initialize the PSX server process.
292 */
293 NTSTATUS STDCALL
294 PsxServerInitialization (
295 IN ULONG ArgumentCount,
296 IN PWSTR *ArgumentArray
297 )
298 {
299 NTSTATUS Status;
300
301 /* Get our heap */
302 PdxInitializeHeap ();
303 /* Initialize POSIX+ and Sessions */
304 Status = PdxInitializeDirectories ();
305 if (!NT_SUCCESS(Status)) return Status;
306 /* LPCs dispatchers */
307 Status = PdxInitializeListeners ();
308 if (!NT_SUCCESS(Status)) return Status;
309 /* Terminal manager */
310 Status = PsxInitializeSessions ();
311 if (!NT_SUCCESS(Status)) return Status;
312 /* Process manager */
313 Status = PsxInitializeProcesses ();
314 if (!NT_SUCCESS(Status)) return Status;
315 /* OK. Run! */
316 Status = PdxRunServer ();
317 /* Done */
318 return Status;
319 }
320 /* EOF */