Author: ion Date: Mon Oct 30 17:28:50 2006 New Revision: 24666
URL: http://svn.reactos.org/svn/reactos?rev=24666&view=rev Log: - Add lpc\ntlpc directory when NTLPC = 1. - Add function stubs in appropriate files. - Implement NtConnectPort (stub to NtSecureConnectPort). Implement NtReplyWaitReceivePort (stub to NtReplyWaitReceivePortEx). Everything else is unimplemented. - Implement LpcpInitSystem and object callbacks LpcpDeletePort and LpcpClosePort. - Add internal lpc.h header.
Added: trunk/reactos/ntoskrnl/lpc/ntlpc/ trunk/reactos/ntoskrnl/lpc/ntlpc/close.c trunk/reactos/ntoskrnl/lpc/ntlpc/complete.c trunk/reactos/ntoskrnl/lpc/ntlpc/connect.c trunk/reactos/ntoskrnl/lpc/ntlpc/create.c trunk/reactos/ntoskrnl/lpc/ntlpc/listen.c trunk/reactos/ntoskrnl/lpc/ntlpc/lpc.h trunk/reactos/ntoskrnl/lpc/ntlpc/port.c trunk/reactos/ntoskrnl/lpc/ntlpc/reply.c trunk/reactos/ntoskrnl/lpc/ntlpc/send.c
Added: trunk/reactos/ntoskrnl/lpc/ntlpc/close.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/lpc/ntlpc/close.c?... ============================================================================== --- trunk/reactos/ntoskrnl/lpc/ntlpc/close.c (added) +++ trunk/reactos/ntoskrnl/lpc/ntlpc/close.c Mon Oct 30 17:28:50 2006 @@ -1,0 +1,395 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/lpc/close.c + * PURPOSE: Local Procedure Call: Rundown, Cleanup, Deletion + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include <ntoskrnl.h> +#include "lpc.h" +#define NDEBUG +#include <internal/debug.h> + +/* PRIVATE FUNCTIONS *********************************************************/ + +VOID +NTAPI +LpcExitThread(IN PETHREAD Thread) +{ + PLPCP_MESSAGE Message; + + /* Acquire the lock */ + KeAcquireGuardedMutex(&LpcpLock); + + /* Make sure that the Reply Chain is empty */ + if (!IsListEmpty(&Thread->LpcReplyChain)) + { + /* It's not, remove the entry */ + RemoveEntryList(&Thread->LpcReplyChain); + } + + /* Set the thread in exit mode */ + Thread->LpcExitThreadCalled = TRUE; + Thread->LpcReplyMessageId = 0; + + /* Check if there's a reply message */ + Message = Thread->LpcReplyMessage; + if (Message) + { + /* FIXME: TODO */ + ASSERT(FALSE); + } + + /* Release the lock */ + KeReleaseGuardedMutex(&LpcpLock); +} + +VOID +NTAPI +LpcpFreeToPortZone(IN PLPCP_MESSAGE Message, + IN ULONG Flags) +{ + PLPCP_CONNECTION_MESSAGE ConnectMessage; + PLPCP_PORT_OBJECT ClientPort = NULL; + PETHREAD Thread = NULL; + BOOLEAN LockHeld = Flags & 1; + PAGED_CODE(); + LPCTRACE(LPC_CLOSE_DEBUG, "Message: %p. Flags: %lx\n", Message, Flags); + + /* Acquire the lock if not already */ + if (!LockHeld) KeAcquireGuardedMutex(&LpcpLock); + + /* Check if the queue list is empty */ + if (!IsListEmpty(&Message->Entry)) + { + /* Remove and re-initialize */ + RemoveEntryList(&Message->Entry); + InitializeListHead(&Message->Entry); + } + + /* Check if we've already replied */ + if (Message->RepliedToThread) + { + /* Set thread to dereference and clean up */ + Thread = Message->RepliedToThread; + Message->RepliedToThread = NULL; + } + + /* Check if this is a connection request */ + if (Message->Request.u2.s2.Type == LPC_CONNECTION_REQUEST) + { + /* Get the connection message */ + ConnectMessage = (PLPCP_CONNECTION_MESSAGE)(Message + 1); + + /* Clear the client port */ + ClientPort = ConnectMessage->ClientPort; + if (ClientPort) ConnectMessage->ClientPort = NULL; + } + + /* Release the lock */ + KeReleaseGuardedMutex(&LpcpLock); + + /* Check if we had anything to dereference */ + if (Thread) ObDereferenceObject(Thread); + if (ClientPort) ObDereferenceObject(ClientPort); + + /* Free the entry */ + ExFreeToPagedLookasideList(&LpcpMessagesLookaside, Message); + + /* Reacquire the lock if needed */ + if ((LockHeld) && !(Flags & 2)) KeAcquireGuardedMutex(&LpcpLock); +} + +VOID +NTAPI +LpcpDestroyPortQueue(IN PLPCP_PORT_OBJECT Port, + IN BOOLEAN Destroy) +{ + PLIST_ENTRY ListHead, NextEntry; + PETHREAD Thread; + PLPCP_MESSAGE Message; + PLPCP_CONNECTION_MESSAGE ConnectMessage; + LPCTRACE(LPC_CLOSE_DEBUG, "Port: %p. Flags: %lx\n", Port, Port->Flags); + + /* Hold the lock */ + KeAcquireGuardedMutex(&LpcpLock); + + /* Disconnect the port to which this port is connected */ + if (Port->ConnectedPort) Port->ConnectedPort->ConnectedPort = NULL; + + /* Check if this is a connection port */ + if ((Port->Flags & LPCP_PORT_TYPE_MASK) == LPCP_CONNECTION_PORT) + { + /* Delete the name */ + Port->Flags |= LPCP_NAME_DELETED; + } + + /* Walk all the threads waiting and signal them */ + ListHead = &Port->LpcReplyChainHead; + NextEntry = ListHead->Flink; + while (NextEntry != ListHead) + { + /* Get the Thread */ + Thread = CONTAINING_RECORD(NextEntry, ETHREAD, LpcReplyChain); + + /* Make sure we're not in exit */ + if (Thread->LpcExitThreadCalled) break; + + /* Move to the next entry */ + NextEntry = NextEntry->Flink; + + /* Remove and reinitialize the List */ + RemoveEntryList(&Thread->LpcReplyChain); + InitializeListHead(&Thread->LpcReplyChain); + + /* Check if someone is waiting */ + if (!KeReadStateSemaphore(&Thread->LpcReplySemaphore)) + { + /* Get the message and check if it's a connection request */ + Message = Thread->LpcReplyMessage; + if (Message->Request.u2.s2.Type == LPC_CONNECTION_REQUEST) + { + /* Get the connection message */ + ConnectMessage = (PLPCP_CONNECTION_MESSAGE)(Message + 1); + + /* Check if it had a section */ + if (ConnectMessage->SectionToMap) + { + /* Dereference it */ + ObDereferenceObject(ConnectMessage->SectionToMap); + } + } + + /* Clear the reply message */ + Thread->LpcReplyMessage = NULL; + + /* And remove the message from the port zone */ + LpcpFreeToPortZone(Message, TRUE); + } + + /* Release the semaphore and reset message id count */ + Thread->LpcReplyMessageId = 0; + LpcpCompleteWait(&Thread->LpcReplySemaphore); + } + + /* Reinitialize the list head */ + InitializeListHead(&Port->LpcReplyChainHead); + + /* Loop queued messages */ + ListHead = &Port->MsgQueue.ReceiveHead; + NextEntry = ListHead->Flink; + while (ListHead != NextEntry) + { + /* Get the message */ + Message = CONTAINING_RECORD(NextEntry, LPCP_MESSAGE, Entry); + NextEntry = NextEntry->Flink; + + /* Free and reinitialize it's list head */ + InitializeListHead(&Message->Entry); + + /* Remove it from the port zone */ + LpcpFreeToPortZone(Message, TRUE); + } + + /* Reinitialize the message queue list head */ + InitializeListHead(&Port->MsgQueue.ReceiveHead); + + /* Release the lock */ + KeReleaseGuardedMutex(&LpcpLock); + + /* Check if we have to free the port entirely */ + if (Destroy) + { + /* Check if the semaphore exists */ + if (Port->MsgQueue.Semaphore) + { + /* Use the semaphore to find the port queue and free it */ + ExFreePool(CONTAINING_RECORD(Port->MsgQueue.Semaphore, + LPCP_NONPAGED_PORT_QUEUE, + Semaphore)); + } + } +} + +VOID +NTAPI +LpcpClosePort(IN PEPROCESS Process OPTIONAL, + IN PVOID Object, + IN ACCESS_MASK GrantedAccess, + IN ULONG ProcessHandleCount, + IN ULONG SystemHandleCount) +{ + PLPCP_PORT_OBJECT Port = (PLPCP_PORT_OBJECT)Object; + LPCTRACE(LPC_CLOSE_DEBUG, "Port: %p. Flags: %lx\n", Port, Port->Flags); + + /* Only Server-side Connection Ports need clean up*/ + if ((Port->Flags & LPCP_PORT_TYPE_MASK) == LPCP_CONNECTION_PORT) + { + /* Check the handle count */ + switch (SystemHandleCount) + { + /* No handles left */ + case 0: + + /* Destroy the port queue */ + LpcpDestroyPortQueue(Port, TRUE); + break; + + /* Last handle remaining */ + case 1: + + /* Reset the queue only */ + LpcpDestroyPortQueue(Port, FALSE); + + /* More handles remain, do nothing */ + default: + break; + } + } +} + +VOID +NTAPI +LpcpFreePortClientSecurity(IN PLPCP_PORT_OBJECT Port) +{ + /* Check if this is a client port */ + if ((Port->Flags & LPCP_PORT_TYPE_MASK) == LPCP_CLIENT_PORT) + { + /* Check if security is static */ + if (!(Port->Flags & LPCP_SECURITY_DYNAMIC)) + { + /* Check if we have a token */ + if (Port->StaticSecurity.ClientToken) + { + /* Free security */ + SeDeleteClientSecurity(&Port->StaticSecurity); + } + } + } +} + +VOID +NTAPI +LpcpDeletePort(IN PVOID ObjectBody) +{ + LARGE_INTEGER Timeout; + PETHREAD Thread; + PLPCP_PORT_OBJECT Port = (PLPCP_PORT_OBJECT)ObjectBody; + PLPCP_PORT_OBJECT ConnectionPort; + PLPCP_MESSAGE Message; + PLIST_ENTRY ListHead, NextEntry; + HANDLE Pid; + CLIENT_DIED_MSG ClientDiedMsg; + Timeout.QuadPart = -1000000; + PAGED_CODE(); + LPCTRACE(LPC_CLOSE_DEBUG, "Port: %p. Flags: %lx\n", Port, Port->Flags); + + /* Check if this is a communication port */ + if ((Port->Flags & LPCP_PORT_TYPE_MASK) == LPCP_COMMUNICATION_PORT) + { + /* Acquire the lock */ + KeAcquireGuardedMutex(&LpcpLock); + + /* Get the thread */ + Thread = Port->ClientThread; + if (Thread) + { + /* Clear it */ + Port->ClientThread = NULL; + + /* Release the lock and dereference */ + KeReleaseGuardedMutex(&LpcpLock); + ObDereferenceObject(Thread); + } + else + { + /* Release the lock */ + KeReleaseGuardedMutex(&LpcpLock); + } + } + + /* Check if this is a client-side port */ + if ((Port->Flags & LPCP_PORT_TYPE_MASK) == LPCP_CLIENT_PORT) + { + /* Setup the client died message */ + ClientDiedMsg.h.u1.s1.TotalLength = sizeof(ClientDiedMsg); + ClientDiedMsg.h.u1.s1.DataLength = sizeof(ClientDiedMsg.CreateTime); + ClientDiedMsg.h.u2.ZeroInit = LPC_PORT_CLOSED; + ClientDiedMsg.CreateTime = PsGetCurrentProcess()->CreateTime; + + /* Send it */ + for (;;) + { + /* Send the message */ + if (LpcRequestPort(Port, + &ClientDiedMsg.h) != STATUS_NO_MEMORY) break; + + /* Wait until trying again */ + KeDelayExecutionThread(KernelMode, FALSE, &Timeout); + } + } + + /* Destroy the port queue */ + LpcpDestroyPortQueue(Port, TRUE); + + /* Check if we had a client view */ + if (Port->ClientSectionBase) MmUnmapViewOfSection(PsGetCurrentProcess(), + Port->ClientSectionBase); + + /* Check for a server view */ + if (Port->ServerSectionBase) MmUnmapViewOfSection(PsGetCurrentProcess(), + Port->ServerSectionBase); + + /* Get the connection port */ + ConnectionPort = Port->ConnectionPort; + if (ConnectionPort) + { + /* Get the PID */ + Pid = PsGetCurrentProcessId(); + + /* Acquire the lock */ + KeAcquireGuardedMutex(&LpcpLock); + + /* Loop the data lists */ + ListHead = &ConnectionPort->LpcDataInfoChainHead; + NextEntry = ListHead->Flink; + while (NextEntry != ListHead) + { + /* Get the message */ + Message = CONTAINING_RECORD(NextEntry, LPCP_MESSAGE, Entry); + NextEntry = NextEntry->Flink; + + /* Check if the PID matches */ + if (Message->Request.ClientId.UniqueProcess == Pid) + { + /* Remove it */ + RemoveEntryList(&Message->Entry); + LpcpFreeToPortZone(Message, TRUE); + } + } + + /* Release the lock */ + KeReleaseGuardedMutex(&LpcpLock); + + /* Dereference the object unless it's the same port */ + if (ConnectionPort != Port) ObDereferenceObject(ConnectionPort); + } + + /* Check if this is a connection port with a server process*/ + if (((Port->Flags & LPCP_PORT_TYPE_MASK) == LPCP_CONNECTION_PORT) && + (ConnectionPort->ServerProcess)) + { + /* Dereference the server process */ + ObDereferenceObject(ConnectionPort->ServerProcess); + ConnectionPort->ServerProcess = NULL; + } + + /* Free client security */ + LpcpFreePortClientSecurity(Port); + LPCTRACE(LPC_CLOSE_DEBUG, "Port: %p deleted\n", Port); +} + +/* EOF */
Added: trunk/reactos/ntoskrnl/lpc/ntlpc/complete.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/lpc/ntlpc/complete... ============================================================================== --- trunk/reactos/ntoskrnl/lpc/ntlpc/complete.c (added) +++ trunk/reactos/ntoskrnl/lpc/ntlpc/complete.c Mon Oct 30 17:28:50 2006 @@ -1,0 +1,47 @@ +/* +* PROJECT: ReactOS Kernel +* LICENSE: GPL - See COPYING in the top level directory +* FILE: ntoskrnl/lpc/complete.c +* PURPOSE: Local Procedure Call: Connection Completion +* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) +*/ + +/* INCLUDES ******************************************************************/ + +#include <ntoskrnl.h> +#include "lpc.h" +#define NDEBUG +#include <internal/debug.h> + +/* PRIVATE FUNCTIONS *********************************************************/ + +/* PUBLIC FUNCTIONS **********************************************************/ + +/* + * @implemented + */ +NTSTATUS +NTAPI +NtAcceptConnectPort(OUT PHANDLE PortHandle, + IN PVOID PortContext OPTIONAL, + IN PPORT_MESSAGE ReplyMessage, + IN BOOLEAN AcceptConnection, + IN PPORT_VIEW ClientView, + IN PREMOTE_PORT_VIEW ServerView) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +NtCompleteConnectPort(IN HANDLE PortHandle) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +/* EOF */
Added: trunk/reactos/ntoskrnl/lpc/ntlpc/connect.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/lpc/ntlpc/connect.... ============================================================================== --- trunk/reactos/ntoskrnl/lpc/ntlpc/connect.c (added) +++ trunk/reactos/ntoskrnl/lpc/ntlpc/connect.c Mon Oct 30 17:28:50 2006 @@ -1,0 +1,65 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/lpc/connect.c + * PURPOSE: Local Procedure Call: Connection Management + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include <ntoskrnl.h> +#include "lpc.h" +#define NDEBUG +#include <internal/debug.h> + +/* PRIVATE FUNCTIONS *********************************************************/ + +/* PUBLIC FUNCTIONS **********************************************************/ + +/* + * @implemented + */ +NTSTATUS +NTAPI +NtSecureConnectPort(OUT PHANDLE PortHandle, + IN PUNICODE_STRING PortName, + IN PSECURITY_QUALITY_OF_SERVICE Qos, + IN OUT PPORT_VIEW ClientView OPTIONAL, + IN PSID ServerSid OPTIONAL, + IN OUT PREMOTE_PORT_VIEW ServerView OPTIONAL, + OUT PULONG MaxMessageLength OPTIONAL, + IN OUT PVOID ConnectionInformation OPTIONAL, + IN OUT PULONG ConnectionInformationLength OPTIONAL) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +NtConnectPort(OUT PHANDLE PortHandle, + IN PUNICODE_STRING PortName, + IN PSECURITY_QUALITY_OF_SERVICE Qos, + IN PPORT_VIEW ClientView, + IN PREMOTE_PORT_VIEW ServerView, + OUT PULONG MaxMessageLength, + IN PVOID ConnectionInformation, + OUT PULONG ConnectionInformationLength) +{ + /* Call the newer API */ + return NtSecureConnectPort(PortHandle, + PortName, + Qos, + ClientView, + NULL, + ServerView, + MaxMessageLength, + ConnectionInformation, + ConnectionInformationLength); +} + +/* EOF */
Added: trunk/reactos/ntoskrnl/lpc/ntlpc/create.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/lpc/ntlpc/create.c... ============================================================================== --- trunk/reactos/ntoskrnl/lpc/ntlpc/create.c (added) +++ trunk/reactos/ntoskrnl/lpc/ntlpc/create.c Mon Oct 30 17:28:50 2006 @@ -1,0 +1,77 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/lpc/create.c + * PURPOSE: Local Procedure Call: Port/Queue/Message Creation + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include <ntoskrnl.h> +#include "lpc.h" +#define NDEBUG +#include <internal/debug.h> + +/* PRIVATE FUNCTIONS *********************************************************/ + +NTSTATUS +NTAPI +LpcpCreatePort(OUT PHANDLE PortHandle, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN ULONG MaxConnectionInfoLength, + IN ULONG MaxMessageLength, + IN ULONG MaxPoolUsage, + IN BOOLEAN Waitable) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +/* PUBLIC FUNCTIONS **********************************************************/ + +/* + * @implemented + */ +NTSTATUS +NTAPI +NtCreatePort(OUT PHANDLE PortHandle, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN ULONG MaxConnectInfoLength, + IN ULONG MaxDataLength, + IN ULONG MaxPoolUsage) +{ + PAGED_CODE(); + + /* Call the internal API */ + return LpcpCreatePort(PortHandle, + ObjectAttributes, + MaxConnectInfoLength, + MaxDataLength, + MaxPoolUsage, + FALSE); +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +NtCreateWaitablePort(OUT PHANDLE PortHandle, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN ULONG MaxConnectInfoLength, + IN ULONG MaxDataLength, + IN ULONG MaxPoolUsage) +{ + PAGED_CODE(); + + /* Call the internal API */ + return LpcpCreatePort(PortHandle, + ObjectAttributes, + MaxConnectInfoLength, + MaxDataLength, + MaxPoolUsage, + TRUE); +} + +/* EOF */
Added: trunk/reactos/ntoskrnl/lpc/ntlpc/listen.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/lpc/ntlpc/listen.c... ============================================================================== --- trunk/reactos/ntoskrnl/lpc/ntlpc/listen.c (added) +++ trunk/reactos/ntoskrnl/lpc/ntlpc/listen.c Mon Oct 30 17:28:50 2006 @@ -1,0 +1,31 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/lpc/listen.c + * PURPOSE: Local Procedure Call: Listening + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include <ntoskrnl.h> +#include "lpc.h" +#define NDEBUG +#include <internal/debug.h> + +/* PUBLIC FUNCTIONS **********************************************************/ + +/* + * @implemented + */ +NTSTATUS +NTAPI +NtListenPort(IN HANDLE PortHandle, + OUT PPORT_MESSAGE ConnectMessage) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + + +/* EOF */
Added: trunk/reactos/ntoskrnl/lpc/ntlpc/lpc.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/lpc/ntlpc/lpc.h?re... ============================================================================== --- trunk/reactos/ntoskrnl/lpc/ntlpc/lpc.h (added) +++ trunk/reactos/ntoskrnl/lpc/ntlpc/lpc.h Mon Oct 30 17:28:50 2006 @@ -1,0 +1,216 @@ +/* +* PROJECT: ReactOS Kernel +* LICENSE: GPL - See COPYING in the top level directory +* FILE: ntoskrnl/include/lpc.h +* PURPOSE: Internal header for the Local Procedure Call +* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) +*/ + +// +// Define this if you want debugging support +// +#define _LPC_DEBUG_ 0x01 + +// +// These define the Debug Masks Supported +// +#define LPC_CREATE_DEBUG 0x01 +#define LPC_CLOSE_DEBUG 0x02 +#define LPC_CONNECT_DEBUG 0x04 +#define LPC_LISTEN_DEBUG 0x08 +#define LPC_REPLY_DEBUG 0x10 +#define LPC_COMPLETE_DEBUG 0x20 +#define LPC_SEND_DEBUG 0x40 + +// +// Debug/Tracing support +// +#if _LPC_DEBUG_ +#ifdef NEW_DEBUG_SYSTEM_IMPLEMENTED // enable when Debug Filters are implemented +#define LPCTRACE(x, ...) \ + { \ + DbgPrintEx("%s [%.16s] - ", \ + __FUNCTION__, \ + PsGetCurrentProcess()->ImageFileName); \ + DbgPrintEx(__VA_ARGS__); \ + } +#else +#define LPCTRACE(x, ...) \ + if (x & LpcpTraceLevel) \ + { \ + DbgPrint("%s [%.16s:%lx] - ", \ + __FUNCTION__, \ + PsGetCurrentProcess()->ImageFileName, \ + PsGetCurrentThreadId()); \ + DbgPrint(__VA_ARGS__); \ + } +#endif +#endif + +// +// Gets the message type, removing the kernel-mode flag +// +#define LpcpGetMessageType(x) \ + ((x)->u2.s2.MessageType &~ LPCP_KERNEL_MESSAGE) + +// +// Waits on an LPC semaphore for a receive operation +// +#define LpcpReceiveWait(s, w) \ +{ \ + LPCTRACE(LPC_REPLY_DEBUG, "Wait: %p\n", s); \ + Status = KeWaitForSingleObject(s, \ + WrLpcReceive, \ + w, \ + FALSE, \ + NULL); \ + LPCTRACE(LPC_REPLY_DEBUG, "Wait done: %lx\n", Status); \ +} + +// +// Waits on an LPC semaphore for a reply operation +// +#define LpcpReplyWait(s, w) \ +{ \ + LPCTRACE(LPC_SEND_DEBUG, "Wait: %p\n", s); \ + Status = KeWaitForSingleObject(s, \ + WrLpcReply, \ + w, \ + FALSE, \ + NULL); \ + LPCTRACE(LPC_SEND_DEBUG, "Wait done: %lx\n", Status); \ + if (Status == STATUS_USER_APC) \ + { \ + /* We were preempted by an APC */ \ + if (KeReadStateSemaphore(s)) \ + { \ + /* It's still signaled, so wait on it */ \ + KeWaitForSingleObject(s, \ + Executive, \ + KernelMode, \ + FALSE, \ + NULL); \ + Status = STATUS_SUCCESS; \ + } \ + } \ +} + +// +// Waits on an LPC semaphore for a connect operation +// +#define LpcpConnectWait(s, w) \ +{ \ + LPCTRACE(LPC_CONNECT_DEBUG, "Wait: %p\n", s); \ + Status = KeWaitForSingleObject(s, \ + Executive, \ + w, \ + FALSE, \ + NULL); \ + LPCTRACE(LPC_CONNECT_DEBUG, "Wait done: %lx\n", Status);\ + if (Status == STATUS_USER_APC) \ + { \ + /* We were preempted by an APC */ \ + if (KeReadStateSemaphore(s)) \ + { \ + /* It's still signaled, so wait on it */ \ + KeWaitForSingleObject(s, \ + Executive, \ + KernelMode, \ + FALSE, \ + NULL); \ + Status = STATUS_SUCCESS; \ + } \ + } \ +} + +// +// Releases an LPC Semaphore to complete a wait +// +#define LpcpCompleteWait(s) \ +{ \ + /* Release the semaphore */ \ + LPCTRACE(LPC_SEND_DEBUG, "Release: %p\n", s); \ + KeReleaseSemaphore(s, 1, 1, FALSE); \ +} + +// +// Internal flag used for Kernel LPC Messages +// +#define LPCP_KERNEL_MESSAGE 0x8000 + +// +// Internal Port Management +// +VOID +NTAPI +LpcpClosePort( + IN PEPROCESS Process OPTIONAL, + IN PVOID Object, + IN ACCESS_MASK GrantedAccess, + IN ULONG ProcessHandleCount, + IN ULONG SystemHandleCount +); + +VOID +NTAPI +LpcpDeletePort( + IN PVOID ObjectBody +); + +NTSTATUS +NTAPI +LpcpInitializePortQueue( + IN PLPCP_PORT_OBJECT Port +); + +VOID +NTAPI +LpcpFreeToPortZone( + IN PLPCP_MESSAGE Message, + IN ULONG Flags +); + +VOID +NTAPI +LpcpMoveMessage( + IN PPORT_MESSAGE Destination, + IN PPORT_MESSAGE Origin, + IN PVOID Data, + IN ULONG MessageType, + IN PCLIENT_ID ClientId +); + +VOID +NTAPI +LpcpSaveDataInfoMessage( + IN PLPCP_PORT_OBJECT Port, + IN PLPCP_MESSAGE Message +); + +// +// Module-external utlity functions +// +VOID +NTAPI +LpcExitThread( + IN PETHREAD Thread +); + +// +// Initialization functions +// +NTSTATUS +NTAPI +LpcpInitSystem( + VOID +); + +// +// Global data inside the Process Manager +// +extern POBJECT_TYPE LpcPortObjectType; +extern ULONG LpcpNextMessageId, LpcpNextCallbackId; +extern KGUARDED_MUTEX LpcpLock; +extern PAGED_LOOKASIDE_LIST LpcpMessagesLookaside; +extern ULONG LpcpMaxMessageSize; +extern ULONG LpcpTraceLevel;
Added: trunk/reactos/ntoskrnl/lpc/ntlpc/port.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/lpc/ntlpc/port.c?r... ============================================================================== --- trunk/reactos/ntoskrnl/lpc/ntlpc/port.c (added) +++ trunk/reactos/ntoskrnl/lpc/ntlpc/port.c Mon Oct 30 17:28:50 2006 @@ -1,0 +1,108 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/lpc/port.c + * PURPOSE: Local Procedure Call: Port Management + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include <ntoskrnl.h> +#include "lpc.h" +#define NDEBUG +#include <internal/debug.h> + +/* GLOBALS *******************************************************************/ + +POBJECT_TYPE LpcPortObjectType; +ULONG LpcpMaxMessageSize; +PAGED_LOOKASIDE_LIST LpcpMessagesLookaside; +KGUARDED_MUTEX LpcpLock; +ULONG LpcpTraceLevel = 0xFFFFFFFF; +ULONG LpcpNextMessageId = 1, LpcpNextCallbackId = 1; + +static GENERIC_MAPPING LpcpPortMapping = +{ + STANDARD_RIGHTS_READ, + STANDARD_RIGHTS_WRITE, + 0, + PORT_ALL_ACCESS +}; + +/* PRIVATE FUNCTIONS *********************************************************/ + +NTSTATUS +INIT_FUNCTION +NTAPI +LpcpInitSystem(VOID) +{ + OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; + UNICODE_STRING Name; + + /* Setup the LPC Lock */ + KeInitializeGuardedMutex(&LpcpLock); + + /* Create the Port Object Type */ + RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); + RtlInitUnicodeString(&Name, L"Port"); + ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); + ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(LPCP_PORT_OBJECT); + ObjectTypeInitializer.DefaultPagedPoolCharge = sizeof(LPCP_NONPAGED_PORT_QUEUE); + ObjectTypeInitializer.GenericMapping = LpcpPortMapping; + ObjectTypeInitializer.PoolType = PagedPool; + ObjectTypeInitializer.UseDefaultObject = TRUE; + ObjectTypeInitializer.CloseProcedure = LpcpClosePort; + ObjectTypeInitializer.DeleteProcedure = LpcpDeletePort; + ObjectTypeInitializer.ValidAccessMask = PORT_ALL_ACCESS; + ObCreateObjectType(&Name, + &ObjectTypeInitializer, + NULL, + &LpcPortObjectType); + + /* Allocate the LPC lookaside list */ + LpcpMaxMessageSize = LPCP_MAX_MESSAGE_SIZE; + ExInitializePagedLookasideList(&LpcpMessagesLookaside, + NULL, + NULL, + 0, + LpcpMaxMessageSize, + TAG('L', 'p', 'c', 'M'), + 32); + + /* We're done */ + return STATUS_SUCCESS; +} + +/* PUBLIC FUNCTIONS **********************************************************/ + +NTSTATUS +NTAPI +NtImpersonateClientOfPort(IN HANDLE PortHandle, + IN PPORT_MESSAGE ClientMessage) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +NtQueryPortInformationProcess(VOID) +{ + /* This is all this function does */ + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +NtQueryInformationPort(IN HANDLE PortHandle, + IN PORT_INFORMATION_CLASS PortInformationClass, + OUT PVOID PortInformation, + IN ULONG PortInformationLength, + OUT PULONG ReturnLength) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +/* EOF */
Added: trunk/reactos/ntoskrnl/lpc/ntlpc/reply.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/lpc/ntlpc/reply.c?... ============================================================================== --- trunk/reactos/ntoskrnl/lpc/ntlpc/reply.c (added) +++ trunk/reactos/ntoskrnl/lpc/ntlpc/reply.c Mon Oct 30 17:28:50 2006 @@ -1,0 +1,109 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/lpc/reply.c + * PURPOSE: Local Procedure Call: Receive (Replies) + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include <ntoskrnl.h> +#include "lpc.h" +#define NDEBUG +#include <internal/debug.h> + +/* PRIVATE FUNCTIONS *********************************************************/ + +/* PUBLIC FUNCTIONS **********************************************************/ + +/* + * @unimplemented + */ +NTSTATUS +NTAPI +NtReplyPort(IN HANDLE PortHandle, + IN PPORT_MESSAGE LpcReply) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +/* + * @unimplemented + */ +NTSTATUS +NTAPI +NtReplyWaitReceivePortEx(IN HANDLE PortHandle, + OUT PVOID *PortContext OPTIONAL, + IN PPORT_MESSAGE ReplyMessage OPTIONAL, + OUT PPORT_MESSAGE ReceiveMessage, + IN PLARGE_INTEGER Timeout OPTIONAL) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +NtReplyWaitReceivePort(IN HANDLE PortHandle, + OUT PVOID *PortContext OPTIONAL, + IN PPORT_MESSAGE ReplyMessage OPTIONAL, + OUT PPORT_MESSAGE ReceiveMessage) +{ + /* Call the newer API */ + return NtReplyWaitReceivePortEx(PortHandle, + PortContext, + ReplyMessage, + ReceiveMessage, + NULL); +} + +/* + * @unimplemented + */ +NTSTATUS +NTAPI +NtReplyWaitReplyPort(IN HANDLE PortHandle, + IN PPORT_MESSAGE ReplyMessage) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +/* + * @unimplemented + */ +NTSTATUS +NTAPI +NtReadRequestData(IN HANDLE PortHandle, + IN PPORT_MESSAGE Message, + IN ULONG Index, + IN PVOID Buffer, + IN ULONG BufferLength, + OUT PULONG Returnlength) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +/* + * @unimplemented + */ +NTSTATUS +NTAPI +NtWriteRequestData(IN HANDLE PortHandle, + IN PPORT_MESSAGE Message, + IN ULONG Index, + IN PVOID Buffer, + IN ULONG BufferLength, + OUT PULONG ReturnLength) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +/* EOF */
Added: trunk/reactos/ntoskrnl/lpc/ntlpc/send.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/lpc/ntlpc/send.c?r... ============================================================================== --- trunk/reactos/ntoskrnl/lpc/ntlpc/send.c (added) +++ trunk/reactos/ntoskrnl/lpc/ntlpc/send.c Mon Oct 30 17:28:50 2006 @@ -1,0 +1,68 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/lpc/send.c + * PURPOSE: Local Procedure Call: Sending (Requests) + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include <ntoskrnl.h> +#include "lpc.h" +#define NDEBUG +#include <internal/debug.h> + +/* PUBLIC FUNCTIONS **********************************************************/ + +/* + * @unimplemented + */ +NTSTATUS +NTAPI +LpcRequestPort(IN PVOID Port, + IN PPORT_MESSAGE LpcMessage) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +/* +* @unimplemented +*/ +NTSTATUS +NTAPI +LpcRequestWaitReplyPort(IN PVOID Port, + IN PPORT_MESSAGE LpcMessageRequest, + OUT PPORT_MESSAGE LpcMessageReply) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +/* + * @unimplemented + */ +NTSTATUS +NTAPI +NtRequestPort(IN HANDLE PortHandle, + IN PPORT_MESSAGE LpcMessage) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +NtRequestWaitReplyPort(IN HANDLE PortHandle, + IN PPORT_MESSAGE LpcRequest, + IN OUT PPORT_MESSAGE LpcReply) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +/* EOF */