1 /* $Id: smss.c 12852 2005-01-06 13:58:04Z mf $
3 * client.c - Session Manager client Management
5 * ReactOS Operating System
7 * --------------------------------------------------------------------
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.
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.
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,
24 * --------------------------------------------------------------------
26 #define NTOS_MODE_USER
29 #include <sm/helper.h>
37 struct _SM_CLIENT_DIRECTORY
39 RTL_CRITICAL_SECTION Lock
;
41 PSM_CLIENT_DATA Client
;
46 /**********************************************************************
52 NTSTATUS Status
= STATUS_SUCCESS
;
53 UNICODE_STRING SbApiPortName
= {0,0,NULL
};
54 HANDLE hSmApiPort
= (HANDLE
) 0;
56 DPRINT("SM: %s called\n",__FUNCTION__
);
58 Status
= SmConnectApiPort(& SbApiPortName
,
60 IMAGE_SUBSYSTEM_NATIVE
,
62 if(!NT_SUCCESS(Status
))
64 DPRINT("SM: %s: SMDLL!SmConnectApiPort failed (Status=0x%08lx)\n",__FUNCTION__
,Status
);
67 Status
= SmCompleteSession (hSmApiPort
, (HANDLE
)0, hSmApiPort
);
68 if(!NT_SUCCESS(Status
))
70 DPRINT("SM: %s: SMDLL!SmCompleteSession failed (Status=0x%08lx)\n",__FUNCTION__
,Status
);
78 /**********************************************************************
79 * SmInitializeClientManagement/0
82 SmInitializeClientManagement (VOID
)
84 DPRINT("SM: %s called\n", __FUNCTION__
);
85 RtlInitializeCriticalSection(& SmpClientDirectory
.Lock
);
86 SmpClientDirectory
.Count
= 0;
87 SmpClientDirectory
.Client
= NULL
;
89 /* Register IMAGE_SUBSYSTE_NATIVE to be managed by SM */
90 return SmpRegisterSmss();
92 return STATUS_SUCCESS
;
96 /**********************************************************************
100 * Lookup the subsystem server descriptor given its image ID.
103 * SmpClientDirectory.Lock is released only on success.
105 static PSM_CLIENT_DATA STDCALL
106 SmpLookupClient (USHORT SubsystemId
)
108 PSM_CLIENT_DATA Client
= NULL
;
110 DPRINT("SM: %s called\n", __FUNCTION__
);
112 RtlEnterCriticalSection (& SmpClientDirectory
.Lock
);
113 if (SmpClientDirectory
.Count
> 0)
115 Client
= SmpClientDirectory
.Client
;
116 while (NULL
!= Client
)
118 if (SubsystemId
== Client
->SubsystemId
)
120 RtlLeaveCriticalSection (& SmpClientDirectory
.Lock
);
123 Client
= Client
->Next
;
127 * Note that we do *not* release SmpClientDirectory.Lock here
128 * because SmpLookupClient is called to FAIL when SubsystemId
129 * is not registered yet.
134 /**********************************************************************
138 SmCreateClient(PSM_PORT_MESSAGE Request
, PSM_CLIENT_DATA
* ClientData
)
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
);
144 DPRINT("SM: %s called\n", __FUNCTION__
);
147 * Check if a client for the ID already exist.
149 if (SmpLookupClient(ConnectData
->Subsystem
))
151 DPRINT("SMSS: %s: attempt to register again subsystem %d.\n",
153 ConnectData
->Subsystem
);
154 return STATUS_UNSUCCESSFUL
;
156 DPRINT("SM: %s: registering subsystem %d \n", __FUNCTION__
, ConnectData
->Subsystem
);
158 * Allocate the storage for client data
160 pClient
= RtlAllocateHeap (SmpHeap
,
162 sizeof (SM_CLIENT_DATA
));
165 DPRINT("SM: %s: out of memory!\n",__FUNCTION__
);
166 return STATUS_NO_MEMORY
;
169 * Initialize the client data
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)
177 RtlCopyMemory (pClient
->SbApiPortName
,
182 * Insert the new descriptor in the
185 if (NULL
== SmpClientDirectory
.Client
)
187 SmpClientDirectory
.Client
= pClient
;
189 PSM_CLIENT_DATA pCD
= NULL
;
191 for (pCD
=SmpClientDirectory
.Client
;
196 pClient
->Next
= NULL
;
197 ++ SmpClientDirectory
.Count
;
199 * Note we unlock the client directory here, because
200 * it was locked by SmpLookupClient on failure.
202 RtlLeaveCriticalSection (& SmpClientDirectory
.Lock
);
205 *ClientData
= pClient
;
207 return STATUS_SUCCESS
;
210 /**********************************************************************
214 SmDestroyClient (ULONG SubsystemId
)
216 DPRINT("SM: %s called\n", __FUNCTION__
);
218 RtlEnterCriticalSection (& SmpClientDirectory
.Lock
);
220 RtlLeaveCriticalSection (& SmpClientDirectory
.Lock
);
221 return STATUS_SUCCESS
;