1 /* $Id: connect.c,v 1.4 2001/01/29 00:13:21 ea Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/lpc/connect.c
6 * PURPOSE: Communication mechanism
7 * PROGRAMMER: David Welch (welch@cwcom.net)
12 /* INCLUDES *****************************************************************/
14 #include <ddk/ntddk.h>
15 #include <internal/ob.h>
16 #include <internal/port.h>
17 #include <internal/dbg.h>
20 #include <internal/debug.h>
23 /**********************************************************************
28 * Connect to a named port and wait for the other side to
29 * accept the connection.
39 * UserConnectInfoLength
45 NtConnectPort (PHANDLE ConnectedPort
,
46 PUNICODE_STRING PortName
,
47 PSECURITY_QUALITY_OF_SERVICE Qos
,
48 PLPC_SECTION_WRITE WriteMap
,
49 PLPC_SECTION_READ ReadMap
,
50 PULONG MaxMessageSize
,
52 PULONG UserConnectInfoLength
)
60 ULONG ConnectInfoLength
;
63 DPRINT("PortName %x\n", PortName
);
64 DPRINT("NtConnectPort(PortName %S)\n", PortName
->Buffer
);
67 * Copy in user parameters
69 memcpy (&ConnectInfoLength
, UserConnectInfoLength
,
70 sizeof (*UserConnectInfoLength
));
73 * Get access to the port
75 Status
= ObReferenceObjectByName (PortName
,
78 PORT_ALL_ACCESS
, /* DesiredAccess */
83 if (!NT_SUCCESS(Status
))
85 DPRINT("Failed to reference named port (status %x)\n", Status
);
89 * Create a port to represent our side of the connection
91 OurPort
= ObCreateObject (&OurPortHandle
,
95 NiInitializePort(OurPort
);
97 * Create a request message
99 DPRINT("Creating request message\n");
101 Request
= ExAllocatePool (NonPagedPool
,
102 (sizeof (LPC_MESSAGE
) + ConnectInfoLength
));
104 Request
->DataSize
= ConnectInfoLength
;
105 Request
->MessageSize
= sizeof(LPC_MESSAGE
) + ConnectInfoLength
;
106 Request
->SharedSectionSize
= 0;
107 if ((ConnectInfo
!= NULL
) && (ConnectInfoLength
> 0))
109 memcpy ((PVOID
) (Request
+ 1), ConnectInfo
, ConnectInfoLength
);
112 * Queue the message to the named port
114 DPRINT("Queuing message\n");
116 EiReplyOrRequestPort (NamedPort
,
118 LPC_CONNECTION_REQUEST
,
120 KeSetEvent (&NamedPort
->Event
, IO_NO_INCREMENT
, FALSE
);
122 DPRINT("Waiting for connection completion\n");
125 * Wait for them to accept our connection
127 KeWaitForSingleObject (&OurPort
->Event
,
133 DPRINT("Received connection completion\n");
134 KeAcquireSpinLock (&OurPort
->Lock
, &oldIrql
);
135 Reply
= EiDequeueMessagePort (OurPort
);
136 KeReleaseSpinLock (&OurPort
->Lock
, oldIrql
);
137 memcpy (ConnectInfo
, Reply
->MessageData
, Reply
->Message
.DataSize
);
138 *UserConnectInfoLength
= Reply
->Message
.DataSize
;
140 if (Reply
->Message
.MessageType
== LPC_CONNECTION_REFUSED
)
142 ObDereferenceObject (NamedPort
);
143 ObDereferenceObject (OurPort
);
144 ZwClose (OurPortHandle
);
145 ExFreePool (Request
);
147 return (STATUS_UNSUCCESSFUL
);
150 OurPort
->State
= EPORT_CONNECTED_CLIENT
;
151 *ConnectedPort
= OurPortHandle
;
153 ExFreePool (Request
);
155 DPRINT("Exited successfully\n");
157 return (STATUS_SUCCESS
);
161 /**********************************************************************
163 * NtAcceptConnectPort@24
178 EXPORTED NTSTATUS STDCALL
179 NtAcceptConnectPort (PHANDLE ServerPortHandle
,
180 HANDLE NamedPortHandle
,
181 PLPC_MESSAGE LpcMessage
,
183 PLPC_SECTION_WRITE WriteMap
,
184 PLPC_SECTION_READ ReadMap
)
188 PEPORT OurPort
= NULL
;
189 PQUEUEDMESSAGE ConnectionRequest
;
192 Status
= ObReferenceObjectByHandle (NamedPortHandle
,
198 if (!NT_SUCCESS(Status
))
203 * Create a port object for our side of the connection
207 OurPort
= ObCreateObject (ServerPortHandle
,
211 NiInitializePort(OurPort
);
214 * Dequeue the connection request
216 KeAcquireSpinLock (&NamedPort
->Lock
, & oldIrql
);
217 ConnectionRequest
= EiDequeueConnectMessagePort (NamedPort
);
218 KeReleaseSpinLock (&NamedPort
->Lock
, oldIrql
);
222 EiReplyOrRequestPort (ConnectionRequest
->Sender
,
224 LPC_CONNECTION_REFUSED
,
226 KeSetEvent (&ConnectionRequest
->Sender
->Event
,
229 ObDereferenceObject (ConnectionRequest
->Sender
);
230 ExFreePool (ConnectionRequest
);
231 ObDereferenceObject (NamedPort
);
232 return (STATUS_SUCCESS
);
235 * Connect the two ports
237 OurPort
->OtherPort
= ConnectionRequest
->Sender
;
238 OurPort
->OtherPort
->OtherPort
= OurPort
;
239 EiReplyOrRequestPort (ConnectionRequest
->Sender
,
243 ExFreePool (ConnectionRequest
);
245 ObDereferenceObject (OurPort
);
246 ObDereferenceObject (NamedPort
);
248 return (STATUS_SUCCESS
);
251 /**********************************************************************
253 * NtSecureConnectPort@36
256 * Connect to a named port and wait for the other side to
257 * accept the connection. Possibly verify that the server
258 * matches the ServerSid (trusted server).
270 * UserConnectInfoLength
276 NtSecureConnectPort (OUT PHANDLE ConnectedPort
,
277 IN PUNICODE_STRING PortName
,
278 IN PSECURITY_QUALITY_OF_SERVICE Qos
,
279 IN OUT PLPC_SECTION_WRITE WriteMap OPTIONAL
,
280 IN PSID ServerSid OPTIONAL
,
281 IN OUT PLPC_SECTION_READ ReadMap OPTIONAL
,
282 OUT PULONG MaxMessageSize OPTIONAL
,
283 IN OUT PVOID ConnectInfo OPTIONAL
,
284 IN OUT PULONG UserConnectInfoLength OPTIONAL
)
286 return (STATUS_NOT_IMPLEMENTED
);