mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
- Implemented NpfsCleanup.
- Moved most of the code from NpfsClose to NpfsCleanup. - If a pipe handle is closed, remove the fcb from the wait list and cancel a connecting irp if one is waiting. svn path=/trunk/; revision=14310
This commit is contained in:
parent
a106e5c2e0
commit
2b55bc2731
3 changed files with 131 additions and 28 deletions
|
@ -92,7 +92,7 @@ NpfsSignalAndRemoveListeningServerInstance(PNPFS_PIPE Pipe,
|
|||
{
|
||||
DPRINT("Server found! Fcb %p\n", Waiter->Fcb);
|
||||
|
||||
Waiter->Irp->IoStatus.Status = FILE_PIPE_CONNECTED_STATE;
|
||||
Waiter->Irp->IoStatus.Status = STATUS_PIPE_CONNECTED;
|
||||
Waiter->Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Waiter->Irp, IO_NO_INCREMENT);
|
||||
|
||||
|
@ -467,10 +467,9 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
|
|||
|
||||
if (NewPipe)
|
||||
{
|
||||
/*
|
||||
* FIXME:
|
||||
* Lock the pipelist and remove the pipe from the list.
|
||||
*/
|
||||
KeLockMutex(&DeviceExt->PipeListLock);
|
||||
RemoveEntryList(&Pipe->PipeListEntry);
|
||||
KeUnlockMutex(&DeviceExt->PipeListLock);
|
||||
RtlFreeUnicodeString(&Pipe->PipeName);
|
||||
ExFreePool(Pipe);
|
||||
}
|
||||
|
@ -494,10 +493,6 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
|
|||
|
||||
Pipe->CurrentInstances++;
|
||||
|
||||
KeLockMutex(&Pipe->FcbListLock);
|
||||
InsertTailList(&Pipe->ServerFcbListHead, &Fcb->FcbListEntry);
|
||||
KeUnlockMutex(&Pipe->FcbListLock);
|
||||
|
||||
Fcb->Pipe = Pipe;
|
||||
Fcb->PipeEnd = FILE_PIPE_SERVER_END;
|
||||
Fcb->PipeState = FILE_PIPE_LISTENING_STATE;
|
||||
|
@ -511,6 +506,10 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
|
|||
SynchronizationEvent,
|
||||
FALSE);
|
||||
|
||||
KeLockMutex(&Pipe->FcbListLock);
|
||||
InsertTailList(&Pipe->ServerFcbListHead, &Fcb->FcbListEntry);
|
||||
KeUnlockMutex(&Pipe->FcbListLock);
|
||||
|
||||
FileObject->FsContext = Fcb;
|
||||
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
|
@ -522,6 +521,125 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
|
|||
}
|
||||
|
||||
|
||||
NTSTATUS STDCALL
|
||||
NpfsCleanup(PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
{
|
||||
PNPFS_DEVICE_EXTENSION DeviceExt;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
PFILE_OBJECT FileObject;
|
||||
PNPFS_FCB Fcb;
|
||||
PNPFS_PIPE Pipe;
|
||||
BOOL Server;
|
||||
|
||||
DPRINT("NpfsCleanup(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
|
||||
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
FileObject = IoStack->FileObject;
|
||||
Fcb = FileObject->FsContext;
|
||||
|
||||
if (Fcb == NULL)
|
||||
{
|
||||
DPRINT("Success!\n");
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
DPRINT("Fcb %x\n", Fcb);
|
||||
Pipe = Fcb->Pipe;
|
||||
|
||||
DPRINT("Cleaning pipe %wZ\n", &Pipe->PipeName);
|
||||
|
||||
KeLockMutex(&Pipe->FcbListLock);
|
||||
|
||||
Server = (Fcb->PipeEnd == FILE_PIPE_SERVER_END);
|
||||
|
||||
if (Server)
|
||||
{
|
||||
/* FIXME: Clean up existing connections here ?? */
|
||||
DPRINT("Server\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("Client\n");
|
||||
}
|
||||
|
||||
if (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE)
|
||||
{
|
||||
if (Fcb->OtherSide)
|
||||
{
|
||||
Fcb->OtherSide->PipeState = FILE_PIPE_DISCONNECTED_STATE;
|
||||
Fcb->OtherSide->OtherSide = NULL;
|
||||
/*
|
||||
* Signaling the write event. If is possible that an other
|
||||
* thread waits for an empty buffer.
|
||||
*/
|
||||
KeSetEvent(&Fcb->OtherSide->Event, IO_NO_INCREMENT, FALSE);
|
||||
}
|
||||
}
|
||||
else if (Fcb->PipeState == FILE_PIPE_LISTENING_STATE)
|
||||
{
|
||||
PLIST_ENTRY Entry;
|
||||
PNPFS_WAITER_ENTRY WaitEntry = NULL;
|
||||
BOOLEAN Complete = FALSE;
|
||||
KIRQL oldIrql;
|
||||
|
||||
Entry = Fcb->Pipe->WaiterListHead.Flink;
|
||||
while (Entry != &Fcb->Pipe->WaiterListHead)
|
||||
{
|
||||
WaitEntry = CONTAINING_RECORD(Entry, NPFS_WAITER_ENTRY, Entry);
|
||||
if (WaitEntry->Fcb == Fcb)
|
||||
{
|
||||
RemoveEntryList(Entry);
|
||||
IoAcquireCancelSpinLock(&oldIrql);
|
||||
if (!Irp->Cancel)
|
||||
{
|
||||
IoSetCancelRoutine(WaitEntry->Irp, NULL);
|
||||
Complete = TRUE;
|
||||
}
|
||||
IoReleaseCancelSpinLock(oldIrql);
|
||||
break;
|
||||
}
|
||||
Entry = Entry->Flink;
|
||||
}
|
||||
|
||||
if (Entry != &Fcb->Pipe->WaiterListHead)
|
||||
{
|
||||
if (Complete)
|
||||
{
|
||||
WaitEntry->Irp->IoStatus.Status = STATUS_PIPE_BROKEN;
|
||||
WaitEntry->Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(WaitEntry->Irp, IO_NO_INCREMENT);
|
||||
}
|
||||
ExFreePool(WaitEntry);
|
||||
}
|
||||
}
|
||||
Fcb->PipeState = FILE_PIPE_CLOSING_STATE;
|
||||
|
||||
KeUnlockMutex(&Pipe->FcbListLock);
|
||||
|
||||
ExAcquireFastMutex(&Fcb->DataListLock);
|
||||
if (Fcb->Data)
|
||||
{
|
||||
ExFreePool(Fcb->Data);
|
||||
Fcb->Data = NULL;
|
||||
Fcb->ReadPtr = NULL;
|
||||
Fcb->WritePtr = NULL;
|
||||
}
|
||||
ExReleaseFastMutex(&Fcb->DataListLock);
|
||||
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
DPRINT("Success!\n");
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
NpfsClose(PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
|
@ -560,7 +678,6 @@ NpfsClose(PDEVICE_OBJECT DeviceObject,
|
|||
|
||||
if (Server)
|
||||
{
|
||||
/* FIXME: Clean up existing connections here ?? */
|
||||
DPRINT("Server\n");
|
||||
Pipe->CurrentInstances--;
|
||||
}
|
||||
|
@ -569,27 +686,12 @@ NpfsClose(PDEVICE_OBJECT DeviceObject,
|
|||
DPRINT("Client\n");
|
||||
}
|
||||
|
||||
if (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE)
|
||||
{
|
||||
if (Fcb->OtherSide)
|
||||
{
|
||||
Fcb->OtherSide->PipeState = FILE_PIPE_CLOSING_STATE;
|
||||
Fcb->OtherSide->OtherSide = NULL;
|
||||
/*
|
||||
* Signaling the write event. If is possible that an other
|
||||
* thread waits for an empty buffer.
|
||||
*/
|
||||
KeSetEvent(&Fcb->OtherSide->Event, IO_NO_INCREMENT, FALSE);
|
||||
}
|
||||
|
||||
Fcb->PipeState = 0;
|
||||
}
|
||||
ASSERT (Fcb->PipeState == FILE_PIPE_CLOSING_STATE);
|
||||
|
||||
FileObject->FsContext = NULL;
|
||||
|
||||
RemoveEntryList(&Fcb->FcbListEntry);
|
||||
if (Fcb->Data)
|
||||
ExFreePool(Fcb->Data);
|
||||
|
||||
ExFreePool(Fcb);
|
||||
|
||||
KeUnlockMutex(&Pipe->FcbListLock);
|
||||
|
|
|
@ -40,7 +40,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
|
|||
NpfsSetInformation;
|
||||
DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] =
|
||||
NpfsQueryVolumeInformation;
|
||||
// DriverObject->MajorFunction[IRP_MJ_CLEANUP] = NpfsCleanup;
|
||||
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = NpfsCleanup;
|
||||
DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = NpfsFlushBuffers;
|
||||
// DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] =
|
||||
// NpfsDirectoryControl;
|
||||
|
|
|
@ -99,6 +99,7 @@ extern NPAGED_LOOKASIDE_LIST NpfsPipeDataLookasideList;
|
|||
|
||||
NTSTATUS STDCALL NpfsCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
NTSTATUS STDCALL NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
NTSTATUS STDCALL NpfsCleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
NTSTATUS STDCALL NpfsClose(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
|
||||
NTSTATUS STDCALL NpfsRead(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
|
|
Loading…
Reference in a new issue