Fixes for problems with NtReplyWaitReceive and KeWaitForSingleObject

svn path=/trunk/; revision=1540
This commit is contained in:
David Welch 2001-01-18 15:00:09 +00:00
parent 3116ca9df2
commit a8660c1f02
10 changed files with 268 additions and 312 deletions

View file

@ -3,8 +3,7 @@
#include <napi/lpc.h> #include <napi/lpc.h>
typedef typedef struct _EPORT
struct _EPORT
{ {
KSPIN_LOCK Lock; KSPIN_LOCK Lock;
KEVENT Event; KEVENT Event;
@ -21,7 +20,6 @@ struct _EPORT
ULONG MaxDataLength; ULONG MaxDataLength;
ULONG MaxConnectInfoLength; ULONG MaxConnectInfoLength;
} EPORT, * PEPORT; } EPORT, * PEPORT;
@ -29,22 +27,16 @@ typedef struct _EPORT_TERMINATION_REQUEST
{ {
LIST_ENTRY ThreadListEntry; LIST_ENTRY ThreadListEntry;
PEPORT Port; PEPORT Port;
} EPORT_TERMINATION_REQUEST, *PEPORT_TERMINATION_REQUEST; } EPORT_TERMINATION_REQUEST, *PEPORT_TERMINATION_REQUEST;
NTSTATUS STDCALL
LpcRequestPort (PEPORT Port,
PLPC_MESSAGE LpcMessage);
NTSTATUS NTSTATUS
STDCALL STDCALL
LpcRequestPort ( LpcSendTerminationPort (PEPORT Port,
PEPORT Port, TIME CreationTime);
PLPC_MESSAGE LpcMessage
);
NTSTATUS
STDCALL
LpcSendTerminationPort (
PEPORT Port,
TIME CreationTime
);
/* Port Object Access */ /* Port Object Access */
@ -63,14 +55,12 @@ LpcSendTerminationPort (
#define EPORT_CONNECTED_SERVER (6) #define EPORT_CONNECTED_SERVER (6)
#define EPORT_DISCONNECTED (7) #define EPORT_DISCONNECTED (7)
typedef typedef struct _QUEUEDMESSAGE
struct _QUEUEDMESSAGE
{ {
PEPORT Sender; PEPORT Sender;
LIST_ENTRY QueueListEntry; LIST_ENTRY QueueListEntry;
LPC_MESSAGE Message; LPC_MESSAGE Message;
UCHAR MessageData [MAX_MESSAGE_DATA]; UCHAR MessageData [MAX_MESSAGE_DATA];
} QUEUEDMESSAGE, *PQUEUEDMESSAGE; } QUEUEDMESSAGE, *PQUEUEDMESSAGE;
/* Code in ntoskrnl/lpc/close.h */ /* Code in ntoskrnl/lpc/close.h */

View file

@ -69,7 +69,7 @@ BOOLEAN KiTestAlert(VOID)
KeReleaseSpinLock(&PiApcLock, oldIrql); KeReleaseSpinLock(&PiApcLock, oldIrql);
return(FALSE); return(FALSE);
} }
KeGetCurrentThread()->ApcState.UserApcPending = 1; KeGetCurrentThread()->ApcState.UserApcPending++;
KeReleaseSpinLock(&PiApcLock, oldIrql); KeReleaseSpinLock(&PiApcLock, oldIrql);
return(TRUE); return(TRUE);
} }
@ -94,7 +94,6 @@ BOOLEAN KiDeliverUserApc(PKTRAP_FRAME TrapFrame)
DPRINT("KiDeliverUserApc(TrapFrame %x/%x)\n", TrapFrame, DPRINT("KiDeliverUserApc(TrapFrame %x/%x)\n", TrapFrame,
KeGetCurrentThread()->TrapFrame); KeGetCurrentThread()->TrapFrame);
Thread = KeGetCurrentThread(); Thread = KeGetCurrentThread();
KeAcquireSpinLock(&PiApcLock, &oldlvl);
/* /*
* Check for thread termination * Check for thread termination
@ -111,6 +110,8 @@ BOOLEAN KiDeliverUserApc(PKTRAP_FRAME TrapFrame)
KeReleaseSpinLock(&PiThreadListLock, oldlvl); KeReleaseSpinLock(&PiThreadListLock, oldlvl);
} }
KeAcquireSpinLock(&PiApcLock, &oldlvl);
current_entry = Thread->ApcState.ApcListHead[1].Flink; current_entry = Thread->ApcState.ApcListHead[1].Flink;
/* /*
@ -225,13 +226,9 @@ VOID STDCALL KiDeliverApc(ULONG Unknown1,
KeCallKernelRoutineApc(Apc); KeCallKernelRoutineApc(Apc);
KeAcquireSpinLock(&PiApcLock, &oldlvl); KeAcquireSpinLock(&PiApcLock, &oldlvl);
DPRINT("Called kernel routine for APC\n");
// PsFreezeThread(Thread, NULL, FALSE, KernelMode);
DPRINT("Done frozen thread\n");
Thread->Tcb.ApcState.KernelApcInProgress--; Thread->Tcb.ApcState.KernelApcInProgress--;
} }
KeReleaseSpinLock(&PiApcLock, oldlvl); KeReleaseSpinLock(&PiApcLock, oldlvl);
// Thread->Tcb.WaitStatus = STATUS_KERNEL_APC;
} }
VOID STDCALL VOID STDCALL
@ -285,6 +282,15 @@ KeInsertQueueApc (PKAPC Apc,
KeRemoveAllWaitsThread(CONTAINING_RECORD(TargetThread, ETHREAD, Tcb), KeRemoveAllWaitsThread(CONTAINING_RECORD(TargetThread, ETHREAD, Tcb),
STATUS_KERNEL_APC); STATUS_KERNEL_APC);
} }
/*
* For user mode APCs if the thread is already waiting then we wait it
* up and increment UserApcPending so it will deliver the APC on exit
* from kernel mode. If the thread isn't waiting then before it
* enters an alertable, user mode wait then it will check for
* user mode APCs and if there are any pending then return immediately
* and they will be delivered on exit from kernel mode
*/
if (Apc->ApcMode == UserMode && TargetThread->Alertable == TRUE && if (Apc->ApcMode == UserMode && TargetThread->Alertable == TRUE &&
TargetThread->WaitMode == UserMode) TargetThread->WaitMode == UserMode)
{ {

View file

@ -1,4 +1,4 @@
/* $Id: irq.c,v 1.3 2000/12/10 23:42:00 dwelch Exp $ /* $Id: irq.c,v 1.4 2001/01/18 15:00:08 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -190,24 +190,18 @@ KiInterruptDispatch (ULONG irq, PKIRQ_TRAPFRAME Trapframe)
HalEndSystemInterrupt (DISPATCH_LEVEL, 0); HalEndSystemInterrupt (DISPATCH_LEVEL, 0);
__asm__("sti\n\t"); __asm__("sti\n\t");
if (irq == 0)
{
KeExpireTimers();
}
if (KeGetCurrentThread() != NULL) if (KeGetCurrentThread() != NULL)
{ {
KeGetCurrentThread()->LastEip = Trapframe->Eip; KeGetCurrentThread()->LastEip = Trapframe->Eip;
} }
KiDispatchInterrupt(); KiDispatchInterrupt();
if (irq == 0)
{
PsDispatchThread(THREAD_STATE_RUNNABLE); PsDispatchThread(THREAD_STATE_RUNNABLE);
} }
else
{
// DbgPrint("$");
} }
HalEndSystemInterrupt (old_level, 0); HalEndSystemInterrupt (old_level, 0);
// DbgPrint("}");
} }

View file

@ -1,4 +1,4 @@
/* $Id: usercall.c,v 1.16 2000/10/11 20:50:34 dwelch Exp $ /* $Id: usercall.c,v 1.17 2001/01/18 15:00:08 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -44,12 +44,14 @@ VOID KiSystemCallHook(ULONG Nr, ...)
ULONG KiAfterSystemCallHook(ULONG NtStatus, PKTRAP_FRAME TrapFrame) ULONG KiAfterSystemCallHook(ULONG NtStatus, PKTRAP_FRAME TrapFrame)
{ {
assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
if (KeGetCurrentThread()->ApcState.UserApcPending == 0 || if (KeGetCurrentThread()->ApcState.UserApcPending == 0 ||
TrapFrame->Cs == KERNEL_CS) TrapFrame->Cs == KERNEL_CS)
{ {
return(NtStatus); return(NtStatus);
} }
KiDeliverUserApc(TrapFrame); KiDeliverUserApc(TrapFrame);
assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
return(NtStatus); return(NtStatus);
} }

View file

@ -422,37 +422,36 @@ NTSTATUS STDCALL KeWaitForSingleObject (PVOID Object,
return(STATUS_WAIT_0); return(STATUS_WAIT_0);
} }
CurrentThread->WaitStatus = STATUS_UNSUCCESSFUL;
/* Append wait block to the KTHREAD wait block list */ /* Append wait block to the KTHREAD wait block list */
CurrentThread->WaitBlockList = &CurrentThread->WaitBlock[0]; CurrentThread->WaitBlockList = &CurrentThread->WaitBlock[0];
CurrentThread->WaitBlock[0].Object = Object; CurrentThread->WaitBlock[0].Object = Object;
CurrentThread->WaitBlock[0].Thread = CurrentThread; CurrentThread->WaitBlock[0].Thread = CurrentThread;
CurrentThread->WaitBlock[0].WaitKey = 0; CurrentThread->WaitBlock[0].WaitKey = 0;
CurrentThread->WaitBlock[0].WaitType = WaitAny; CurrentThread->WaitBlock[0].WaitType = WaitAny;
CurrentThread->WaitBlock[0].NextWaitBlock = NULL; CurrentThread->WaitBlock[0].NextWaitBlock = NULL;
DPRINT("hdr->WaitListHead.Flink %x hdr->WaitListHead.Blink %x CurrentThread->WaitBlock[0].WaitListEntry = %x\n", InsertTailList(&hdr->WaitListHead,
hdr->WaitListHead.Flink,hdr->WaitListHead.Blink, CurrentThread->WaitBlock[0].WaitListEntry ); &CurrentThread->WaitBlock[0].WaitListEntry);
InsertTailList(&hdr->WaitListHead, &CurrentThread->WaitBlock[0].WaitListEntry);
KeReleaseDispatcherDatabaseLock(FALSE); KeReleaseDispatcherDatabaseLock(FALSE);
DPRINT("Waiting for %x with irql %d\n", Object, KeGetCurrentIrql()); DPRINT("Waiting for %x with irql %d\n", Object, KeGetCurrentIrql());
Status = STATUS_SUCCESS;
PsFreezeThread(PsGetCurrentThread(), PsFreezeThread(PsGetCurrentThread(),
&Status, &Status,
(UCHAR)Alertable, (UCHAR)Alertable,
WaitMode); WaitMode);
DPRINT("Woke from wait\n"); if (!NT_SUCCESS(Status))
{
DPRINT1("Woke from wait with status %x\n", Status);
}
} while (Status == STATUS_KERNEL_APC); } while (Status == STATUS_KERNEL_APC);
if (Timeout != NULL) if (Timeout != NULL)
{ {
KeCancelTimer(&KeGetCurrentThread()->Timer); KeCancelTimer(&KeGetCurrentThread()->Timer);
} }
if (Status == STATUS_USER_APC)
{
KiTestAlert();
}
DPRINT("Returning from KeWaitForSingleObject()\n"); DPRINT("Returning from KeWaitForSingleObject()\n");
return Status; return(Status);
} }

