SM/CSR: move win32k.sys loading from the SM to the Win32 user mode server.
[reactos.git] / reactos / subsys / smss / initss.c
1 /* $Id$
2 *
3 * initss.c - Load the subsystems
4 *
5 * ReactOS Operating System
6 *
7 * --------------------------------------------------------------------
8 *
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.
13 *
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 * General Public License for more details.
18 *
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,
22 * MA 02139, USA.
23 *
24 * --------------------------------------------------------------------
25 */
26
27
28 #include "smss.h"
29
30 #include <rosrtl/string.h>
31
32 #define NDEBUG
33 #include <debug.h>
34
35 /* SM handle for its own \SmApiPort */
36 HANDLE hSmApiPort = (HANDLE) 0;
37
38
39 /* TODO:
40 *
41 * a) look if a special option is set for smss.exe in
42 * HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
43 */
44
45 /**********************************************************************
46 * SmpRegisterSmss/0
47 *
48 * DESCRIPTION
49 * Make smss register with itself for IMAGE_SUBSYSTEM_NATIVE
50 * (programmatically). This also opens hSmApiPort to be used
51 * in loading required subsystems.
52 */
53
54 static NTSTATUS
55 SmpRegisterSmss(VOID)
56 {
57 NTSTATUS Status = STATUS_SUCCESS;
58 RTL_PROCESS_INFO ProcessInfo;
59
60
61 DPRINT("SM: %s called\n",__FUNCTION__);
62
63 RtlZeroMemory (& ProcessInfo, sizeof ProcessInfo);
64 ProcessInfo.Size = sizeof ProcessInfo;
65 ProcessInfo.ProcessHandle = (HANDLE) SmSsProcessId;
66 ProcessInfo.ClientId.UniqueProcess = (HANDLE) SmSsProcessId;
67 DPRINT("SM: %s: ProcessInfo.ProcessHandle=%lx\n",
68 __FUNCTION__,ProcessInfo.ProcessHandle);
69 Status = SmCreateClient (& ProcessInfo, L"Session Manager");
70 if (NT_SUCCESS(Status))
71 {
72 UNICODE_STRING SbApiPortName = {0,0,NULL};
73
74 RtlInitUnicodeString (& SbApiPortName, L"");
75 Status = SmConnectApiPort(& SbApiPortName,
76 (HANDLE) -1, /* SM has no SB port */
77 IMAGE_SUBSYSTEM_NATIVE,
78 & hSmApiPort);
79 if(!NT_SUCCESS(Status))
80 {
81 DPRINT("SM: %s: SMLIB!SmConnectApiPort failed (Status=0x%08lx)\n",
82 __FUNCTION__,Status);
83 return Status;
84 }
85 DPRINT("SM self registered\n");
86 }
87 else
88 {
89 DPRINT1("SM: %s: SmCreateClient failed (Status=0x%08lx)\n",
90 __FUNCTION__, Status);
91 }
92 /*
93 * Note that you don't need to call complete session
94 * because connection handling code autocompletes
95 * the client structure for IMAGE_SUBSYSTEM_NATIVE.
96 */
97 return Status;
98 }
99
100
101 /**********************************************************************
102 * SmpLoadRequiredSubsystems/0
103 */
104 static NTSTATUS
105 SmpLoadRequiredSubsystems (VOID)
106 {
107 NTSTATUS Status = STATUS_SUCCESS;
108 WCHAR Data [MAX_PATH + 1];
109 ULONG DataLength = sizeof Data;
110 ULONG DataType = 0;
111
112
113 DPRINT("SM: %s called\n", __FUNCTION__);
114
115 RtlZeroMemory (Data, DataLength);
116 Status = SmLookupSubsystem (L"Required",
117 Data,
118 & DataLength,
119 & DataType,
120 NULL);
121 if((STATUS_SUCCESS == Status) && (DataLength > sizeof Data[0]))
122 {
123 PWCHAR Name = NULL;
124 ULONG Offset = 0;
125
126 for (Name = Data; (Offset < DataLength); )
127 {
128 if(L'\0' != *Name)
129 {
130 UNICODE_STRING Program;
131
132 /* Run the current program */
133 RtlInitUnicodeString (& Program, Name);
134 Status = SmExecuteProgram (hSmApiPort, & Program);
135 if(!NT_SUCCESS(Status))
136 {
137 DPRINT1("SM: %s failed to run '%S' program (Status=0x%08lx)\n",
138 __FUNCTION__, Name, Status);
139 }
140 /* Look for the next program */
141 while ((L'\0' != *Name) && (Offset < DataLength))
142 {
143 ++ Name;
144 ++ Offset;
145 }
146 }
147 ++ Name;
148 ++ Offset;
149 }
150 }
151
152 return Status;
153 }
154
155 /**********************************************************************
156 * SmLoadSubsystems/0
157 */
158 NTSTATUS
159 SmLoadSubsystems(VOID)
160 {
161 NTSTATUS Status = STATUS_SUCCESS;
162
163
164 DPRINT("SM: loading subsystems\n");
165
166 /* SM self registers */
167 Status = SmpRegisterSmss();
168 if(!NT_SUCCESS(Status)) return Status;
169 /* Load Required subsystems (Debug Windows) */
170 Status = SmpLoadRequiredSubsystems();
171 if(!NT_SUCCESS(Status)) return Status;
172 /* done */
173 return Status;
174 }
175
176 /* EOF */