mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
- Fix pipe connection to non-waiting pipes.
- More corrections to the cancellation logic. - Minor correction to read/write event setting (still I'm getting infinite loops there in some cases). svn path=/trunk/; revision=13856
This commit is contained in:
parent
91979c15bb
commit
dc2b964751
4 changed files with 99 additions and 61 deletions
|
@ -147,40 +147,14 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
KeUnlockMutex(&DeviceExt->PipeListLock);
|
KeUnlockMutex(&DeviceExt->PipeListLock);
|
||||||
|
|
||||||
/*
|
|
||||||
* Step 2. Search for listening server FCB.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Acquire the lock for FCB lists. From now on no modifications to the
|
* Acquire the lock for FCB lists. From now on no modifications to the
|
||||||
* FCB lists are allowed, because it can cause various misconsistencies.
|
* FCB lists are allowed, because it can cause various misconsistencies.
|
||||||
*/
|
*/
|
||||||
KeLockMutex(&Pipe->FcbListLock);
|
KeLockMutex(&Pipe->FcbListLock);
|
||||||
|
|
||||||
if (!SpecialAccess)
|
|
||||||
{
|
|
||||||
ServerFcb = NpfsFindListeningServerInstance(Pipe);
|
|
||||||
if (ServerFcb == NULL)
|
|
||||||
{
|
|
||||||
/* Not found, bail out with error for FILE_OPEN requests. */
|
|
||||||
DPRINT("No listening server fcb found!\n");
|
|
||||||
KeUnlockMutex(&Pipe->FcbListLock);
|
|
||||||
Irp->IoStatus.Status = STATUS_PIPE_BUSY;
|
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
||||||
return STATUS_PIPE_BUSY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (IsListEmpty(&Pipe->ServerFcbListHead))
|
|
||||||
{
|
|
||||||
DPRINT("No server fcb found!\n");
|
|
||||||
KeUnlockMutex(&Pipe->FcbListLock);
|
|
||||||
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
||||||
return STATUS_UNSUCCESSFUL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Step 3. Create the client FCB.
|
* Step 2. Create the client FCB.
|
||||||
*/
|
*/
|
||||||
ClientFcb = ExAllocatePool(NonPagedPool, sizeof(NPFS_FCB));
|
ClientFcb = ExAllocatePool(NonPagedPool, sizeof(NPFS_FCB));
|
||||||
if (ClientFcb == NULL)
|
if (ClientFcb == NULL)
|
||||||
|
@ -226,6 +200,73 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
|
||||||
KeInitializeEvent(&ClientFcb->ConnectEvent, SynchronizationEvent, FALSE);
|
KeInitializeEvent(&ClientFcb->ConnectEvent, SynchronizationEvent, FALSE);
|
||||||
KeInitializeEvent(&ClientFcb->Event, SynchronizationEvent, FALSE);
|
KeInitializeEvent(&ClientFcb->Event, SynchronizationEvent, FALSE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Step 3. Search for listening server FCB.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!SpecialAccess)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* WARNING: Point of no return! Once we get the server FCB it's
|
||||||
|
* possible that we completed a wait request and so we have to
|
||||||
|
* complete even this request.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ServerFcb = NpfsFindListeningServerInstance(Pipe);
|
||||||
|
if (ServerFcb == NULL)
|
||||||
|
{
|
||||||
|
PLIST_ENTRY CurrentEntry;
|
||||||
|
PNPFS_FCB Fcb;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If no waiting server FCB was found then try to pick
|
||||||
|
* one of the listing server FCB on the pipe.
|
||||||
|
*/
|
||||||
|
|
||||||
|
CurrentEntry = Pipe->ServerFcbListHead.Flink;
|
||||||
|
while (CurrentEntry != &Pipe->ServerFcbListHead)
|
||||||
|
{
|
||||||
|
Fcb = CONTAINING_RECORD(CurrentEntry, NPFS_FCB, FcbListEntry);
|
||||||
|
if (Fcb->PipeState == FILE_PIPE_LISTENING_STATE)
|
||||||
|
{
|
||||||
|
ServerFcb = Fcb;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
CurrentEntry = CurrentEntry->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* No one is listening to me?! I'm so lonely... :(
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (ServerFcb == NULL)
|
||||||
|
{
|
||||||
|
/* Not found, bail out with error for FILE_OPEN requests. */
|
||||||
|
DPRINT("No listening server fcb found!\n");
|
||||||
|
if (ClientFcb->Data)
|
||||||
|
ExFreePool(ClientFcb->Data);
|
||||||
|
KeUnlockMutex(&Pipe->FcbListLock);
|
||||||
|
Irp->IoStatus.Status = STATUS_PIPE_BUSY;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return STATUS_PIPE_BUSY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Signal the server thread and remove it from the waiter list */
|
||||||
|
/* FIXME: Merge this with the NpfsFindListeningServerInstance routine. */
|
||||||
|
NpfsSignalAndRemoveListeningServerInstance(Pipe, ServerFcb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (IsListEmpty(&Pipe->ServerFcbListHead))
|
||||||
|
{
|
||||||
|
DPRINT("No server fcb found!\n");
|
||||||
|
KeUnlockMutex(&Pipe->FcbListLock);
|
||||||
|
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Step 4. Add the client FCB to a list and connect it if possible.
|
* Step 4. Add the client FCB to a list and connect it if possible.
|
||||||
*/
|
*/
|
||||||
|
@ -240,9 +281,6 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
|
||||||
ServerFcb->OtherSide = ClientFcb;
|
ServerFcb->OtherSide = ClientFcb;
|
||||||
ClientFcb->PipeState = FILE_PIPE_CONNECTED_STATE;
|
ClientFcb->PipeState = FILE_PIPE_CONNECTED_STATE;
|
||||||
ServerFcb->PipeState = FILE_PIPE_CONNECTED_STATE;
|
ServerFcb->PipeState = FILE_PIPE_CONNECTED_STATE;
|
||||||
|
|
||||||
/* Signal the server thread and remove it from the waiter list */
|
|
||||||
NpfsSignalAndRemoveListeningServerInstance(Pipe, ServerFcb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
KeUnlockMutex(&Pipe->FcbListLock);
|
KeUnlockMutex(&Pipe->FcbListLock);
|
||||||
|
|
|
@ -26,19 +26,12 @@ NpfsListeningCancelRoutine(IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
DPRINT1("NpfsListeningCancelRoutine() called\n");
|
DPRINT1("NpfsListeningCancelRoutine() called\n");
|
||||||
|
|
||||||
/* FIXME: Not tested. */
|
|
||||||
|
|
||||||
IoReleaseCancelSpinLock(Irp->CancelIrql);
|
IoReleaseCancelSpinLock(Irp->CancelIrql);
|
||||||
|
|
||||||
Waiter = Irp->Tail.Overlay.DriverContext[0];
|
Waiter = Irp->Tail.Overlay.DriverContext[0];
|
||||||
|
|
||||||
KeLockMutex(&Waiter->Pipe->FcbListLock);
|
KeLockMutex(&Waiter->Pipe->FcbListLock);
|
||||||
RemoveEntryList(&Waiter->Entry);
|
RemoveEntryList(&Waiter->Entry);
|
||||||
if (IoSetCancelRoutine(Waiter->Irp, NULL) == NULL)
|
|
||||||
{
|
|
||||||
KeUnlockMutex(&Waiter->Pipe->FcbListLock);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
KeUnlockMutex(&Waiter->Pipe->FcbListLock);
|
KeUnlockMutex(&Waiter->Pipe->FcbListLock);
|
||||||
|
|
||||||
Irp->IoStatus.Status = STATUS_CANCELLED;
|
Irp->IoStatus.Status = STATUS_CANCELLED;
|
||||||
|
@ -53,7 +46,6 @@ NpfsAddListeningServerInstance(PIRP Irp,
|
||||||
PNPFS_FCB Fcb)
|
PNPFS_FCB Fcb)
|
||||||
{
|
{
|
||||||
PNPFS_WAITER_ENTRY Entry;
|
PNPFS_WAITER_ENTRY Entry;
|
||||||
KIRQL OldIrql;
|
|
||||||
|
|
||||||
Entry = ExAllocatePool(NonPagedPool, sizeof(NPFS_WAITER_ENTRY));
|
Entry = ExAllocatePool(NonPagedPool, sizeof(NPFS_WAITER_ENTRY));
|
||||||
if (Entry == NULL)
|
if (Entry == NULL)
|
||||||
|
@ -63,21 +55,26 @@ NpfsAddListeningServerInstance(PIRP Irp,
|
||||||
Entry->Fcb = Fcb;
|
Entry->Fcb = Fcb;
|
||||||
Entry->Pipe = Fcb->Pipe;
|
Entry->Pipe = Fcb->Pipe;
|
||||||
|
|
||||||
IoAcquireCancelSpinLock(&OldIrql);
|
KeLockMutex(&Fcb->Pipe->FcbListLock);
|
||||||
|
|
||||||
|
IoMarkIrpPending(Irp);
|
||||||
|
Irp->Tail.Overlay.DriverContext[0] = Entry;
|
||||||
|
InsertTailList(&Fcb->Pipe->WaiterListHead, &Entry->Entry);
|
||||||
|
|
||||||
|
IoSetCancelRoutine(Irp, NpfsListeningCancelRoutine);
|
||||||
|
|
||||||
if (!Irp->Cancel)
|
if (!Irp->Cancel)
|
||||||
{
|
{
|
||||||
Irp->Tail.Overlay.DriverContext[0] = Entry;
|
|
||||||
IoMarkIrpPending(Irp);
|
|
||||||
IoSetCancelRoutine(Irp, NpfsListeningCancelRoutine);
|
|
||||||
KeLockMutex(&Fcb->Pipe->FcbListLock);
|
|
||||||
InsertTailList(&Fcb->Pipe->WaiterListHead, &Entry->Entry);
|
|
||||||
KeUnlockMutex(&Fcb->Pipe->FcbListLock);
|
KeUnlockMutex(&Fcb->Pipe->FcbListLock);
|
||||||
IoReleaseCancelSpinLock(OldIrql);
|
|
||||||
return STATUS_PENDING;
|
return STATUS_PENDING;
|
||||||
}
|
}
|
||||||
/* IRP has already been cancelled */
|
|
||||||
IoReleaseCancelSpinLock(OldIrql);
|
RemoveEntryList(&Entry->Entry);
|
||||||
|
|
||||||
|
Irp->IoStatus.Status = STATUS_CANCELLED;
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
KeUnlockMutex(&Fcb->Pipe->FcbListLock);
|
||||||
ExFreePool(Entry);
|
ExFreePool(Entry);
|
||||||
|
|
||||||
return STATUS_CANCELLED;
|
return STATUS_CANCELLED;
|
||||||
|
|
|
@ -165,7 +165,10 @@ NpfsRead(PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
if (Length == 0)
|
if (Length == 0)
|
||||||
{
|
{
|
||||||
KeSetEvent(&WriterFcb->Event, IO_NO_INCREMENT, FALSE);
|
if (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE)
|
||||||
|
{
|
||||||
|
KeSetEvent(&WriterFcb->Event, IO_NO_INCREMENT, FALSE);
|
||||||
|
}
|
||||||
KeResetEvent(&Fcb->Event);
|
KeResetEvent(&Fcb->Event);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -197,6 +200,11 @@ NpfsRead(PDEVICE_OBJECT DeviceObject,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
KeResetEvent(&Fcb->Event);
|
||||||
|
if (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE)
|
||||||
|
{
|
||||||
|
KeSetEvent(&WriterFcb->Event, IO_NO_INCREMENT, FALSE);
|
||||||
|
}
|
||||||
Fcb->ReadDataAvailable = 0;
|
Fcb->ReadDataAvailable = 0;
|
||||||
Fcb->WriteQuotaAvailable = Fcb->MaxDataLength;
|
Fcb->WriteQuotaAvailable = Fcb->MaxDataLength;
|
||||||
}
|
}
|
||||||
|
@ -204,11 +212,6 @@ NpfsRead(PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
if (Information > 0)
|
if (Information > 0)
|
||||||
{
|
{
|
||||||
if (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE)
|
|
||||||
{
|
|
||||||
KeSetEvent(&WriterFcb->Event, IO_NO_INCREMENT, FALSE);
|
|
||||||
}
|
|
||||||
KeResetEvent(&Fcb->Event);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -383,12 +386,12 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
|
||||||
ReaderFcb->WriteQuotaAvailable = 0;
|
ReaderFcb->WriteQuotaAvailable = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Information > 0)
|
if (Information > 0)
|
||||||
{
|
{
|
||||||
KeSetEvent(&ReaderFcb->Event, IO_NO_INCREMENT, FALSE);
|
KeSetEvent(&ReaderFcb->Event, IO_NO_INCREMENT, FALSE);
|
||||||
KeResetEvent(&Fcb->Event);
|
KeResetEvent(&Fcb->Event);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ NpfsQueryFsDeviceInformation(PFILE_FS_DEVICE_INFORMATION FsDeviceInfo,
|
||||||
|
|
||||||
DPRINT("NpfsQueryFsDeviceInformation() finished.\n");
|
DPRINT("NpfsQueryFsDeviceInformation() finished.\n");
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue