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,30 +20,23 @@ struct _EPORT
ULONG MaxDataLength; ULONG MaxDataLength;
ULONG MaxConnectInfoLength; ULONG MaxConnectInfoLength;
} EPORT, * PEPORT; } EPORT, * PEPORT;
typedef struct _EPORT_TERMINATION_REQUEST 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();
PsDispatchThread(THREAD_STATE_RUNNABLE); if (irq == 0)
} {
else PsDispatchThread(THREAD_STATE_RUNNABLE);
{ }
// 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,40 +26,32 @@
* *
* *
*/ */
EXPORTED EXPORTED NTSTATUS STDCALL
NTSTATUS
STDCALL
NtCompleteConnectPort (HANDLE PortHandle) NtCompleteConnectPort (HANDLE PortHandle)
{ {
NTSTATUS Status; NTSTATUS Status;
PEPORT OurPort; 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); OurPort->State = EPORT_CONNECTED_SERVER;
Status = ObReferenceObjectByHandle ( ObDereferenceObject (OurPort);
PortHandle,
PORT_ALL_ACCESS, return (STATUS_SUCCESS);
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);
} }

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,155 +41,120 @@
* RETURN VALUE * RETURN VALUE
* *
*/ */
NTSTATUS NTSTATUS STDCALL
STDCALL NtConnectPort (PHANDLE ConnectedPort,
NtConnectPort ( PUNICODE_STRING PortName,
PHANDLE ConnectedPort, PSECURITY_QUALITY_OF_SERVICE Qos,
PUNICODE_STRING PortName, PLPC_SECTION_WRITE WriteMap,
PSECURITY_QUALITY_OF_SERVICE Qos, PLPC_SECTION_READ ReadMap,
PLPC_SECTION_WRITE WriteMap, PULONG MaxMessageSize,
PLPC_SECTION_READ ReadMap, PVOID ConnectInfo,
PULONG MaxMessageSize, PULONG UserConnectInfoLength)
PVOID ConnectInfo,
PULONG UserConnectInfoLength
)
{ {
NTSTATUS Status; NTSTATUS Status;
PEPORT NamedPort; PEPORT NamedPort;
PEPORT OurPort; PEPORT OurPort;
HANDLE OurPortHandle; HANDLE OurPortHandle;
PLPC_MESSAGE Request; PLPC_MESSAGE Request;
PQUEUEDMESSAGE Reply; PQUEUEDMESSAGE Reply;
ULONG ConnectInfoLength; ULONG ConnectInfoLength;
KIRQL oldIrql; KIRQL oldIrql;
DPRINT("PortName %x\n", PortName); DPRINT("PortName %x\n", PortName);
DPRINT("NtConnectPort(PortName %S)\n", PortName->Buffer); DPRINT("NtConnectPort(PortName %S)\n", PortName->Buffer);
/* /*
* Copy in user parameters * Copy in user parameters
*/ */
memcpy ( memcpy (&ConnectInfoLength, UserConnectInfoLength,
& ConnectInfoLength, sizeof (*UserConnectInfoLength));
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("Received connection completion\n"); /*
KeAcquireSpinLock ( * Get access to the port
& OurPort->Lock, */
& oldIrql Status = ObReferenceObjectByName (PortName,
); 0,
Reply = EiDequeueMessagePort (OurPort); NULL,
KeReleaseSpinLock ( PORT_ALL_ACCESS, /* DesiredAccess */
& OurPort->Lock, ExPortType,
oldIrql UserMode,
); NULL,
memcpy ( (PVOID*)&NamedPort);
ConnectInfo, if (!NT_SUCCESS(Status))
Reply->MessageData, {
Reply->Message.DataSize DPRINT("Failed to reference named port (status %x)\n", Status);
); return (Status);
*UserConnectInfoLength = Reply->Message.DataSize; }
/*
* 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) Request->DataSize = ConnectInfoLength;
{ Request->MessageSize = sizeof(LPC_MESSAGE) + ConnectInfoLength;
ObDereferenceObject (NamedPort); Request->SharedSectionSize = 0;
ObDereferenceObject (OurPort); if ((ConnectInfo != NULL) && (ConnectInfoLength > 0))
ZwClose (OurPortHandle); {
ExFreePool (Request); memcpy ((PVOID) (Request + 1), ConnectInfo, ConnectInfoLength);
ExFreePool (Reply); }
return (STATUS_UNSUCCESSFUL); /*
} * 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; DPRINT("Waiting for connection completion\n");
*ConnectedPort = OurPortHandle;
ExFreePool (Reply); /*
ExFreePool (Request); * Wait for them to accept our connection
*/
DPRINT("Exited successfully\n"); KeWaitForSingleObject (&OurPort->Event,
UserRequest,
return (STATUS_SUCCESS); 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 * RETURN VALUE
* *
*/ */
EXPORTED EXPORTED NTSTATUS STDCALL
NTSTATUS NtAcceptConnectPort (PHANDLE ServerPortHandle,
STDCALL HANDLE NamedPortHandle,
NtAcceptConnectPort ( PLPC_MESSAGE LpcMessage,
PHANDLE ServerPortHandle, BOOLEAN AcceptIt,
HANDLE NamedPortHandle, PLPC_SECTION_WRITE WriteMap,
PLPC_MESSAGE LpcMessage, PLPC_SECTION_READ ReadMap)
BOOLEAN AcceptIt,
PLPC_SECTION_WRITE WriteMap,
PLPC_SECTION_READ ReadMap
)
{ {
NTSTATUS Status; NTSTATUS Status;
PEPORT NamedPort; PEPORT NamedPort;
PEPORT OurPort = NULL; PEPORT OurPort = NULL;
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); /*
} * Create a port object for our side of the connection
/* */
* Create a port object for our side of the connection if (AcceptIt == 1)
*/ {
if (AcceptIt == 1) OurPort = ObCreateObject (ServerPortHandle,
{
OurPort = ObCreateObject (
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 (ConnectionRequest->Sender,
EiReplyOrRequestPort ( LpcMessage,
ConnectionRequest->Sender, 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, LpcMessage,
LPC_CONNECTION_REFUSED, LPC_REPLY,
NamedPort OurPort);
); ExFreePool (ConnectionRequest);
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);
ObDereferenceObject (OurPort); ObDereferenceObject (OurPort);
ObDereferenceObject (NamedPort); ObDereferenceObject (NamedPort);
return (STATUS_SUCCESS); 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 * 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,7 +225,11 @@ ULONG PsUnfreezeThread(PETHREAD Thread, PNTSTATUS WaitStatus)
if (WaitStatus != NULL) if (WaitStatus != NULL)
{ {
Thread->Tcb.WaitStatus = *WaitStatus; if (!NT_SUCCESS((*WaitStatus)))
{
KeBugCheck(0);
}
Thread->Tcb.WaitStatus = *WaitStatus;
} }
if (r <= 0) 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 * 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);