- 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). Modified: trunk/reactos/drivers/fs/np/create.c Modified: trunk/reactos/drivers/fs/np/fsctrl.c Modified: trunk/reactos/drivers/fs/np/rw.c Modified: trunk/reactos/drivers/fs/np/volume.c _____
Modified: trunk/reactos/drivers/fs/np/create.c --- trunk/reactos/drivers/fs/np/create.c 2005-03-06 14:03:37 UTC (rev 13855) +++ trunk/reactos/drivers/fs/np/create.c 2005-03-06 16:42:36 UTC (rev 13856) @@ -148,39 +148,13 @@
KeUnlockMutex(&DeviceExt->PipeListLock);
/* - * Step 2. Search for listening server FCB. - */ - - /* * Acquire the lock for FCB lists. From now on no modifications to the * FCB lists are allowed, because it can cause various misconsistencies. */ 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)); if (ClientFcb == NULL) @@ -227,6 +201,73 @@ 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. */
@@ -240,9 +281,6 @@ ServerFcb->OtherSide = ClientFcb; ClientFcb->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); _____
Modified: trunk/reactos/drivers/fs/np/fsctrl.c --- trunk/reactos/drivers/fs/np/fsctrl.c 2005-03-06 14:03:37 UTC (rev 13855) +++ trunk/reactos/drivers/fs/np/fsctrl.c 2005-03-06 16:42:36 UTC (rev 13856) @@ -26,19 +26,12 @@
DPRINT1("NpfsListeningCancelRoutine() called\n");
- /* FIXME: Not tested. */ - IoReleaseCancelSpinLock(Irp->CancelIrql);
Waiter = Irp->Tail.Overlay.DriverContext[0];
KeLockMutex(&Waiter->Pipe->FcbListLock); RemoveEntryList(&Waiter->Entry); - if (IoSetCancelRoutine(Waiter->Irp, NULL) == NULL) - { - KeUnlockMutex(&Waiter->Pipe->FcbListLock); - return; - } KeUnlockMutex(&Waiter->Pipe->FcbListLock);
Irp->IoStatus.Status = STATUS_CANCELLED; @@ -53,7 +46,6 @@ PNPFS_FCB Fcb) { PNPFS_WAITER_ENTRY Entry; - KIRQL OldIrql;
Entry = ExAllocatePool(NonPagedPool, sizeof(NPFS_WAITER_ENTRY)); if (Entry == NULL) @@ -63,21 +55,26 @@ Entry->Fcb = Fcb; 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) { - 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); - IoReleaseCancelSpinLock(OldIrql); 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);
return STATUS_CANCELLED; _____
Modified: trunk/reactos/drivers/fs/np/rw.c --- trunk/reactos/drivers/fs/np/rw.c 2005-03-06 14:03:37 UTC (rev 13855) +++ trunk/reactos/drivers/fs/np/rw.c 2005-03-06 16:42:36 UTC (rev 13856) @@ -165,7 +165,10 @@
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); break; } @@ -197,6 +200,11 @@ } else { + KeResetEvent(&Fcb->Event); + if (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE) + { + KeSetEvent(&WriterFcb->Event, IO_NO_INCREMENT, FALSE); + } Fcb->ReadDataAvailable = 0; Fcb->WriteQuotaAvailable = Fcb->MaxDataLength; } @@ -204,11 +212,6 @@
if (Information > 0) { - if (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE) - { - KeSetEvent(&WriterFcb->Event, IO_NO_INCREMENT, FALSE); - } - KeResetEvent(&Fcb->Event); break; } } @@ -383,12 +386,12 @@ ReaderFcb->WriteQuotaAvailable = 0; }
- if (Information > 0) - { - KeSetEvent(&ReaderFcb->Event, IO_NO_INCREMENT, FALSE); - KeResetEvent(&Fcb->Event); - break; - } + if (Information > 0) + { + KeSetEvent(&ReaderFcb->Event, IO_NO_INCREMENT, FALSE); + KeResetEvent(&Fcb->Event); + break; + } } }
_____
Modified: trunk/reactos/drivers/fs/np/volume.c --- trunk/reactos/drivers/fs/np/volume.c 2005-03-06 14:03:37 UTC (rev 13855) +++ trunk/reactos/drivers/fs/np/volume.c 2005-03-06 16:42:36 UTC (rev 13856) @@ -36,7 +36,7 @@
DPRINT("NpfsQueryFsDeviceInformation() finished.\n");
- return STATUS_SUCCESS; + return STATUS_SUCCESS; }