View file

@ -1,4 +1,4 @@
/* $Id: complete.c,v 1.2 2000/10/22 16:36:51 ekohl Exp $ /* $Id: complete.c,v 1.3 2001/01/18 15:00:08 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -26,9 +26,7 @@
* *
* *
*/ */
EXPORTED EXPORTED NTSTATUS STDCALL
NTSTATUS
STDCALL
NtCompleteConnectPort (HANDLE PortHandle) NtCompleteConnectPort (HANDLE PortHandle)
{ {
NTSTATUS Status; NTSTATUS Status;
@ -36,24 +34,18 @@ NtCompleteConnectPort (HANDLE PortHandle)
DPRINT("NtCompleteConnectPort(PortHandle %x)\n", PortHandle); DPRINT("NtCompleteConnectPort(PortHandle %x)\n", PortHandle);
Status = ObReferenceObjectByHandle ( Status = ObReferenceObjectByHandle (PortHandle,
PortHandle,
PORT_ALL_ACCESS, PORT_ALL_ACCESS,
ExPortType, ExPortType,
UserMode, UserMode,
(PVOID *) & OurPort, (PVOID*)&OurPort,
NULL NULL);
);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
return (Status); return (Status);
} }
KeSetEvent ( KeSetEvent (&OurPort->OtherPort->Event, IO_NO_INCREMENT, FALSE);
& OurPort->OtherPort->Event,
IO_NO_INCREMENT,
FALSE
);
OurPort->State = EPORT_CONNECTED_SERVER; OurPort->State = EPORT_CONNECTED_SERVER;

