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