updated an absolete comment
[reactos.git] / reactos / subsys / smss / initss.c
1 /* $Id: init.c 13449 2005-02-06 21:55:07Z ea $
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 UNICODE_STRING SbApiPortName = {0,0,NULL};
59
60
61 DPRINT("SM: %s called\n",__FUNCTION__);
62
63 RtlInitUnicodeString (& SbApiPortName, L"");
64 Status = SmConnectApiPort(& SbApiPortName,
65 (HANDLE) -1, /* SM has no SB port */
66 IMAGE_SUBSYSTEM_NATIVE,
67 & hSmApiPort);
68 if(!NT_SUCCESS(Status))
69 {
70 DPRINT("SM: %s: SMLIB!SmConnectApiPort failed (Status=0x%08lx)\n",
71 __FUNCTION__,Status);
72 return Status;
73 }
74 DPRINT("SM self registered\n");
75 /*
76 * Note that you don't need to call complete session
77 * because connection handling code autocompletes
78 * the client structure for IMAGE_SUBSYSTEM_NATIVE.
79 */
80 return Status;
81 }
82
83
84 /**********************************************************************
85 * SmpLoadKernelModeSubsystem/0
86 */
87 static NTSTATUS
88 SmpLoadKernelModeSubsystem (VOID)
89 {
90 NTSTATUS Status = STATUS_SUCCESS;
91 WCHAR Data [MAX_PATH + 1];
92 ULONG DataLength = sizeof Data;
93 ULONG DataType = 0;
94
95
96 DPRINT("SM: %s called\n", __FUNCTION__);
97
98 Status = SmLookupSubsystem (L"Kmode",
99 Data,
100 & DataLength,
101 & DataType,
102 TRUE);
103 if((STATUS_SUCCESS == Status) && (DataLength > sizeof Data[0]))
104 {
105 WCHAR ImagePath [MAX_PATH + 1] = {0};
106 SYSTEM_LOAD_AND_CALL_IMAGE ImageInfo;
107
108 wcscpy (ImagePath, L"\\??\\");
109 wcscat (ImagePath, Data);
110 RtlZeroMemory (& ImageInfo, sizeof ImageInfo);
111 RtlInitUnicodeString (& ImageInfo.ModuleName, ImagePath);
112 Status = NtSetSystemInformation(SystemLoadAndCallImage,
113 & ImageInfo,
114 sizeof ImageInfo);
115 if(!NT_SUCCESS(Status))
116 {
117 DPRINT("SM: %s: loading Kmode failed (Status=0x%08lx)\n",
118 __FUNCTION__, Status);
119 }
120 }
121 return Status;
122 }
123
124 /**********************************************************************
125 * SmpLoadRequiredSubsystems/0
126 */
127 static NTSTATUS
128 SmpLoadRequiredSubsystems (VOID)
129 {
130 NTSTATUS Status = STATUS_SUCCESS;
131 WCHAR Data [MAX_PATH + 1];
132 ULONG DataLength = sizeof Data;
133 ULONG DataType = 0;
134
135
136 DPRINT("SM: %s called\n", __FUNCTION__);
137
138 RtlZeroMemory (Data, DataLength);
139 Status = SmLookupSubsystem (L"Required",
140 Data,
141 & DataLength,
142 & DataType,
143 FALSE);
144 if((STATUS_SUCCESS == Status) && (DataLength > sizeof Data[0]))
145 {
146 PWCHAR Name = NULL;
147 ULONG Offset = 0;
148
149 for (Name = Data; (Offset < DataLength); )
150 {
151 if(L'\0' != *Name)
152 {
153 UNICODE_STRING Program;
154
155 /* Run the current program */
156 RtlInitUnicodeString (& Program, Name);
157 Status = SmExecuteProgram (hSmApiPort, & Program);
158 if(!NT_SUCCESS(Status))
159 {
160 DPRINT1("SM: %s failed to run '%S' program (Status=0x%08lx)\n",
161 __FUNCTION__, Name, Status);
162 }
163 /* Look for the next program */
164 while ((L'\0' != *Name) && (Offset < DataLength))
165 {
166 ++ Name;
167 ++ Offset;
168 }
169 }
170 ++ Name;
171 ++ Offset;
172 }
173 }
174
175 return Status;
176 }
177
178 /**********************************************************************
179 * SmLoadSubsystems/0
180 */
181 NTSTATUS
182 SmLoadSubsystems(VOID)
183 {
184 NTSTATUS Status = STATUS_SUCCESS;
185
186
187 DPRINT("SM: loading subsystems\n");
188
189 /* SM self registers */
190 Status = SmpRegisterSmss();
191 if(!NT_SUCCESS(Status)) return Status;
192 /* Load Kmode subsystem (aka win32k.sys) */
193 Status = SmpLoadKernelModeSubsystem();
194 if(!NT_SUCCESS(Status)) return Status;
195 /* Load Required subsystems (Debug Windows) */
196 Status = SmpLoadRequiredSubsystems();
197 if(!NT_SUCCESS(Status)) return Status;
198 /* done */
199 return Status;
200 }
201
202 /* EOF */