View file

@ -1,4 +1,4 @@
/* $Id: connect.c,v 1.2 2000/10/22 16:36:51 ekohl Exp $ /* $Id: connect.c,v 1.3 2001/01/18 15:00:09 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -41,18 +41,15 @@
* RETURN VALUE * RETURN VALUE
* *
*/ */
NTSTATUS NTSTATUS STDCALL
STDCALL NtConnectPort (PHANDLE ConnectedPort,
NtConnectPort (
PHANDLE ConnectedPort,
PUNICODE_STRING PortName, PUNICODE_STRING PortName,
PSECURITY_QUALITY_OF_SERVICE Qos, PSECURITY_QUALITY_OF_SERVICE Qos,
PLPC_SECTION_WRITE WriteMap, PLPC_SECTION_WRITE WriteMap,
PLPC_SECTION_READ ReadMap, PLPC_SECTION_READ ReadMap,
PULONG MaxMessageSize, PULONG MaxMessageSize,
PVOID ConnectInfo, PVOID ConnectInfo,
PULONG UserConnectInfoLength PULONG UserConnectInfoLength)
)
{ {
NTSTATUS Status; NTSTATUS Status;
PEPORT NamedPort; PEPORT NamedPort;
@ -69,24 +66,20 @@ NtConnectPort (
/* /*
* Copy in user parameters * Copy in user parameters
*/ */
memcpy ( memcpy (&ConnectInfoLength, UserConnectInfoLength,
& ConnectInfoLength, sizeof (*UserConnectInfoLength));
UserConnectInfoLength,
sizeof (*UserConnectInfoLength)
);
/* /*
* Get access to the port * Get access to the port
*/ */
Status = ObReferenceObjectByName ( Status = ObReferenceObjectByName (PortName,
PortName,
0, 0,
NULL, NULL,
PORT_ALL_ACCESS, /* DesiredAccess */ PORT_ALL_ACCESS, /* DesiredAccess */
ExPortType, ExPortType,
UserMode, UserMode,
NULL, NULL,
(PVOID *) & NamedPort (PVOID*)&NamedPort);
);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("Failed to reference named port (status %x)\n", Status); DPRINT("Failed to reference named port (status %x)\n", Status);
@ -95,81 +88,53 @@ NtConnectPort (
/* /*
* Create a port to represent our side of the connection * Create a port to represent our side of the connection
*/ */
OurPort = ObCreateObject ( OurPort = ObCreateObject (&OurPortHandle,
& OurPortHandle,
PORT_ALL_ACCESS, PORT_ALL_ACCESS,
NULL, NULL,
ExPortType ExPortType);
);
NiInitializePort(OurPort); NiInitializePort(OurPort);
/* /*
* Create a request message * Create a request message
*/ */
DPRINT("Creating request message\n"); DPRINT("Creating request message\n");
Request = ExAllocatePool ( Request = ExAllocatePool (NonPagedPool,
NonPagedPool, (sizeof (LPC_MESSAGE) + ConnectInfoLength));
(sizeof (LPC_MESSAGE) + ConnectInfoLength)
);
Request->DataSize = ConnectInfoLength; Request->DataSize = ConnectInfoLength;
Request->MessageSize = sizeof(LPC_MESSAGE) + ConnectInfoLength; Request->MessageSize = sizeof(LPC_MESSAGE) + ConnectInfoLength;
Request->SharedSectionSize = 0; Request->SharedSectionSize = 0;
if ( (ConnectInfo != NULL) if ((ConnectInfo != NULL) && (ConnectInfoLength > 0))
&& (ConnectInfoLength > 0)
)
{ {
memcpy ( memcpy ((PVOID) (Request + 1), ConnectInfo, ConnectInfoLength);
(PVOID) (Request + 1),
ConnectInfo,
ConnectInfoLength
);
} }
/* /*
* Queue the message to the named port * Queue the message to the named port
*/ */
DPRINT("Queuing message\n"); DPRINT("Queuing message\n");
EiReplyOrRequestPort ( EiReplyOrRequestPort (NamedPort,
NamedPort,
Request, Request,
LPC_CONNECTION_REQUEST, LPC_CONNECTION_REQUEST,
OurPort OurPort);
); KeSetEvent (&NamedPort->Event, IO_NO_INCREMENT, FALSE);
KeSetEvent (
& NamedPort->Event,
IO_NO_INCREMENT,
FALSE
);
DPRINT("Waiting for connection completion\n"); DPRINT("Waiting for connection completion\n");
/* /*
* Wait for them to accept our connection * Wait for them to accept our connection
*/ */
KeWaitForSingleObject ( KeWaitForSingleObject (&OurPort->Event,
& OurPort->Event,
UserRequest, UserRequest,
UserMode, UserMode,
FALSE, FALSE,
NULL NULL);
);
DPRINT("Received connection completion\n"); DPRINT("Received connection completion\n");
KeAcquireSpinLock ( KeAcquireSpinLock (&OurPort->Lock, &oldIrql);
& OurPort->Lock,
& oldIrql
);
Reply = EiDequeueMessagePort (OurPort); Reply = EiDequeueMessagePort (OurPort);
KeReleaseSpinLock ( KeReleaseSpinLock (&OurPort->Lock, oldIrql);
& OurPort->Lock, memcpy (ConnectInfo, Reply->MessageData, Reply->Message.DataSize);
oldIrql
);
memcpy (
ConnectInfo,
Reply->MessageData,
Reply->Message.DataSize
);
*UserConnectInfoLength = Reply->Message.DataSize; *UserConnectInfoLength = Reply->Message.DataSize;
if (Reply->Message.MessageType == LPC_CONNECTION_REFUSED) if (Reply->Message.MessageType == LPC_CONNECTION_REFUSED)
@ -210,17 +175,13 @@ NtConnectPort (
* RETURN VALUE * RETURN VALUE
* *
*/ */
EXPORTED EXPORTED NTSTATUS STDCALL
NTSTATUS NtAcceptConnectPort (PHANDLE ServerPortHandle,
STDCALL
NtAcceptConnectPort (
PHANDLE ServerPortHandle,
HANDLE NamedPortHandle, HANDLE NamedPortHandle,
PLPC_MESSAGE LpcMessage, PLPC_MESSAGE LpcMessage,
BOOLEAN AcceptIt, BOOLEAN AcceptIt,
PLPC_SECTION_WRITE WriteMap, PLPC_SECTION_WRITE WriteMap,
PLPC_SECTION_READ ReadMap PLPC_SECTION_READ ReadMap)
)
{ {
NTSTATUS Status; NTSTATUS Status;
PEPORT NamedPort; PEPORT NamedPort;
@ -228,14 +189,12 @@ NtAcceptConnectPort (
PQUEUEDMESSAGE ConnectionRequest; PQUEUEDMESSAGE ConnectionRequest;
KIRQL oldIrql; KIRQL oldIrql;
Status = ObReferenceObjectByHandle ( Status = ObReferenceObjectByHandle (NamedPortHandle,
NamedPortHandle,
PORT_ALL_ACCESS, PORT_ALL_ACCESS,
ExPortType, ExPortType,
UserMode, UserMode,
(PVOID *) & NamedPort, (PVOID*)&NamedPort,
NULL NULL);
);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
return (Status); return (Status);
@ -245,34 +204,28 @@ NtAcceptConnectPort (
*/ */
if (AcceptIt == 1) if (AcceptIt == 1)
{ {
OurPort = ObCreateObject ( OurPort = ObCreateObject (ServerPortHandle,
ServerPortHandle,
PORT_ALL_ACCESS, PORT_ALL_ACCESS,
NULL, NULL,
ExPortType ExPortType);
);
NiInitializePort(OurPort); NiInitializePort(OurPort);
} }
/* /*
* Dequeue the connection request * Dequeue the connection request
*/ */
KeAcquireSpinLock (& NamedPort->Lock, & oldIrql); KeAcquireSpinLock (&NamedPort->Lock, & oldIrql);
ConnectionRequest = EiDequeueConnectMessagePort (NamedPort); ConnectionRequest = EiDequeueConnectMessagePort (NamedPort);
KeReleaseSpinLock (& NamedPort->Lock, oldIrql); KeReleaseSpinLock (&NamedPort->Lock, oldIrql);
if (AcceptIt != 1) if (AcceptIt != 1)
{ {
EiReplyOrRequestPort ( EiReplyOrRequestPort (ConnectionRequest->Sender,
ConnectionRequest->Sender,
LpcMessage, LpcMessage,
LPC_CONNECTION_REFUSED, LPC_CONNECTION_REFUSED,
NamedPort NamedPort);
); KeSetEvent (&ConnectionRequest->Sender->Event,
KeSetEvent (
& ConnectionRequest->Sender->Event,
IO_NO_INCREMENT, IO_NO_INCREMENT,
FALSE FALSE);
);
ObDereferenceObject (ConnectionRequest->Sender); ObDereferenceObject (ConnectionRequest->Sender);
ExFreePool (ConnectionRequest); ExFreePool (ConnectionRequest);
ObDereferenceObject (NamedPort); ObDereferenceObject (NamedPort);
@ -283,12 +236,10 @@ NtAcceptConnectPort (
*/ */
OurPort->OtherPort = ConnectionRequest->Sender; OurPort->OtherPort = ConnectionRequest->Sender;
OurPort->OtherPort->OtherPort = OurPort; OurPort->OtherPort->OtherPort = OurPort;
EiReplyOrRequestPort ( EiReplyOrRequestPort (ConnectionRequest->Sender,
ConnectionRequest->Sender,
LpcMessage, LpcMessage,
LPC_REPLY, LPC_REPLY,
OurPort OurPort);
);
ExFreePool (ConnectionRequest); ExFreePool (ConnectionRequest);
ObDereferenceObject (OurPort); ObDereferenceObject (OurPort);

View file

@ -1,4 +1,4 @@
/* $Id: reply.c,v 1.3 2000/12/28 03:38:07 dwelch Exp $ /* $Id: reply.c,v 1.4 2001/01/18 15:00:09 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -42,6 +42,11 @@ EiReplyOrRequestPort (IN PEPORT Port,
KIRQL oldIrql; KIRQL oldIrql;
PQUEUEDMESSAGE MessageReply; PQUEUEDMESSAGE MessageReply;
if (Port == NULL)
{
KeBugCheck(0);
}
MessageReply = ExAllocatePool(NonPagedPool, sizeof(QUEUEDMESSAGE)); MessageReply = ExAllocatePool(NonPagedPool, sizeof(QUEUEDMESSAGE));
MessageReply->Sender = Sender; MessageReply->Sender = Sender;
@ -142,10 +147,19 @@ NtReplyWaitReceivePort (HANDLE PortHandle,
NULL); NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("NtReplyWaitReceivePort() = %x\n", Status); DPRINT1("NtReplyWaitReceivePort() = %x\n", Status);
return(Status); return(Status);
} }
if (Port->State != EPORT_CONNECTED_CLIENT &&
Port->State != EPORT_CONNECTED_SERVER &&
LpcReply != NULL)
{
DPRINT1("NtReplyWaitReceivePort() = %x (State was %x)\n",
STATUS_PORT_DISCONNECTED, Port->State);
return(STATUS_PORT_DISCONNECTED);
}
/* /*
* Send the reply * Send the reply
*/ */
@ -160,6 +174,7 @@ NtReplyWaitReceivePort (HANDLE PortHandle,
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
ObDereferenceObject(Port); ObDereferenceObject(Port);
DPRINT1("NtReplyWaitReceivePort() = %x\n", Status);
return(Status); return(Status);
} }
} }
@ -176,6 +191,7 @@ NtReplyWaitReceivePort (HANDLE PortHandle,
NULL); NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("NtReplyWaitReceivePort() = %x\n", Status);
return(Status); return(Status);
} }
@ -186,7 +202,7 @@ NtReplyWaitReceivePort (HANDLE PortHandle,
Request = EiDequeueMessagePort(Port); Request = EiDequeueMessagePort(Port);
/* /*
* There is a race between the event being set and the port being * There is a race between the event being set and the port lock being
* taken in which another thread may dequeue the same request so * taken in which another thread may dequeue the same request so
* we may need to loop. * we may need to loop.
*/ */

View file

@ -1,4 +1,4 @@
/* $Id: thread.c,v 1.64 2000/12/26 05:32:44 dwelch Exp $ /* $Id: thread.c,v 1.65 2001/01/18 15:00:09 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -225,6 +225,10 @@ ULONG PsUnfreezeThread(PETHREAD Thread, PNTSTATUS WaitStatus)
if (WaitStatus != NULL) if (WaitStatus != NULL)
{ {
if (!NT_SUCCESS((*WaitStatus)))
{
KeBugCheck(0);
}
Thread->Tcb.WaitStatus = *WaitStatus; Thread->Tcb.WaitStatus = *WaitStatus;
} }

View file

@ -1,4 +1,4 @@
/* $Id: wapi.c,v 1.9 2000/07/11 04:09:25 phreak Exp $ /* $Id: wapi.c,v 1.10 2001/01/18 15:00:09 dwelch Exp $
* *
* reactos/subsys/csrss/api/wapi.c * reactos/subsys/csrss/api/wapi.c
* *
@ -63,12 +63,14 @@ static void Thread_Api2(HANDLE ServerPort)
0, 0,
&Reply->Header, &Reply->Header,
&LpcRequest.Header); &LpcRequest.Header);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status) &&
Status != STATUS_PORT_DISCONNECTED)
{ {
DisplayString(L"CSR: NtReplyWaitReceivePort failed\n"); DisplayString(L"CSR: NtReplyWaitReceivePort failed\n");
} }
if (LpcRequest.Header.MessageType == LPC_PORT_CLOSED) if (LpcRequest.Header.MessageType == LPC_PORT_CLOSED ||
Status == STATUS_PORT_DISCONNECTED)
{ {
CsrFreeProcessData( LpcRequest.Header.Cid.UniqueProcess ); CsrFreeProcessData( LpcRequest.Header.Cid.UniqueProcess );
NtClose(ServerPort); NtClose(ServerPort);