📄 create.c
字号:
else
{
NewPipe = TRUE;
Fcb = ExAllocatePool(NonPagedPool, sizeof(NPFS_FCB));
if (Fcb == NULL)
{
KeUnlockMutex(&DeviceExt->PipeListLock);
ExFreePool(Ccb);
Irp->IoStatus.Status = STATUS_NO_MEMORY;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_NO_MEMORY;
}
Fcb->PipeName.Length = FileObject->FileName.Length;
Fcb->PipeName.MaximumLength = Fcb->PipeName.Length + sizeof(UNICODE_NULL);
Fcb->PipeName.Buffer = ExAllocatePool(NonPagedPool, Fcb->PipeName.MaximumLength);
if (Fcb->PipeName.Buffer == NULL)
{
KeUnlockMutex(&DeviceExt->PipeListLock);
ExFreePool(Fcb);
ExFreePool(Ccb);
Irp->IoStatus.Status = STATUS_NO_MEMORY;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_NO_MEMORY;
}
RtlCopyUnicodeString(&Fcb->PipeName, &FileObject->FileName);
InitializeListHead(&Fcb->ServerCcbListHead);
InitializeListHead(&Fcb->ClientCcbListHead);
InitializeListHead(&Fcb->WaiterListHead);
KeInitializeMutex(&Fcb->CcbListLock, 0);
Fcb->PipeType = Buffer->NamedPipeType;
Fcb->WriteMode = Buffer->ReadMode;
Fcb->ReadMode = Buffer->ReadMode;
Fcb->CompletionMode = Buffer->CompletionMode;
switch (IoStack->Parameters.CreatePipe.ShareAccess & (FILE_SHARE_READ|FILE_SHARE_WRITE))
{
case FILE_SHARE_READ:
Fcb->PipeConfiguration = FILE_PIPE_OUTBOUND;
break;
case FILE_SHARE_WRITE:
Fcb->PipeConfiguration = FILE_PIPE_INBOUND;
break;
case FILE_SHARE_READ|FILE_SHARE_WRITE:
Fcb->PipeConfiguration = FILE_PIPE_FULL_DUPLEX;
break;
}
Fcb->MaximumInstances = Buffer->MaximumInstances;
Fcb->CurrentInstances = 0;
Fcb->TimeOut = Buffer->DefaultTimeout;
if (!(Fcb->PipeConfiguration & FILE_PIPE_OUTBOUND) ||
Fcb->PipeConfiguration & FILE_PIPE_FULL_DUPLEX)
{
if (Buffer->InboundQuota == 0)
{
Fcb->InboundQuota = DeviceExt->DefaultQuota;
}
else
{
Fcb->InboundQuota = PAGE_ROUND_UP(Buffer->InboundQuota);
if (Fcb->InboundQuota < DeviceExt->MinQuota)
{
Fcb->InboundQuota = DeviceExt->MinQuota;
}
else if (Fcb->InboundQuota > DeviceExt->MaxQuota)
{
Fcb->InboundQuota = DeviceExt->MaxQuota;
}
}
}
else
{
Fcb->InboundQuota = 0;
}
if (Fcb->PipeConfiguration & (FILE_PIPE_FULL_DUPLEX|FILE_PIPE_OUTBOUND))
{
if (Buffer->OutboundQuota == 0)
{
Fcb->OutboundQuota = DeviceExt->DefaultQuota;
}
else
{
Fcb->OutboundQuota = PAGE_ROUND_UP(Buffer->OutboundQuota);
if (Fcb->OutboundQuota < DeviceExt->MinQuota)
{
Fcb->OutboundQuota = DeviceExt->MinQuota;
}
else if (Fcb->OutboundQuota > DeviceExt->MaxQuota)
{
Fcb->OutboundQuota = DeviceExt->MaxQuota;
}
}
}
else
{
Fcb->OutboundQuota = 0;
}
InsertTailList(&DeviceExt->PipeListHead, &Fcb->PipeListEntry);
KeUnlockMutex(&DeviceExt->PipeListLock);
}
if (Fcb->InboundQuota)
{
Ccb->Data = ExAllocatePool(PagedPool, Fcb->InboundQuota);
if (Ccb->Data == NULL)
{
ExFreePool(Ccb);
if (NewPipe)
{
KeLockMutex(&DeviceExt->PipeListLock);
RemoveEntryList(&Fcb->PipeListEntry);
KeUnlockMutex(&DeviceExt->PipeListLock);
RtlFreeUnicodeString(&Fcb->PipeName);
ExFreePool(Fcb);
}
Irp->IoStatus.Status = STATUS_NO_MEMORY;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_NO_MEMORY;
}
}
else
{
Ccb->Data = NULL;
}
Ccb->ReadPtr = Ccb->Data;
Ccb->WritePtr = Ccb->Data;
Ccb->ReadDataAvailable = 0;
Ccb->WriteQuotaAvailable = Fcb->InboundQuota;
Ccb->MaxDataLength = Fcb->InboundQuota;
InitializeListHead(&Ccb->ReadRequestListHead);
ExInitializeFastMutex(&Ccb->DataListLock);
Fcb->CurrentInstances++;
Ccb->Fcb = Fcb;
Ccb->PipeEnd = FILE_PIPE_SERVER_END;
Ccb->PipeState = FILE_PIPE_LISTENING_STATE;
Ccb->OtherSide = NULL;
DPRINT("CCB: %x\n", Ccb);
KeInitializeEvent(&Ccb->ConnectEvent, SynchronizationEvent, FALSE);
KeInitializeEvent(&Ccb->ReadEvent, SynchronizationEvent, FALSE);
KeInitializeEvent(&Ccb->WriteEvent, SynchronizationEvent, FALSE);
KeLockMutex(&Fcb->CcbListLock);
InsertTailList(&Fcb->ServerCcbListHead, &Ccb->CcbListEntry);
KeUnlockMutex(&Fcb->CcbListLock);
FileObject->FsContext = Fcb;
FileObject->FsContext2 = Ccb;
FileObject->Flags |= FO_NAMED_PIPE;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
DPRINT("Success!\n");
return STATUS_SUCCESS;
}
NTSTATUS STDCALL
NpfsCleanup(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PNPFS_DEVICE_EXTENSION DeviceExt;
PIO_STACK_LOCATION IoStack;
PFILE_OBJECT FileObject;
PNPFS_CCB Ccb, OtherSide;
PNPFS_FCB Fcb;
BOOLEAN Server;
DPRINT("NpfsCleanup(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
IoStack = IoGetCurrentIrpStackLocation(Irp);
DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
FileObject = IoStack->FileObject;
Ccb = FileObject->FsContext2;
if (Ccb == NULL)
{
DPRINT("Success!\n");
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
DPRINT("CCB %p\n", Ccb);
Fcb = Ccb->Fcb;
DPRINT("Cleaning pipe %wZ\n", &Fcb->PipeName);
KeLockMutex(&Fcb->CcbListLock);
Server = (Ccb->PipeEnd == FILE_PIPE_SERVER_END);
if (Server)
{
/* FIXME: Clean up existing connections here ?? */
DPRINT("Server\n");
}
else
{
DPRINT("Client\n");
}
if (Ccb->PipeState == FILE_PIPE_CONNECTED_STATE)
{
OtherSide = Ccb->OtherSide;
/* Lock the server first */
if (Server)
{
ExAcquireFastMutex(&Ccb->DataListLock);
ExAcquireFastMutex(&OtherSide->DataListLock);
}
else
{
ExAcquireFastMutex(&OtherSide->DataListLock);
ExAcquireFastMutex(&Ccb->DataListLock);
}
OtherSide->PipeState = FILE_PIPE_DISCONNECTED_STATE;
OtherSide->OtherSide = NULL;
/*
* Signaling the write event. If is possible that an other
* thread waits for an empty buffer.
*/
KeSetEvent(&OtherSide->ReadEvent, IO_NO_INCREMENT, FALSE);
KeSetEvent(&OtherSide->WriteEvent, IO_NO_INCREMENT, FALSE);
if (Server)
{
ExReleaseFastMutex(&OtherSide->DataListLock);
ExReleaseFastMutex(&Ccb->DataListLock);
}
else
{
ExReleaseFastMutex(&Ccb->DataListLock);
ExReleaseFastMutex(&OtherSide->DataListLock);
}
}
else if (Ccb->PipeState == FILE_PIPE_LISTENING_STATE)
{
PLIST_ENTRY Entry;
PNPFS_WAITER_ENTRY WaitEntry = NULL;
BOOLEAN Complete = FALSE;
KIRQL oldIrql;
PIRP tmpIrp;
Entry = Ccb->Fcb->WaiterListHead.Flink;
while (Entry != &Ccb->Fcb->WaiterListHead)
{
WaitEntry = CONTAINING_RECORD(Entry, NPFS_WAITER_ENTRY, Entry);
if (WaitEntry->Ccb == Ccb)
{
RemoveEntryList(Entry);
tmpIrp = CONTAINING_RECORD(WaitEntry, IRP, Tail.Overlay.DriverContext);
IoAcquireCancelSpinLock(&oldIrql);
if (!tmpIrp->Cancel)
{
(void)IoSetCancelRoutine(tmpIrp, NULL);
Complete = TRUE;
}
IoReleaseCancelSpinLock(oldIrql);
if (Complete)
{
tmpIrp->IoStatus.Status = STATUS_PIPE_BROKEN;
tmpIrp->IoStatus.Information = 0;
IoCompleteRequest(tmpIrp, IO_NO_INCREMENT);
}
break;
}
Entry = Entry->Flink;
}
}
Ccb->PipeState = FILE_PIPE_CLOSING_STATE;
KeUnlockMutex(&Fcb->CcbListLock);
ExAcquireFastMutex(&Ccb->DataListLock);
if (Ccb->Data)
{
ExFreePool(Ccb->Data);
Ccb->Data = NULL;
Ccb->ReadPtr = NULL;
Ccb->WritePtr = NULL;
}
ExReleaseFastMutex(&Ccb->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)
{
PNPFS_DEVICE_EXTENSION DeviceExt;
PIO_STACK_LOCATION IoStack;
PFILE_OBJECT FileObject;
PNPFS_FCB Fcb;
PNPFS_CCB Ccb;
BOOLEAN Server;
DPRINT("NpfsClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
IoStack = IoGetCurrentIrpStackLocation(Irp);
DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
FileObject = IoStack->FileObject;
Ccb = FileObject->FsContext2;
if (Ccb == NULL)
{
DPRINT("Success!\n");
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
DPRINT("CCB %x\n", Ccb);
Fcb = Ccb->Fcb;
DPRINT("Closing pipe %wZ\n", &Fcb->PipeName);
KeLockMutex(&Fcb->CcbListLock);
Server = (Ccb->PipeEnd == FILE_PIPE_SERVER_END);
if (Server)
{
DPRINT("Server\n");
Fcb->CurrentInstances--;
}
else
{
DPRINT("Client\n");
}
ASSERT(Ccb->PipeState == FILE_PIPE_CLOSING_STATE);
FileObject->FsContext2 = NULL;
RemoveEntryList(&Ccb->CcbListEntry);
ExFreePool(Ccb);
KeUnlockMutex(&Fcb->CcbListLock);
if (IsListEmpty(&Fcb->ServerCcbListHead) &&
IsListEmpty(&Fcb->ClientCcbListHead))
{
RtlFreeUnicodeString(&Fcb->PipeName);
KeLockMutex(&DeviceExt->PipeListLock);
RemoveEntryList(&Fcb->PipeListEntry);
KeUnlockMutex(&DeviceExt->PipeListLock);
ExFreePool(Fcb);
FileObject->FsContext = NULL;
}
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
DPRINT("Success!\n");
return STATUS_SUCCESS;
}
/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -