1 /* $Id: send.c,v 1.7 2001/12/01 20:57:23 phreak Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/lpc/send.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>
18 #include <internal/safe.h>
21 #include <internal/debug.h>
24 /**********************************************************************
37 LpcSendTerminationPort (IN PEPORT Port
,
41 LPC_TERMINATION_MESSAGE Msg
;
43 Msg
.CreationTime
= CreationTime
;
44 Status
= LpcRequestPort (Port
, &Msg
.Header
);
49 /**********************************************************************
62 LpcSendDebugMessagePort (IN PEPORT Port
,
63 IN PLPC_DBG_MESSAGE Message
,
64 OUT PLPC_DBG_MESSAGE Reply
)
68 PQUEUEDMESSAGE ReplyMessage
;
70 Status
= EiReplyOrRequestPort(Port
,
74 if (!NT_SUCCESS(Status
))
76 ObDereferenceObject(Port
);
79 KeReleaseSemaphore(&Port
->OtherPort
->Semaphore
, IO_NO_INCREMENT
, 1, FALSE
);
84 KeWaitForSingleObject(&Port
->Semaphore
,
93 KeAcquireSpinLock(&Port
->Lock
, &oldIrql
);
94 ReplyMessage
= EiDequeueMessagePort(Port
);
95 KeReleaseSpinLock(&Port
->Lock
, oldIrql
);
96 memcpy(Reply
, &ReplyMessage
->Message
, ReplyMessage
->Message
.MessageSize
);
97 ExFreePool(ReplyMessage
);
99 return(STATUS_SUCCESS
);
103 /**********************************************************************
115 NTSTATUS STDCALL
LpcRequestPort (IN PEPORT Port
,
116 IN PLPC_MESSAGE LpcMessage
)
120 DPRINT("LpcRequestPort(PortHandle %x LpcMessage %x)\n", Port
, LpcMessage
);
122 Status
= EiReplyOrRequestPort(Port
,
126 KeReleaseSemaphore( &Port
->Semaphore
, IO_NO_INCREMENT
, 1, FALSE
);
132 /**********************************************************************
144 NTSTATUS STDCALL
NtRequestPort (IN HANDLE PortHandle
,
145 IN PLPC_MESSAGE LpcMessage
)
150 DPRINT("NtRequestPort(PortHandle %x LpcMessage %x)\n", PortHandle
,
153 Status
= ObReferenceObjectByHandle(PortHandle
,
159 if (!NT_SUCCESS(Status
))
161 DPRINT("NtRequestPort() = %x\n", Status
);
165 Status
= LpcRequestPort(Port
->OtherPort
,
168 ObDereferenceObject(Port
);
173 /**********************************************************************
186 NtRequestWaitReplyPort (IN HANDLE PortHandle
,
187 PLPC_MESSAGE UnsafeLpcRequest
,
188 PLPC_MESSAGE UnsafeLpcReply
)
192 PQUEUEDMESSAGE Message
;
194 PLPC_MESSAGE LpcRequest
;
195 USHORT LpcRequestMessageSize
;
197 DPRINT("NtRequestWaitReplyPort(PortHandle %x, LpcRequest %x, "
198 "LpcReply %x)\n", PortHandle
, UnsafeLpcRequest
, UnsafeLpcReply
);
200 Status
= ObReferenceObjectByHandle(PortHandle
,
206 if (!NT_SUCCESS(Status
))
211 Status
= MmCopyFromCaller(&LpcRequestMessageSize
,
212 &UnsafeLpcRequest
->MessageSize
,
214 if (!NT_SUCCESS(Status
))
216 ObDereferenceObject(Port
);
219 if (LpcRequestMessageSize
> (sizeof(LPC_MESSAGE
) + MAX_MESSAGE_DATA
))
221 ObDereferenceObject(Port
);
222 return(STATUS_PORT_MESSAGE_TOO_LONG
);
224 LpcRequest
= ExAllocatePool(NonPagedPool
, LpcRequestMessageSize
);
225 if (LpcRequest
== NULL
)
227 ObDereferenceObject(Port
);
228 return(STATUS_NO_MEMORY
);
230 Status
= MmCopyFromCaller(LpcRequest
, UnsafeLpcRequest
,
231 LpcRequestMessageSize
);
232 if (!NT_SUCCESS(Status
))
234 ExFreePool(LpcRequest
);
235 ObDereferenceObject(Port
);
238 LpcRequestMessageSize
= LpcRequest
->MessageSize
;
239 if (LpcRequestMessageSize
> (sizeof(LPC_MESSAGE
) + MAX_MESSAGE_DATA
))
241 ExFreePool(LpcRequest
);
242 ObDereferenceObject(Port
);
243 return(STATUS_PORT_MESSAGE_TOO_LONG
);
245 if (LpcRequest
->DataSize
!= (LpcRequest
->MessageSize
- sizeof(LPC_MESSAGE
)))
247 ExFreePool(LpcRequest
);
248 ObDereferenceObject(Port
);
249 return(STATUS_PORT_MESSAGE_TOO_LONG
);
252 Status
= EiReplyOrRequestPort(Port
->OtherPort
,
256 if (!NT_SUCCESS(Status
))
258 DbgPrint("Enqueue failed\n");
259 ExFreePool(LpcRequest
);
260 ObDereferenceObject(Port
);
263 ExFreePool(LpcRequest
);
264 KeReleaseSemaphore (&Port
->OtherPort
->Semaphore
, IO_NO_INCREMENT
,
270 KeWaitForSingleObject(&Port
->Semaphore
,
279 KeAcquireSpinLock(&Port
->Lock
, &oldIrql
);
280 Message
= EiDequeueMessagePort(Port
);
281 KeReleaseSpinLock(&Port
->Lock
, oldIrql
);
282 DPRINT("Message->Message.MessageSize %d\n",
283 Message
->Message
.MessageSize
);
284 Status
= MmCopyToCaller(UnsafeLpcReply
, &Message
->Message
,
285 Message
->Message
.MessageSize
);
288 ObDereferenceObject(Port
);
294 /**********************************************************************
306 NTSTATUS STDCALL
NtWriteRequestData (HANDLE PortHandle
,
307 PLPC_MESSAGE Message
,