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

View file

@ -69,7 +69,7 @@ BOOLEAN KiTestAlert(VOID)
KeReleaseSpinLock(&PiApcLock, oldIrql);
return(FALSE);
}
KeGetCurrentThread()->ApcState.UserApcPending = 1;
KeGetCurrentThread()->ApcState.UserApcPending++;
KeReleaseSpinLock(&PiApcLock, oldIrql);
return(TRUE);
}
@ -94,7 +94,6 @@ BOOLEAN KiDeliverUserApc(PKTRAP_FRAME TrapFrame)
DPRINT("KiDeliverUserApc(TrapFrame %x/%x)\n", TrapFrame,
KeGetCurrentThread()->TrapFrame);
Thread = KeGetCurrentThread();
KeAcquireSpinLock(&PiApcLock, &oldlvl);
/*
* Check for thread termination
@ -111,6 +110,8 @@ BOOLEAN KiDeliverUserApc(PKTRAP_FRAME TrapFrame)
KeReleaseSpinLock(&PiThreadListLock, oldlvl);
}
KeAcquireSpinLock(&PiApcLock, &oldlvl);
current_entry = Thread->ApcState.ApcListHead[1].Flink;
/*
@ -225,13 +226,9 @@ VOID STDCALL KiDeliverApc(ULONG Unknown1,
KeCallKernelRoutineApc(Apc);
KeAcquireSpinLock(&PiApcLock, &oldlvl);
DPRINT("Called kernel routine for APC\n");
// PsFreezeThread(Thread, NULL, FALSE, KernelMode);
DPRINT("Done frozen thread\n");
Thread->Tcb.ApcState.KernelApcInProgress--;
}
KeReleaseSpinLock(&PiApcLock, oldlvl);
// Thread->Tcb.WaitStatus = STATUS_KERNEL_APC;
}
VOID STDCALL
@ -285,6 +282,15 @@ KeInsertQueueApc (PKAPC Apc,
KeRemoveAllWaitsThread(CONTAINING_RECORD(TargetThread, ETHREAD, Tcb),
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 &&
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
* PROJECT: ReactOS kernel
@ -190,24 +190,18 @@ KiInterruptDispatch (ULONG irq, PKIRQ_TRAPFRAME Trapframe)
HalEndSystemInterrupt (DISPATCH_LEVEL, 0);
__asm__("sti\n\t");
if (irq == 0)
{
KeExpireTimers();
}
if (KeGetCurrentThread() != NULL)
{
KeGetCurrentThread()->LastEip = Trapframe->Eip;
}
KiDispatchInterrupt();
PsDispatchThread(THREAD_STATE_RUNNABLE);
}
else
{
// DbgPrint("$");
if (irq == 0)
{
PsDispatchThread(THREAD_STATE_RUNNABLE);
}
}
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
* PROJECT: ReactOS kernel
@ -44,12 +44,14 @@ VOID KiSystemCallHook(ULONG Nr, ...)
ULONG KiAfterSystemCallHook(ULONG NtStatus, PKTRAP_FRAME TrapFrame)
{
assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
if (KeGetCurrentThread()->ApcState.UserApcPending == 0 ||
TrapFrame->Cs == KERNEL_CS)
{
return(NtStatus);
}
KiDeliverUserApc(TrapFrame);
assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
return(NtStatus);
}

View file

@ -422,37 +422,36 @@ NTSTATUS STDCALL KeWaitForSingleObject (PVOID Object,
return(STATUS_WAIT_0);
}
CurrentThread->WaitStatus = STATUS_UNSUCCESSFUL;
/* 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].Thread = CurrentThread;
CurrentThread->WaitBlock[0].WaitKey = 0;
CurrentThread->WaitBlock[0].WaitType = WaitAny;
CurrentThread->WaitBlock[0].NextWaitBlock = NULL;
DPRINT("hdr->WaitListHead.Flink %x hdr->WaitListHead.Blink %x CurrentThread->WaitBlock[0].WaitListEntry = %x\n",
hdr->WaitListHead.Flink,hdr->WaitListHead.Blink, CurrentThread->WaitBlock[0].WaitListEntry );
InsertTailList(&hdr->WaitListHead, &CurrentThread->WaitBlock[0].WaitListEntry);
InsertTailList(&hdr->WaitListHead,
&CurrentThread->WaitBlock[0].WaitListEntry);
KeReleaseDispatcherDatabaseLock(FALSE);
DPRINT("Waiting for %x with irql %d\n", Object, KeGetCurrentIrql());
Status = STATUS_SUCCESS;
PsFreezeThread(PsGetCurrentThread(),
&Status,
(UCHAR)Alertable,
WaitMode);
DPRINT("Woke from wait\n");
if (!NT_SUCCESS(Status))
{
DPRINT1("Woke from wait with status %x\n", Status);
}
} while (Status == STATUS_KERNEL_APC);
if (Timeout != NULL)
{
KeCancelTimer(&KeGetCurrentThread()->Timer);
}
if (Status == STATUS_USER_APC)
{
KiTestAlert();
}
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
* PROJECT: ReactOS kernel
@ -26,40 +26,32 @@
*
*
*/
EXPORTED
NTSTATUS
STDCALL
EXPORTED NTSTATUS STDCALL
NtCompleteConnectPort (HANDLE PortHandle)
{
NTSTATUS Status;
PEPORT OurPort;
NTSTATUS Status;
PEPORT OurPort;
DPRINT("NtCompleteConnectPort(PortHandle %x)\n", PortHandle);
Status = ObReferenceObjectByHandle (PortHandle,
PORT_ALL_ACCESS,
ExPortType,
UserMode,
(PVOID*)&OurPort,
NULL);
if (!NT_SUCCESS(Status))
{
return (Status);
}
KeSetEvent (&OurPort->OtherPort->Event, IO_NO_INCREMENT, FALSE);
DPRINT("NtCompleteConnectPort(PortHandle %x)\n", PortHandle);
Status = ObReferenceObjectByHandle (
PortHandle,
PORT_ALL_ACCESS,
ExPortType,
UserMode,
(PVOID *) & OurPort,
NULL
);
if (!NT_SUCCESS(Status))
{
return (Status);
}
KeSetEvent (
& OurPort->OtherPort->Event,
IO_NO_INCREMENT,
FALSE
);
OurPort->State = EPORT_CONNECTED_SERVER;
ObDereferenceObject (OurPort);
return (STATUS_SUCCESS);
OurPort->State = EPORT_CONNECTED_SERVER;
ObDereferenceObject (OurPort);
return (STATUS_SUCCESS);
}

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
* PROJECT: ReactOS kernel
@ -41,155 +41,120 @@
* RETURN VALUE
*
*/
NTSTATUS
STDCALL
NtConnectPort (
PHANDLE ConnectedPort,
PUNICODE_STRING PortName,
PSECURITY_QUALITY_OF_SERVICE Qos,
PLPC_SECTION_WRITE WriteMap,
PLPC_SECTION_READ ReadMap,
PULONG MaxMessageSize,
PVOID ConnectInfo,
PULONG UserConnectInfoLength
)
NTSTATUS STDCALL
NtConnectPort (PHANDLE ConnectedPort,
PUNICODE_STRING PortName,
PSECURITY_QUALITY_OF_SERVICE Qos,
PLPC_SECTION_WRITE WriteMap,
PLPC_SECTION_READ ReadMap,
PULONG MaxMessageSize,
PVOID ConnectInfo,
PULONG UserConnectInfoLength)
{
NTSTATUS Status;
PEPORT NamedPort;
PEPORT OurPort;
HANDLE OurPortHandle;
PLPC_MESSAGE Request;
PQUEUEDMESSAGE Reply;
ULONG ConnectInfoLength;
KIRQL oldIrql;
NTSTATUS Status;
PEPORT NamedPort;
PEPORT OurPort;
HANDLE OurPortHandle;
PLPC_MESSAGE Request;
PQUEUEDMESSAGE Reply;
ULONG ConnectInfoLength;
KIRQL oldIrql;
DPRINT("PortName %x\n", PortName);
DPRINT("NtConnectPort(PortName %S)\n", PortName->Buffer);
/*
* Copy in user parameters
*/
memcpy (
& ConnectInfoLength,
UserConnectInfoLength,
sizeof (*UserConnectInfoLength)
);
/*
* Get access to the port
*/
Status = ObReferenceObjectByName (
PortName,
0,
NULL,
PORT_ALL_ACCESS, /* DesiredAccess */
ExPortType,
UserMode,
NULL,
(PVOID *) & NamedPort
);
if (!NT_SUCCESS(Status))
{
DPRINT("Failed to reference named port (status %x)\n", Status);
return (Status);
}
/*
* Create a port to represent our side of the connection
*/
OurPort = ObCreateObject (
& OurPortHandle,
PORT_ALL_ACCESS,
NULL,
ExPortType
);
NiInitializePort(OurPort);
/*
* Create a request message
*/
DPRINT("Creating request message\n");
Request = ExAllocatePool (
NonPagedPool,
(sizeof (LPC_MESSAGE) + ConnectInfoLength)
);
Request->DataSize = ConnectInfoLength;
Request->MessageSize = sizeof(LPC_MESSAGE) + ConnectInfoLength;
Request->SharedSectionSize = 0;
if ( (ConnectInfo != NULL)
&& (ConnectInfoLength > 0)
)
{
memcpy (
(PVOID) (Request + 1),
ConnectInfo,
ConnectInfoLength
);
}
/*
* Queue the message to the named port
*/
DPRINT("Queuing message\n");
EiReplyOrRequestPort (
NamedPort,
Request,
LPC_CONNECTION_REQUEST,
OurPort
);
KeSetEvent (
& NamedPort->Event,
IO_NO_INCREMENT,
FALSE
);
DPRINT("Waiting for connection completion\n");
/*
* Wait for them to accept our connection
*/
KeWaitForSingleObject (
& OurPort->Event,
UserRequest,
UserMode,
FALSE,
NULL
);
DPRINT("PortName %x\n", PortName);
DPRINT("NtConnectPort(PortName %S)\n", PortName->Buffer);
/*
* Copy in user parameters
*/
memcpy (&ConnectInfoLength, UserConnectInfoLength,
sizeof (*UserConnectInfoLength));
DPRINT("Received connection completion\n");
KeAcquireSpinLock (
& OurPort->Lock,
& oldIrql
);
Reply = EiDequeueMessagePort (OurPort);
KeReleaseSpinLock (
& OurPort->Lock,
oldIrql
);
memcpy (
ConnectInfo,
Reply->MessageData,
Reply->Message.DataSize
);
*UserConnectInfoLength = Reply->Message.DataSize;
/*
* Get access to the port
*/
Status = ObReferenceObjectByName (PortName,
0,
NULL,
PORT_ALL_ACCESS, /* DesiredAccess */
ExPortType,
UserMode,
NULL,
(PVOID*)&NamedPort);
if (!NT_SUCCESS(Status))
{
DPRINT("Failed to reference named port (status %x)\n", Status);
return (Status);
}
/*
* Create a port to represent our side of the connection
*/
OurPort = ObCreateObject (&OurPortHandle,
PORT_ALL_ACCESS,
NULL,
ExPortType);
NiInitializePort(OurPort);
/*
* Create a request message
*/
DPRINT("Creating request message\n");
Request = ExAllocatePool (NonPagedPool,
(sizeof (LPC_MESSAGE) + ConnectInfoLength));
if (Reply->Message.MessageType == LPC_CONNECTION_REFUSED)
{
ObDereferenceObject (NamedPort);
ObDereferenceObject (OurPort);
ZwClose (OurPortHandle);
ExFreePool (Request);
ExFreePool (Reply);
return (STATUS_UNSUCCESSFUL);
}
Request->DataSize = ConnectInfoLength;
Request->MessageSize = sizeof(LPC_MESSAGE) + ConnectInfoLength;
Request->SharedSectionSize = 0;
if ((ConnectInfo != NULL) && (ConnectInfoLength > 0))
{
memcpy ((PVOID) (Request + 1), ConnectInfo, ConnectInfoLength);
}
/*
* Queue the message to the named port
*/
DPRINT("Queuing message\n");
EiReplyOrRequestPort (NamedPort,
Request,
LPC_CONNECTION_REQUEST,
OurPort);
KeSetEvent (&NamedPort->Event, IO_NO_INCREMENT, FALSE);
OurPort->State = EPORT_CONNECTED_CLIENT;
*ConnectedPort = OurPortHandle;
ExFreePool (Reply);
ExFreePool (Request);
DPRINT("Exited successfully\n");
return (STATUS_SUCCESS);
DPRINT("Waiting for connection completion\n");
/*
* Wait for them to accept our connection
*/
KeWaitForSingleObject (&OurPort->Event,
UserRequest,
UserMode,
FALSE,
NULL);
DPRINT("Received connection completion\n");
KeAcquireSpinLock (&OurPort->Lock, &oldIrql);
Reply = EiDequeueMessagePort (OurPort);
KeReleaseSpinLock (&OurPort->Lock, oldIrql);
memcpy (ConnectInfo, Reply->MessageData, Reply->Message.DataSize);
*UserConnectInfoLength = Reply->Message.DataSize;
if (Reply->Message.MessageType == LPC_CONNECTION_REFUSED)
{
ObDereferenceObject (NamedPort);
ObDereferenceObject (OurPort);
ZwClose (OurPortHandle);
ExFreePool (Request);
ExFreePool (Reply);
return (STATUS_UNSUCCESSFUL);
}
OurPort->State = EPORT_CONNECTED_CLIENT;
*ConnectedPort = OurPortHandle;
ExFreePool (Reply);
ExFreePool (Request);
DPRINT("Exited successfully\n");
return (STATUS_SUCCESS);
}
@ -210,91 +175,77 @@ NtConnectPort (
* RETURN VALUE
*
*/
EXPORTED
NTSTATUS
STDCALL
NtAcceptConnectPort (
PHANDLE ServerPortHandle,
HANDLE NamedPortHandle,
PLPC_MESSAGE LpcMessage,
BOOLEAN AcceptIt,
PLPC_SECTION_WRITE WriteMap,
PLPC_SECTION_READ ReadMap
)
EXPORTED NTSTATUS STDCALL
NtAcceptConnectPort (PHANDLE ServerPortHandle,
HANDLE NamedPortHandle,
PLPC_MESSAGE LpcMessage,
BOOLEAN AcceptIt,
PLPC_SECTION_WRITE WriteMap,
PLPC_SECTION_READ ReadMap)
{
NTSTATUS Status;
PEPORT NamedPort;
PEPORT OurPort = NULL;
PQUEUEDMESSAGE ConnectionRequest;
KIRQL oldIrql;
Status = ObReferenceObjectByHandle (
NamedPortHandle,
PORT_ALL_ACCESS,
ExPortType,
UserMode,
(PVOID *) & NamedPort,
NULL
);
if (!NT_SUCCESS(Status))
{
return (Status);
}
/*
* Create a port object for our side of the connection
*/
if (AcceptIt == 1)
{
OurPort = ObCreateObject (
ServerPortHandle,
NTSTATUS Status;
PEPORT NamedPort;
PEPORT OurPort = NULL;
PQUEUEDMESSAGE ConnectionRequest;
KIRQL oldIrql;
Status = ObReferenceObjectByHandle (NamedPortHandle,
PORT_ALL_ACCESS,
ExPortType,
UserMode,
(PVOID*)&NamedPort,
NULL);
if (!NT_SUCCESS(Status))
{
return (Status);
}
/*
* Create a port object for our side of the connection
*/
if (AcceptIt == 1)
{
OurPort = ObCreateObject (ServerPortHandle,
PORT_ALL_ACCESS,
NULL,
ExPortType
);
NiInitializePort(OurPort);
}
/*
* Dequeue the connection request
*/
KeAcquireSpinLock (& NamedPort->Lock, & oldIrql);
ConnectionRequest = EiDequeueConnectMessagePort (NamedPort);
KeReleaseSpinLock (& NamedPort->Lock, oldIrql);
if (AcceptIt != 1)
{
EiReplyOrRequestPort (
ConnectionRequest->Sender,
ExPortType);
NiInitializePort(OurPort);
}
/*
* Dequeue the connection request
*/
KeAcquireSpinLock (&NamedPort->Lock, & oldIrql);
ConnectionRequest = EiDequeueConnectMessagePort (NamedPort);
KeReleaseSpinLock (&NamedPort->Lock, oldIrql);
if (AcceptIt != 1)
{
EiReplyOrRequestPort (ConnectionRequest->Sender,
LpcMessage,
LPC_CONNECTION_REFUSED,
NamedPort);
KeSetEvent (&ConnectionRequest->Sender->Event,
IO_NO_INCREMENT,
FALSE);
ObDereferenceObject (ConnectionRequest->Sender);
ExFreePool (ConnectionRequest);
ObDereferenceObject (NamedPort);
return (STATUS_SUCCESS);
}
/*
* Connect the two ports
*/
OurPort->OtherPort = ConnectionRequest->Sender;
OurPort->OtherPort->OtherPort = OurPort;
EiReplyOrRequestPort (ConnectionRequest->Sender,
LpcMessage,
LPC_CONNECTION_REFUSED,
NamedPort
);
KeSetEvent (
& ConnectionRequest->Sender->Event,
IO_NO_INCREMENT,
FALSE
);
ObDereferenceObject (ConnectionRequest->Sender);
ExFreePool (ConnectionRequest);
ObDereferenceObject (NamedPort);
return (STATUS_SUCCESS);
}
/*
* Connect the two ports
*/
OurPort->OtherPort = ConnectionRequest->Sender;
OurPort->OtherPort->OtherPort = OurPort;
EiReplyOrRequestPort (
ConnectionRequest->Sender,
LpcMessage,
LPC_REPLY,
OurPort
);
ExFreePool (ConnectionRequest);
LPC_REPLY,
OurPort);
ExFreePool (ConnectionRequest);
ObDereferenceObject (OurPort);
ObDereferenceObject (NamedPort);
return (STATUS_SUCCESS);
ObDereferenceObject (OurPort);
ObDereferenceObject (NamedPort);
return (STATUS_SUCCESS);
}

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
* PROJECT: ReactOS kernel
@ -42,6 +42,11 @@ EiReplyOrRequestPort (IN PEPORT Port,
KIRQL oldIrql;
PQUEUEDMESSAGE MessageReply;
if (Port == NULL)
{
KeBugCheck(0);
}
MessageReply = ExAllocatePool(NonPagedPool, sizeof(QUEUEDMESSAGE));
MessageReply->Sender = Sender;
@ -142,10 +147,19 @@ NtReplyWaitReceivePort (HANDLE PortHandle,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT("NtReplyWaitReceivePort() = %x\n", Status);
DPRINT1("NtReplyWaitReceivePort() = %x\n", 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
*/
@ -160,6 +174,7 @@ NtReplyWaitReceivePort (HANDLE PortHandle,
if (!NT_SUCCESS(Status))
{
ObDereferenceObject(Port);
DPRINT1("NtReplyWaitReceivePort() = %x\n", Status);
return(Status);
}
}
@ -176,6 +191,7 @@ NtReplyWaitReceivePort (HANDLE PortHandle,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtReplyWaitReceivePort() = %x\n", Status);
return(Status);
}
@ -186,7 +202,7 @@ NtReplyWaitReceivePort (HANDLE PortHandle,
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
* 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
* PROJECT: ReactOS kernel
@ -225,7 +225,11 @@ ULONG PsUnfreezeThread(PETHREAD Thread, PNTSTATUS WaitStatus)
if (WaitStatus != NULL)
{
Thread->Tcb.WaitStatus = *WaitStatus;
if (!NT_SUCCESS((*WaitStatus)))
{
KeBugCheck(0);
}
Thread->Tcb.WaitStatus = *WaitStatus;
}
if (r <= 0)

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
*
@ -63,12 +63,14 @@ static void Thread_Api2(HANDLE ServerPort)
0,
&Reply->Header,
&LpcRequest.Header);
if (!NT_SUCCESS(Status))
if (!NT_SUCCESS(Status) &&
Status != STATUS_PORT_DISCONNECTED)
{
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 );
NtClose(ServerPort);