diff --git a/reactos/include/ndk/extypes.h b/reactos/include/ndk/extypes.h index 47439cd8f75..01cb60df903 100644 --- a/reactos/include/ndk/extypes.h +++ b/reactos/include/ndk/extypes.h @@ -592,14 +592,6 @@ typedef struct _HANDLE_TABLE_ENTRY }; } HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY; -// -// FIXME -// -#ifdef _REACTOS_ -#undef NTDDI_VERSION -#define NTDDI_VERSION NTDDI_WIN2K -#endif - typedef struct _HANDLE_TABLE { #if (NTDDI_VERSION >= NTDDI_WINXP) @@ -610,7 +602,7 @@ typedef struct _HANDLE_TABLE PEPROCESS QuotaProcess; PVOID UniqueProcessId; #if (NTDDI_VERSION >= NTDDI_WINXP) - EX_PUSH_LOCK HandleLock; + EX_PUSH_LOCK HandleTableLock[4]; LIST_ENTRY HandleTableList; EX_PUSH_LOCK HandleContentionEvent; #else diff --git a/reactos/ntoskrnl/include/internal/lpc.h b/reactos/ntoskrnl/include/internal/lpc.h index 2eba4487101..6dc86d68147 100644 --- a/reactos/ntoskrnl/include/internal/lpc.h +++ b/reactos/ntoskrnl/include/internal/lpc.h @@ -47,6 +47,14 @@ #endif #endif +// +// LPC Port/Message Flags +// +#define LPCP_THREAD_FLAG_IS_PORT 1 +#define LPCP_THREAD_FLAG_NO_IMPERSONATION 2 +#define LPCP_THREAD_FLAGS (LPCP_THREAD_FLAG_IS_PORT | \ + LPCP_THREAD_FLAG_NO_IMPERSONATION) + // // Internal Port Management // diff --git a/reactos/ntoskrnl/include/internal/lpc_x.h b/reactos/ntoskrnl/include/internal/lpc_x.h index a1cc008d3e7..6e8acf5eaed 100644 --- a/reactos/ntoskrnl/include/internal/lpc_x.h +++ b/reactos/ntoskrnl/include/internal/lpc_x.h @@ -120,3 +120,47 @@ LpcpAllocateFromPortZone(VOID) KeReleaseGuardedMutex(&LpcpLock); return Message; } + +// +// Get the LPC Message associated to the Thread +// +PLPCP_MESSAGE +FORCEINLINE +LpcpGetMessageFromThread(IN PETHREAD Thread) +{ + /* Check if the port flag is set */ + if (((ULONG_PTR)Thread->LpcReplyMessage) & LPCP_THREAD_FLAG_IS_PORT) + { + /* The pointer is actually a port, not a message, so return NULL */ + return NULL; + } + + /* Otherwise, this is a message. Return the pointer */ + return (PVOID)((ULONG_PTR)Thread->LpcReplyMessage & ~LPCP_THREAD_FLAGS); +} + +PLPCP_PORT_OBJECT +FORCEINLINE +LpcpGetPortFromThread(IN PETHREAD Thread) +{ + /* Check if the port flag is set */ + if (((ULONG_PTR)Thread->LpcReplyMessage) & LPCP_THREAD_FLAG_IS_PORT) + { + /* The pointer is actually a port, return it */ + return (PVOID)((ULONG_PTR)Thread->LpcWaitingOnPort & + ~LPCP_THREAD_FLAGS); + } + + /* Otherwise, this is a message. There is nothing to return */ + return NULL; +} + +VOID +FORCEINLINE +LpcpSetPortToThread(IN PETHREAD Thread, + IN PLPCP_PORT_OBJECT Port) +{ + /* Set the port object */ + Thread->LpcWaitingOnPort = (PVOID)(((ULONG_PTR)Port) | + LPCP_THREAD_FLAG_IS_PORT); +} diff --git a/reactos/ntoskrnl/lpc/close.c b/reactos/ntoskrnl/lpc/close.c index 95d40719c37..d142d0f50a9 100644 --- a/reactos/ntoskrnl/lpc/close.c +++ b/reactos/ntoskrnl/lpc/close.c @@ -36,7 +36,7 @@ LpcExitThread(IN PETHREAD Thread) Thread->LpcReplyMessageId = 0; /* Check if there's a reply message */ - Message = Thread->LpcReplyMessage; + Message = LpcpGetMessageFromThread(Thread); if (Message) { /* FIXME: TODO */ @@ -57,7 +57,7 @@ LpcpFreeToPortZone(IN PLPCP_MESSAGE Message, PETHREAD Thread = NULL; BOOLEAN LockHeld = Flags & 1, ReleaseLock = Flags & 2; PAGED_CODE(); - DPRINT1("Message: %p. Flags: %lx\n", Message, Flags); + LPCTRACE(LPC_CLOSE_DEBUG, "Message: %p. Flags: %lx\n", Message, Flags); /* Acquire the lock if not already */ if (!LockHeld) KeAcquireGuardedMutex(&LpcpLock); @@ -125,10 +125,10 @@ LpcpDestroyPortQueue(IN PLPCP_PORT_OBJECT Port, { /* Disconnect it */ Port->ConnectedPort->ConnectedPort = NULL; - if (Port->ConnectedPort->ConnectionPort) + ConnectionPort = Port->ConnectedPort->ConnectionPort; + if (ConnectionPort) { - /* Save and clear connection port */ - ConnectionPort = Port->ConnectedPort->ConnectionPort; + /* Clear connection port */ Port->ConnectedPort->ConnectionPort = NULL; } } @@ -162,7 +162,7 @@ LpcpDestroyPortQueue(IN PLPCP_PORT_OBJECT Port, if (!KeReadStateSemaphore(&Thread->LpcReplySemaphore)) { /* Get the message */ - Message = Thread->LpcReplyMessage; + Message = LpcpGetMessageFromThread(Thread); if (Message) { /* Check if it's a connection request */ @@ -198,7 +198,7 @@ LpcpDestroyPortQueue(IN PLPCP_PORT_OBJECT Port, /* Loop queued messages */ while ((Port->MsgQueue.ReceiveHead.Flink) && - !(IsListEmpty (&Port->MsgQueue.ReceiveHead))) + !(IsListEmpty(&Port->MsgQueue.ReceiveHead))) { /* Get the message */ Message = CONTAINING_RECORD(Port->MsgQueue.ReceiveHead.Flink, @@ -342,9 +342,6 @@ LpcpDeletePort(IN PVOID ObjectBody) /* Send it */ for (;;) { - /* FIXME: HACK OF D00m */ - break; - /* Send the message */ if (LpcRequestPort(Port, &ClientDiedMsg.h) != STATUS_NO_MEMORY) break; diff --git a/reactos/ntoskrnl/lpc/complete.c b/reactos/ntoskrnl/lpc/complete.c index 33c68860c7d..6acbd2f2540 100644 --- a/reactos/ntoskrnl/lpc/complete.c +++ b/reactos/ntoskrnl/lpc/complete.c @@ -88,7 +88,7 @@ NtAcceptConnectPort(OUT PHANDLE PortHandle, KeAcquireGuardedMutex(&LpcpLock); /* Make sure that the client wants a reply, and this is the right one */ - if (!(ClientThread->LpcReplyMessage) || + if (!(LpcpGetMessageFromThread(ClientThread)) || !(ReplyMessage->MessageId) || (ClientThread->LpcReplyMessageId != ReplyMessage->MessageId)) { @@ -100,7 +100,7 @@ NtAcceptConnectPort(OUT PHANDLE PortHandle, } /* Now get the message and connection message */ - Message = ClientThread->LpcReplyMessage; + Message = LpcpGetMessageFromThread(ClientThread); ConnectMessage = (PLPCP_CONNECTION_MESSAGE)(Message + 1); /* Get the client and connection port as well */ @@ -353,7 +353,7 @@ NtCompleteConnectPort(IN HANDLE PortHandle) Thread = Port->ClientThread; /* Make sure it has a reply message */ - if (!Thread->LpcReplyMessage) + if (!LpcpGetMessageFromThread(Thread)) { /* It doesn't, quit */ KeReleaseGuardedMutex(&LpcpLock); diff --git a/reactos/ntoskrnl/lpc/connect.c b/reactos/ntoskrnl/lpc/connect.c index da0dcde4784..6031ecedc75 100644 --- a/reactos/ntoskrnl/lpc/connect.c +++ b/reactos/ntoskrnl/lpc/connect.c @@ -35,7 +35,7 @@ LpcpFreeConMsg(IN OUT PLPCP_MESSAGE *Message, } /* Check if there's a reply message */ - ReplyMessage = CurrentThread->LpcReplyMessage; + ReplyMessage = LpcpGetMessageFromThread(CurrentThread); if (ReplyMessage) { /* Get the message */ @@ -54,7 +54,7 @@ LpcpFreeConMsg(IN OUT PLPCP_MESSAGE *Message, CurrentThread->LpcReplyMessage = NULL; /* Get the connection message and clear the section */ - *ConnectMessage = (PLPCP_CONNECTION_MESSAGE)(*Message + 1); + *ConnectMessage = (PLPCP_CONNECTION_MESSAGE)(ReplyMessage + 1); SectionToMap = (*ConnectMessage)->SectionToMap; (*ConnectMessage)->SectionToMap = NULL; } diff --git a/reactos/ntoskrnl/lpc/reply.c b/reactos/ntoskrnl/lpc/reply.c index ac421fbf915..ae6995148e9 100644 --- a/reactos/ntoskrnl/lpc/reply.c +++ b/reactos/ntoskrnl/lpc/reply.c @@ -279,12 +279,10 @@ NtReplyWaitReceivePortEx(IN HANDLE PortHandle, KeAcquireGuardedMutex(&LpcpLock); /* Make sure this is the reply the thread is waiting for */ - if ((WakeupThread->LpcReplyMessageId != ReplyMessage->MessageId))// || -#if 0 - ((WakeupThread->LpcReplyMessage) && - (LpcpGetMessageType(&((PLPCP_MESSAGE)WakeupThread-> - LpcReplyMessage)->Request) != LPC_REQUEST))) -#endif + if ((WakeupThread->LpcReplyMessageId != ReplyMessage->MessageId) || + ((LpcpGetMessageFromThread(WakeupThread)) && + (LpcpGetMessageType(&LpcpGetMessageFromThread(WakeupThread)-> + Request) != LPC_REQUEST))) { /* It isn't, fail */ LpcpFreeToPortZone(Message, 3); diff --git a/reactos/ntoskrnl/lpc/send.c b/reactos/ntoskrnl/lpc/send.c index 525267c1e84..952f4ae9595 100644 --- a/reactos/ntoskrnl/lpc/send.c +++ b/reactos/ntoskrnl/lpc/send.c @@ -155,8 +155,8 @@ LpcRequestPort(IN PVOID PortObject, /* We're done */ KeLeaveCriticalRegion(); - LPCTRACE(LPC_SEND_DEBUG, "Port: %p. Message: %p\n", QueuePort, Message); if (ConnectionPort) ObDereferenceObject(ConnectionPort); + LPCTRACE(LPC_SEND_DEBUG, "Port: %p. Message: %p\n", QueuePort, Message); return STATUS_SUCCESS; } @@ -366,7 +366,7 @@ NtRequestWaitReplyPort(IN HANDLE PortHandle, /* Insert the message in our chain */ InsertTailList(&QueuePort->MsgQueue.ReceiveHead, &Message->Entry); InsertTailList(&ReplyPort->LpcReplyChainHead, &Thread->LpcReplyChain); - Thread->LpcWaitingOnPort = Port; + LpcpSetPortToThread(Thread, Port); /* Release the lock and get the semaphore we'll use later */ KeEnterCriticalRegion(); @@ -392,7 +392,7 @@ NtRequestWaitReplyPort(IN HANDLE PortHandle, KeAcquireGuardedMutex(&LpcpLock); /* Get the LPC Message and clear our thread's reply data */ - Message = Thread->LpcReplyMessage; + Message = LpcpGetMessageFromThread(Thread); Thread->LpcReplyMessage = NULL; Thread->LpcReplyMessageId = 0;