Copy makefile
[reactos.git] / reactos / subsys / smss / client.c
1 /* $Id: smss.c 12852 2005-01-06 13:58:04Z mf $
2 *
3 * client.c - Session Manager client Management
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 #define NTOS_MODE_USER
27 #include <ntos.h>
28 #include "smss.h"
29 #include <sm/helper.h>
30
31 #define NDEBUG
32 #include <debug.h>
33
34 /* Private ADT */
35
36
37 struct _SM_CLIENT_DIRECTORY
38 {
39 RTL_CRITICAL_SECTION Lock;
40 ULONG Count;
41 PSM_CLIENT_DATA Client;
42
43 } SmpClientDirectory;
44
45 #if 0
46 /**********************************************************************
47 * SmpRegisterSmss/0
48 */
49 static NTSTATUS
50 SmpRegisterSmss(VOID)
51 {
52 NTSTATUS Status = STATUS_SUCCESS;
53 UNICODE_STRING SbApiPortName = {0,0,NULL};
54 HANDLE hSmApiPort = (HANDLE) 0;
55
56 DPRINT("SM: %s called\n",__FUNCTION__);
57
58 Status = SmConnectApiPort(& SbApiPortName,
59 (HANDLE) -1,
60 IMAGE_SUBSYSTEM_NATIVE,
61 & hSmApiPort);
62 if(!NT_SUCCESS(Status))
63 {
64 DPRINT("SM: %s: SMDLL!SmConnectApiPort failed (Status=0x%08lx)\n",__FUNCTION__,Status);
65 return Status;
66 }
67 Status = SmCompleteSession (hSmApiPort, (HANDLE)0, hSmApiPort);
68 if(!NT_SUCCESS(Status))
69 {
70 DPRINT("SM: %s: SMDLL!SmCompleteSession failed (Status=0x%08lx)\n",__FUNCTION__,Status);
71 return Status;
72 }
73 NtClose(hSmApiPort);
74 return Status;
75 }
76 #endif
77
78 /**********************************************************************
79 * SmInitializeClientManagement/0
80 */
81 NTSTATUS
82 SmInitializeClientManagement (VOID)
83 {
84 DPRINT("SM: %s called\n", __FUNCTION__);
85 RtlInitializeCriticalSection(& SmpClientDirectory.Lock);
86 SmpClientDirectory.Count = 0;
87 SmpClientDirectory.Client = NULL;
88 #if 0
89 /* Register IMAGE_SUBSYSTE_NATIVE to be managed by SM */
90 return SmpRegisterSmss();
91 #endif
92 return STATUS_SUCCESS;
93
94 }
95
96 /**********************************************************************
97 * SmpLookupClient/1
98 *
99 * DESCRIPTION
100 * Lookup the subsystem server descriptor given its image ID.
101 *
102 * SIDE EFFECTS
103 * SmpClientDirectory.Lock is released only on success.
104 */
105 static PSM_CLIENT_DATA STDCALL
106 SmpLookupClient (USHORT SubsystemId)
107 {
108 PSM_CLIENT_DATA Client = NULL;
109
110 DPRINT("SM: %s called\n", __FUNCTION__);
111
112 RtlEnterCriticalSection (& SmpClientDirectory.Lock);
113 if (SmpClientDirectory.Count > 0)
114 {
115 Client = SmpClientDirectory.Client;
116 while (NULL != Client)
117 {
118 if (SubsystemId == Client->SubsystemId)
119 {
120 RtlLeaveCriticalSection (& SmpClientDirectory.Lock);
121 return Client;
122 }
123 Client = Client->Next;
124 }
125 }
126 /*
127 * Note that we do *not* release SmpClientDirectory.Lock here
128 * because SmpLookupClient is called to FAIL when SubsystemId
129 * is not registered yet.
130 */
131 return Client;
132 }
133
134 /**********************************************************************
135 * SmpCreateClient/2
136 */
137 NTSTATUS STDCALL
138 SmCreateClient(PSM_PORT_MESSAGE Request, PSM_CLIENT_DATA * ClientData)
139 {
140 PSM_CLIENT_DATA pClient = NULL;
141 PSM_CONNECT_DATA ConnectData = (PSM_CONNECT_DATA) ((PBYTE) Request) + sizeof (LPC_REQUEST);
142 ULONG SbApiPortNameSize = SM_CONNECT_DATA_SIZE(*Request);
143
144 DPRINT("SM: %s called\n", __FUNCTION__);
145
146 /*
147 * Check if a client for the ID already exist.
148 */
149 if (SmpLookupClient(ConnectData->Subsystem))
150 {
151 DPRINT("SMSS: %s: attempt to register again subsystem %d.\n",
152 __FUNCTION__,
153 ConnectData->Subsystem);
154 return STATUS_UNSUCCESSFUL;
155 }
156 DPRINT("SM: %s: registering subsystem %d \n", __FUNCTION__, ConnectData->Subsystem);
157 /*
158 * Allocate the storage for client data
159 */
160 pClient = RtlAllocateHeap (SmpHeap,
161 HEAP_ZERO_MEMORY,
162 sizeof (SM_CLIENT_DATA));
163 if (NULL == pClient)
164 {
165 DPRINT("SM: %s: out of memory!\n",__FUNCTION__);
166 return STATUS_NO_MEMORY;
167 }
168 /*
169 * Initialize the client data
170 */
171 pClient->SubsystemId = ConnectData->Subsystem;
172 /* SM auto-initializes; other subsystems are required to call
173 * SM_API_COMPLETE_SESSION via SMDLL. */
174 pClient->Initialized = (IMAGE_SUBSYSTEM_NATIVE == pClient->SubsystemId);
175 if (SbApiPortNameSize > 0)
176 {
177 RtlCopyMemory (pClient->SbApiPortName,
178 ConnectData->SbName,
179 SbApiPortNameSize);
180 }
181 /*
182 * Insert the new descriptor in the
183 * client directory.
184 */
185 if (NULL == SmpClientDirectory.Client)
186 {
187 SmpClientDirectory.Client = pClient;
188 } else {
189 PSM_CLIENT_DATA pCD = NULL;
190
191 for (pCD=SmpClientDirectory.Client;
192 (NULL != pCD->Next);
193 pCD = pCD->Next);
194 pCD->Next = pClient;
195 }
196 pClient->Next = NULL;
197 ++ SmpClientDirectory.Count;
198 /*
199 * Note we unlock the client directory here, because
200 * it was locked by SmpLookupClient on failure.
201 */
202 RtlLeaveCriticalSection (& SmpClientDirectory.Lock);
203 if (ClientData)
204 {
205 *ClientData = pClient;
206 }
207 return STATUS_SUCCESS;
208 }
209
210 /**********************************************************************
211 * SmpDestroyClient/1
212 */
213 NTSTATUS STDCALL
214 SmDestroyClient (ULONG SubsystemId)
215 {
216 DPRINT("SM: %s called\n", __FUNCTION__);
217
218 RtlEnterCriticalSection (& SmpClientDirectory.Lock);
219 /* TODO */
220 RtlLeaveCriticalSection (& SmpClientDirectory.Lock);
221 return STATUS_SUCCESS;
222 }
223
224 /* EOF */