merge ROS Shell without integrated explorer part into trunk
[reactos.git] / posix / server / ob / session.c
1 /* $Id: session.c,v 1.4 2003/12/21 20:11:46 ea Exp $
2 *
3 * PROJECT : ReactOS / POSIX+ Environment Subsystem Server
4 * FILE : reactos/subsys/psx/server/ob/session.c
5 * DESCRIPTION: terminal
6 * DATE : 2002-04-04
7 * AUTHOR : Emanuele Aliberti <eal@users.sf.net>
8 *
9 * --------------------------------------------------------------------
10 *
11 * This software is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; either version 2 of the
14 * License, or (at your option) any later version.
15 *
16 * This software is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this software; see the file COPYING. If not, write
23 * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
24 * MA 02139, USA.
25 *
26 * --------------------------------------------------------------------
27 */
28 #include <psxss.h>
29
30 #define LOCK_ALL_SESSIONS RtlEnterCriticalSection(& Sessions.Lock)
31 #define UNLOCK_ALL_SESSIONS RtlLeaveCriticalSection(& Sessions.Lock)
32 #define LOCK_THIS_SESSION RtlEnterCriticalSection(& Session->Lock)
33 #define UNLOCK_THIS_SESSION RtlLeaveCriticalSection(& Session->Lock)
34
35
36 /* A double-linked list for the PSX_SESSION instances */
37
38 static struct
39 {
40 ULONG NextFreeId;
41 LONG Count;
42 PPSX_SESSION List;
43 CRITICAL_SECTION Lock;
44
45 } Sessions;
46
47 /**** FUNCTIONS ******************************************************/
48
49 /**********************************************************************
50 * PsxInitializeSessions/0
51 *
52 * DESCRIPTION
53 * Initialize the PSX session manager.
54 * ARGUMENTS
55 * None.
56 * RETURN VALUE
57 * None.
58 */
59 NTSTATUS STDCALL
60 PsxInitializeSessions (VOID)
61 {
62 debug_print (L"PSXSS: ->%s", __FUNCTION__);
63 /* Initalize the attributes */
64 Sessions.NextFreeId = 0;
65 Sessions.Count = 0;
66 Sessions.List = NULL;
67 RtlInitializeCriticalSection (& Sessions.Lock);
68 return STATUS_SUCCESS;
69 }
70 /**********************************************************************
71 * PsxCreateSessionObjects/1 PRIVATE
72 *
73 */
74 PRIVATE NTSTATUS STDCALL
75 PsxCreateSessionObjects (
76 IN PLPC_MAX_MESSAGE pRequest,
77 IN OUT PPSX_SESSION pSession
78 )
79 {
80 NTSTATUS Status;
81 OBJECT_ATTRIBUTES Oa;
82 WCHAR NameBuffer [NAME_BUFFER_SIZE];
83 UNICODE_STRING Name;
84 SECURITY_QUALITY_OF_SERVICE Sqos;
85 PSX_CONNECT_PORT_DATA ConnectData;
86 ULONG ConnectDataSize = sizeof ConnectData;
87
88 /* Port */
89 swprintf (
90 NameBuffer,
91 PSX_NS_SESSION_PORT_TEMPLATE,
92 PSX_NS_SUBSYSTEM_DIRECTORY_NAME,
93 PSX_NS_SESSION_DIRECTORY_NAME,
94 pRequest->Header.ClientId.UniqueProcess
95 );
96 debug_print (L"PSXSS: %s: %s", __FUNCTION__, NameBuffer);
97 RtlInitUnicodeString (& Name, NameBuffer);
98 InitializeObjectAttributes (& Oa, & Name, 0, NULL, NULL);
99 RtlZeroMemory (& Sqos, sizeof Sqos);
100 ConnectData.ConnectionType = PSX_CONNECTION_TYPE_SERVER;
101 ConnectData.Version = PSX_LPC_PROTOCOL_VERSION;
102 ConnectData.PortIdentifier = 0;
103 Status = NtConnectPort (
104 & pSession->TerminalChannel.hPort,
105 & Name,
106 & Sqos,
107 NULL,
108 NULL,
109 NULL,
110 (PVOID) & ConnectData,
111 & ConnectDataSize
112 );
113 if (!NT_SUCCESS(Status))
114 {
115 debug_print (L"PSXSS: %s: NtConnectPort failed with %08x\n", __FUNCTION__, Status);
116 return Status;
117 }
118 /* TODO: */
119 /* Section */
120 swprintf (
121 NameBuffer,
122 PSX_NS_SESSION_DATA_TEMPLATE,
123 PSX_NS_SUBSYSTEM_DIRECTORY_NAME,
124 PSX_NS_SESSION_DIRECTORY_NAME,
125 pRequest->Header.ClientId.UniqueProcess
126 );
127 debug_print (L"PSXSS: : %s", __FUNCTION__, NameBuffer);
128 RtlInitUnicodeString (& Name, NameBuffer);
129 InitializeObjectAttributes (& Oa, & Name, 0, 0, 0);
130 Status = NtOpenSection (
131 & pSession->TerminalChannel.Section.Handle,
132 SECTION_ALL_ACCESS, /* DesiredAccess */
133 & Oa
134 );
135 if (!NT_SUCCESS(Status))
136 {
137 NtClose (pSession->TerminalChannel.hPort);
138 debug_print (L"PSXSS: %s: NtOpenSection failed with %08x\n", __FUNCTION__, Status);
139 return Status;
140 }
141 pSession->TerminalChannel.Section.BaseAddress = NULL;
142 pSession->TerminalChannel.Section.ViewSize = PSX_TERMINAL_SECTION_SIZE;
143 Status = NtMapViewOfSection (
144 pSession->TerminalChannel.Section.Handle,
145 NtCurrentProcess(),
146 & pSession->TerminalChannel.Section.BaseAddress,
147 0, /* ZeroBits */
148 0, /* Commitsize */
149 0, /* SectionOffset */
150 & pSession->TerminalChannel.Section.ViewSize,
151 ViewUnmap,
152 0, /* AllocationType */
153 PAGE_READWRITE /* Protect 4 */
154 );
155 if (!NT_SUCCESS(Status))
156 {
157 NtClose (pSession->TerminalChannel.hPort);
158 NtClose (pSession->TerminalChannel.Section.Handle);
159 debug_print (L"PSXSS: %s: NtMapViewOfSection failed with %08x\n", __FUNCTION__, Status);
160 return Status;
161 }
162 return Status;
163 }
164 /**********************************************************************
165 * PsxCreateSession/3
166 *
167 * DESCRIPTION
168 * Create a new PSX_SESSION object and insert it in the
169 * PSX sessions table.
170 * ARGUMENTS
171 * MessageHeader
172 * Id
173 * RETURN VALUE
174 * A status value on error; otherwise STATUS_SUCCESS.
175 */
176 NTSTATUS STDCALL
177 PsxCreateSession (
178 IN PLPC_MAX_MESSAGE pRequest,
179 IN HANDLE hConnectedPort,
180 IN ULONG ulPortIdentifier
181 )
182 {
183 PPSX_SESSION Session = NULL;
184
185 debug_print (L"PSXSS: ->%s", __FUNCTION__);
186 /* Create the PSX_SESSION object */
187 Session = RtlAllocateHeap (Server.Heap, 0, sizeof (PSX_SESSION));
188 if (NULL == Session)
189 {
190 debug_print (L"PSXSS: %s: failed to create a new session object", __FUNCTION__);
191 return STATUS_MEMORY_NOT_ALLOCATED;
192 }
193 RtlZeroMemory (Session, sizeof (PSX_SESSION));
194 /* Initialiaze the new PSX_SESSION object */
195 Session->SessionChannel.hPort = hConnectedPort;
196 Session->SessionChannel.ulPortIdentifier = ulPortIdentifier;
197 LOCK_ALL_SESSIONS;
198 Session->Id = Sessions.NextFreeId ++;
199 UNLOCK_ALL_SESSIONS;
200 Session->Status = SESSION_STATUS_INITIALIZATION;
201 Session->Heap =
202 RtlCreateHeap (
203 HEAP_GROWABLE,
204 NULL,
205 65536,
206 65536,
207 NULL,
208 NULL
209 );
210 if (INVALID_HANDLE_VALUE == Session->Heap)
211 {
212 RtlFreeHeap (Server.Heap, 0, Session);
213 debug_print (L"PSX: %s: failed to create a new heap for session # %d", __FUNCTION__, Session->Id);
214 return STATUS_MEMORY_NOT_ALLOCATED;
215 }
216 RtlInitializeCriticalSection (& Session->Lock);
217 /* TODO: open the terminal's shared section */
218 /* TODO: connect to the terminal's port */
219 /* Inset the new PSX_SESSION object in the sessions table */
220 LOCK_ALL_SESSIONS;
221 if (NULL == Sessions.List)
222 {
223 Sessions.List = Session;
224 Session->Previous = Session;
225 }
226 Session->Next = Sessions.List; /* Last one points to the top one */
227 Session->Previous = Sessions.List->Previous;
228 Sessions.List->Previous = Session; /* Top one now points to the new one (tail) */
229 ++ Sessions.Count;
230 UNLOCK_ALL_SESSIONS;
231 /* DONE */
232 debug_print (L"%s: session # %d created", __FUNCTION__, Session->Id);
233 Session->Status = SESSION_STATUS_READY;
234 return STATUS_SUCCESS;
235 }
236 /**********************************************************************
237 * PsxTerminateSession/1
238 *
239 * DESCRIPTION
240 * Remove a PSX_SESSION object from the PSX sessions table and
241 * destroy it.
242 *
243 * ARGUMENTS
244 *
245 * RETURN VALUE
246 * A status value on error; otherwise STATUS_SUCCESS.
247 */
248 NTSTATUS STDCALL
249 PsxTerminateSession (
250 IN PPSX_SESSION Session
251 )
252 {
253 LONG Id;
254 PPSX_SESSION Previous = NULL;
255 PPSX_SESSION Next = NULL;
256
257 /* Release any resource managed by the session */
258 RtlDestroyHeap (Session->Heap);
259 /* Remove the session object from the sessions table */
260 LOCK_ALL_SESSIONS;
261 Id = Session->Id;
262 Previous = Session->Previous;
263 Next = Session->Next;
264 /* TODO: handle the case of no session left */
265 Next->Previous = Previous;
266 Previous->Next = Next;
267 -- Sessions.Count;
268 UNLOCK_ALL_SESSIONS;
269 /* Delete the old PSX_SESSION object */
270 RtlFreeHeap (Server.Heap, 0, Session);
271 /* DONE */
272 debug_print(L"PSX: session # %d deleted", Id);
273 return STATUS_SUCCESS;
274 }
275
276 NTSTATUS STDCALL
277 PsxWriteTerminalSession (
278 IN PPSX_SESSION Session,
279 IN PVOID Buffer,
280 IN ULONG Size,
281 IN OUT PULONG Written
282 )
283 {
284 LOCK_THIS_SESSION;
285 /* TODO: lock this session's section for writing */
286 /* TODO: copy the data in this session's section */
287 /* TODO: request a WRITE operation to the session terminal */
288 /* TODO: unlock this session's section */
289 UNLOCK_THIS_SESSION;
290 }
291
292 NTSTATUS STDCALL
293 PsxReadTerminalSession (
294 IN PPSX_SESSION Session,
295 OUT PVOID Buffer,
296 IN ULONG Size,
297 IN OUT PULONG Read
298 )
299 {
300 LOCK_THIS_SESSION;
301 /* TODO: lock this session's section for reading */
302 /* TODO: request a READ operation to the session terminal */
303 /* TODO: copy the data from this session's section */
304 /* TODO: unlock this session's section */
305 UNLOCK_THIS_SESSION;
306 }
307 /* EOF */