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 /**********************************************************************
36 LpcSendTerminationPort (IN PEPORT Port,
40 LPC_TERMINATION_MESSAGE Msg;
42 Msg.CreationTime = CreationTime;
43 Status = LpcRequestPort (Port, &Msg.Header);
48 /**********************************************************************
60 LpcSendDebugMessagePort (IN PEPORT Port,
61 IN PLPC_DBG_MESSAGE Message,
62 OUT PLPC_DBG_MESSAGE Reply)
66 PQUEUEDMESSAGE ReplyMessage;
68 Status = EiReplyOrRequestPort(Port,
72 if (!NT_SUCCESS(Status))
74 ObDereferenceObject(Port);
77 KeReleaseSemaphore(&Port->OtherPort->Semaphore, IO_NO_INCREMENT, 1, FALSE);
82 KeWaitForSingleObject(&Port->Semaphore,
91 KeAcquireSpinLock(&Port->Lock, &oldIrql);
92 ReplyMessage = EiDequeueMessagePort(Port);
93 KeReleaseSpinLock(&Port->Lock, oldIrql);
94 memcpy(Reply, &ReplyMessage->Message, ReplyMessage->Message.MessageSize);
95 ExFreePool(ReplyMessage);
97 return(STATUS_SUCCESS);
101 /**********************************************************************
114 NTSTATUS STDCALL LpcRequestPort (IN PEPORT Port,
115 IN PLPC_MESSAGE LpcMessage)
119 DPRINT("LpcRequestPort(PortHandle %x LpcMessage %x)\n", Port, LpcMessage);
121 Status = EiReplyOrRequestPort(Port,
125 KeReleaseSemaphore( &Port->Semaphore, IO_NO_INCREMENT, 1, FALSE );
131 /**********************************************************************
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 /**********************************************************************
187 NtRequestWaitReplyPort (IN HANDLE PortHandle,
188 PLPC_MESSAGE UnsafeLpcRequest,
189 PLPC_MESSAGE UnsafeLpcReply)
193 PQUEUEDMESSAGE Message;
195 PLPC_MESSAGE LpcRequest;
196 USHORT LpcRequestMessageSize;
198 DPRINT("NtRequestWaitReplyPort(PortHandle %x, LpcRequest %x, "
199 "LpcReply %x)\n", PortHandle, UnsafeLpcRequest, UnsafeLpcReply);
201 Status = ObReferenceObjectByHandle(PortHandle,
207 if (!NT_SUCCESS(Status))
212 Status = MmCopyFromCaller(&LpcRequestMessageSize,
213 &UnsafeLpcRequest->MessageSize,
215 if (!NT_SUCCESS(Status))
217 ObDereferenceObject(Port);
220 if (LpcRequestMessageSize > (sizeof(LPC_MESSAGE) + MAX_MESSAGE_DATA))
222 ObDereferenceObject(Port);
223 return(STATUS_PORT_MESSAGE_TOO_LONG);
225 LpcRequest = ExAllocatePool(NonPagedPool, LpcRequestMessageSize);
226 if (LpcRequest == NULL)
228 ObDereferenceObject(Port);
229 return(STATUS_NO_MEMORY);
231 Status = MmCopyFromCaller(LpcRequest, UnsafeLpcRequest,
232 LpcRequestMessageSize);
233 if (!NT_SUCCESS(Status))
235 ExFreePool(LpcRequest);
236 ObDereferenceObject(Port);
239 LpcRequestMessageSize = LpcRequest->MessageSize;
240 if (LpcRequestMessageSize > (sizeof(LPC_MESSAGE) + MAX_MESSAGE_DATA))
242 ExFreePool(LpcRequest);
243 ObDereferenceObject(Port);
244 return(STATUS_PORT_MESSAGE_TOO_LONG);
246 if (LpcRequest->DataSize != (LpcRequest->MessageSize - sizeof(LPC_MESSAGE)))
248 ExFreePool(LpcRequest);
249 ObDereferenceObject(Port);
250 return(STATUS_PORT_MESSAGE_TOO_LONG);
253 Status = EiReplyOrRequestPort(Port->OtherPort,
257 if (!NT_SUCCESS(Status))
259 DbgPrint("Enqueue failed\n");
260 ExFreePool(LpcRequest);
261 ObDereferenceObject(Port);
264 ExFreePool(LpcRequest);
265 KeReleaseSemaphore (&Port->OtherPort->Semaphore, IO_NO_INCREMENT,
271 Status = KeWaitForSingleObject(&Port->Semaphore,
276 if (Status == STATUS_SUCCESS)
282 KeAcquireSpinLock(&Port->Lock, &oldIrql);
283 Message = EiDequeueMessagePort(Port);
284 KeReleaseSpinLock(&Port->Lock, oldIrql);
287 DPRINT("Message->Message.MessageSize %d\n",
288 Message->Message.MessageSize);
289 Status = MmCopyToCaller(UnsafeLpcReply, &Message->Message,
290 Message->Message.MessageSize);
294 Status = STATUS_UNSUCCESSFUL;
298 if (NT_SUCCESS(Status))
300 Status = STATUS_UNSUCCESSFUL;
303 ObDereferenceObject(Port);
309 /**********************************************************************
320 NTSTATUS STDCALL NtWriteRequestData (HANDLE PortHandle,
321 PLPC_MESSAGE Message,