- Rename DEVICE_EXTENSION to NPFS_VCB.
- Add a type variable to distinguish FCBs and CCBs for device, directory or pipe.
- Attach an FCB to the VCB that represents the root directory of the file system and implement an open routine for the root directory.
- Make NpfsWaitPipe work when it is called for the root directory.
[KERNEL32]
- Remove the old version of WaitNamedPipeW.
This patch fixes the broken wait pipe code. It was written and tested on r49458 because later revisions do not work for me.
svn path=/trunk/; revision=49646
#include <debug.h>
DEBUG_CHANNEL(kernel32file);
-//#define USING_PROPER_NPFS_WAIT_SEMANTICS
+#define USING_PROPER_NPFS_WAIT_SEMANTICS
/* FUNCTIONS ****************************************************************/
}
-/*
- * When NPFS will work properly, use this code instead. It is compatible with
- * Microsoft's NPFS.SYS. The main difference is that:
- * - This code actually respects the timeout instead of ignoring it!
- * - This code validates and creates the proper names for both UNC and local pipes
- * - On NT, you open the *root* pipe directory (either \DosDevices\Pipe or
- * \DosDevices\Unc\Server\Pipe) and then send the pipe to wait on in the
- * FILE_PIPE_WAIT_FOR_BUFFER structure.
- */
-#ifdef USING_PROPER_NPFS_WAIT_SEMANTICS
/*
* @implemented
*/
/* Success */
return TRUE;
}
-#else
-/*
- * @implemented
- */
-BOOL
-WINAPI
-WaitNamedPipeW(LPCWSTR lpNamedPipeName,
- DWORD nTimeOut)
-{
- UNICODE_STRING NamedPipeName;
- NTSTATUS Status;
- OBJECT_ATTRIBUTES ObjectAttributes;
- FILE_PIPE_WAIT_FOR_BUFFER WaitPipe;
- HANDLE FileHandle;
- IO_STATUS_BLOCK Iosb;
-
- if (RtlDosPathNameToNtPathName_U(lpNamedPipeName,
- &NamedPipeName,
- NULL,
- NULL) == FALSE)
- {
- return FALSE;
- }
-
- InitializeObjectAttributes(&ObjectAttributes,
- &NamedPipeName,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
- Status = NtOpenFile(&FileHandle,
- FILE_READ_ATTRIBUTES | SYNCHRONIZE,
- &ObjectAttributes,
- &Iosb,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- FILE_SYNCHRONOUS_IO_NONALERT);
- if (!NT_SUCCESS(Status))
- {
- SetLastErrorByStatus(Status);
- RtlFreeUnicodeString(&NamedPipeName);
- return FALSE;
- }
-
- /* Check what timeout we got */
- if (nTimeOut == NMPWAIT_USE_DEFAULT_WAIT)
- {
- /* Don't use a timeout */
- WaitPipe.TimeoutSpecified = FALSE;
- }
- else
- {
- /* Check if we should wait forever */
- if (nTimeOut == NMPWAIT_WAIT_FOREVER)
- {
- /* Set the max */
- WaitPipe.Timeout.LowPart = 0;
- WaitPipe.Timeout.HighPart = 0x80000000;
- }
- else
- {
- /* Convert to NT format */
- WaitPipe.Timeout.QuadPart = UInt32x32To64(-10000, nTimeOut);
- }
-
- /* In both cases, we do have a timeout */
- WaitPipe.TimeoutSpecified = TRUE;
- }
-
- Status = NtFsControlFile(FileHandle,
- NULL,
- NULL,
- NULL,
- &Iosb,
- FSCTL_PIPE_WAIT,
- &WaitPipe,
- sizeof(WaitPipe),
- NULL,
- 0);
- NtClose(FileHandle);
- if (!NT_SUCCESS(Status))
- {
- SetLastErrorByStatus(Status);
- RtlFreeUnicodeString(&NamedPipeName);
- return FALSE;
- }
-
- RtlFreeUnicodeString(&NamedPipeName);
- return TRUE;
-}
-#endif
/*
/* FUNCTIONS *****************************************************************/
-static PNPFS_FCB
-NpfsFindPipe(PNPFS_DEVICE_EXTENSION DeviceExt,
+PNPFS_FCB
+NpfsFindPipe(PNPFS_VCB Vcb,
PUNICODE_STRING PipeName)
{
PLIST_ENTRY CurrentEntry;
PNPFS_FCB Fcb;
- CurrentEntry = DeviceExt->PipeListHead.Flink;
- while (CurrentEntry != &DeviceExt->PipeListHead)
+ CurrentEntry = Vcb->PipeListHead.Flink;
+ while (CurrentEntry != &Vcb->PipeListHead)
{
Fcb = CONTAINING_RECORD(CurrentEntry, NPFS_FCB, PipeListEntry);
if (RtlCompareUnicodeString(PipeName,
}
+static VOID
+NpfsOpenRootDirectory(PNPFS_FCB Fcb,
+ PFILE_OBJECT FileObject,
+ PIO_STATUS_BLOCK IoStatus)
+{
+ PNPFS_CCB Ccb;
+
+ DPRINT("NpfsOpenRootDirectory()\n");
+
+ Ccb = ExAllocatePool(NonPagedPool, sizeof(NPFS_CCB));
+ if (Ccb == NULL)
+ {
+ IoStatus->Status = STATUS_NO_MEMORY;
+ return;
+ }
+
+ Ccb->Type = CCB_DIRECTORY;
+ Ccb->Fcb = Fcb;
+
+ FileObject->FsContext = Fcb;
+ FileObject->FsContext2 = Ccb;
+
+ IoStatus->Information = FILE_OPENED;
+ IoStatus->Status = STATUS_SUCCESS;
+
+ return;
+}
+
+
NTSTATUS NTAPI
NpfsCreate(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PEXTENDED_IO_STACK_LOCATION IoStack;
+ PUNICODE_STRING FileName;
PFILE_OBJECT FileObject;
+ PFILE_OBJECT RelatedFileObject;
PNPFS_FCB Fcb;
PNPFS_CCB ClientCcb;
PNPFS_CCB ServerCcb = NULL;
- PNPFS_DEVICE_EXTENSION DeviceExt;
- BOOLEAN SpecialAccess;
+ PNPFS_VCB Vcb;
ACCESS_MASK DesiredAccess;
+ NTSTATUS Status;
DPRINT("NpfsCreate(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
- DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
IoStack = (PEXTENDED_IO_STACK_LOCATION)IoGetCurrentIrpStackLocation(Irp);
FileObject = IoStack->FileObject;
+ RelatedFileObject = FileObject->RelatedFileObject;
+ FileName = &FileObject->FileName;
DesiredAccess = IoStack->Parameters.CreatePipe.SecurityContext->DesiredAccess;
+
DPRINT("FileObject %p\n", FileObject);
DPRINT("FileName %wZ\n", &FileObject->FileName);
Irp->IoStatus.Information = 0;
- SpecialAccess = ((DesiredAccess & SPECIFIC_RIGHTS_ALL) == FILE_READ_ATTRIBUTES);
- if (SpecialAccess)
+ if (FileName->Length == 2 && FileName->Buffer[0] == L'\\' && RelatedFileObject == NULL)
{
- DPRINT("NpfsCreate() open client end for special use!\n");
+ DPRINT("Open the root directory\n");
+
+ NpfsOpenRootDirectory(Vcb->RootFcb,
+ FileObject,
+ &Irp->IoStatus);
+
+ Status = Irp->IoStatus.Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return Status;
}
+
/*
* Step 1. Find the pipe we're trying to open.
*/
- KeLockMutex(&DeviceExt->PipeListLock);
- Fcb = NpfsFindPipe(DeviceExt,
+ KeLockMutex(&Vcb->PipeListLock);
+ Fcb = NpfsFindPipe(Vcb,
&FileObject->FileName);
if (Fcb == NULL)
{
/* Not found, bail out with error. */
DPRINT("No pipe found!\n");
- KeUnlockMutex(&DeviceExt->PipeListLock);
+ KeUnlockMutex(&Vcb->PipeListLock);
Irp->IoStatus.Status = STATUS_OBJECT_NAME_NOT_FOUND;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_OBJECT_NAME_NOT_FOUND;
}
- KeUnlockMutex(&DeviceExt->PipeListLock);
+ KeUnlockMutex(&Vcb->PipeListLock);
/*
* Acquire the lock for CCB lists. From now on no modifications to the
return STATUS_NO_MEMORY;
}
+ ClientCcb->Type = CCB_PIPE;
ClientCcb->Thread = (struct ETHREAD *)Irp->Tail.Overlay.Thread;
ClientCcb->Fcb = Fcb;
ClientCcb->PipeEnd = FILE_PIPE_CLIENT_END;
ClientCcb->OtherSide = NULL;
- ClientCcb->PipeState = SpecialAccess ? 0 : FILE_PIPE_DISCONNECTED_STATE;
+// ClientCcb->PipeState = SpecialAccess ? 0 : FILE_PIPE_DISCONNECTED_STATE;
+ ClientCcb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
InitializeListHead(&ClientCcb->ReadRequestListHead);
DPRINT("CCB: %p\n", ClientCcb);
/*
* Step 3. Search for listening server CCB.
*/
-
+/*
if (!SpecialAccess)
{
+*/
/*
* WARNING: Point of no return! Once we get the server CCB it's
* possible that we completed a wait request and so we have to
/* FIXME: Merge this with the NpfsFindListeningServerInstance routine. */
NpfsSignalAndRemoveListeningServerInstance(Fcb, ServerCcb);
}
+/*
}
else if (IsListEmpty(&Fcb->ServerCcbListHead))
{
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_UNSUCCESSFUL;
}
+*/
/*
* Step 4. Add the client CCB to a list and connect it if possible.
{
PEXTENDED_IO_STACK_LOCATION IoStack;
PFILE_OBJECT FileObject;
- PNPFS_DEVICE_EXTENSION DeviceExt;
+ PNPFS_VCB Vcb;
PNPFS_FCB Fcb;
PNPFS_CCB Ccb;
PNAMED_PIPE_CREATE_PARAMETERS Buffer;
DPRINT("NpfsCreateNamedPipe(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
- DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
IoStack = (PEXTENDED_IO_STACK_LOCATION)IoGetCurrentIrpStackLocation(Irp);
FileObject = IoStack->FileObject;
DPRINT("FileObject %p\n", FileObject);
return STATUS_NO_MEMORY;
}
+ Ccb->Type = CCB_PIPE;
Ccb->Thread = (struct ETHREAD *)Irp->Tail.Overlay.Thread;
- KeLockMutex(&DeviceExt->PipeListLock);
+ KeLockMutex(&Vcb->PipeListLock);
/*
* First search for existing Pipe with the same name.
*/
- Fcb = NpfsFindPipe(DeviceExt,
+ Fcb = NpfsFindPipe(Vcb,
&FileObject->FileName);
if (Fcb != NULL)
{
* Found Pipe with the same name. Check if we are
* allowed to use it.
*/
- KeUnlockMutex(&DeviceExt->PipeListLock);
+ KeUnlockMutex(&Vcb->PipeListLock);
if (Fcb->CurrentInstances >= Fcb->MaximumInstances)
{
Fcb = ExAllocatePool(NonPagedPool, sizeof(NPFS_FCB));
if (Fcb == NULL)
{
- KeUnlockMutex(&DeviceExt->PipeListLock);
+ KeUnlockMutex(&Vcb->PipeListLock);
ExFreePool(Ccb);
Irp->IoStatus.Status = STATUS_NO_MEMORY;
Irp->IoStatus.Information = 0;
return STATUS_NO_MEMORY;
}
+ Fcb->Type = FCB_PIPE;
+ Fcb->Vcb = Vcb;
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);
+ KeUnlockMutex(&Vcb->PipeListLock);
ExFreePool(Fcb);
ExFreePool(Ccb);
Irp->IoStatus.Status = STATUS_NO_MEMORY;
{
if (Buffer->InboundQuota == 0)
{
- Fcb->InboundQuota = DeviceExt->DefaultQuota;
+ Fcb->InboundQuota = Vcb->DefaultQuota;
}
else
{
Fcb->InboundQuota = PAGE_ROUND_UP(Buffer->InboundQuota);
- if (Fcb->InboundQuota < DeviceExt->MinQuota)
+ if (Fcb->InboundQuota < Vcb->MinQuota)
{
- Fcb->InboundQuota = DeviceExt->MinQuota;
+ Fcb->InboundQuota = Vcb->MinQuota;
}
- else if (Fcb->InboundQuota > DeviceExt->MaxQuota)
+ else if (Fcb->InboundQuota > Vcb->MaxQuota)
{
- Fcb->InboundQuota = DeviceExt->MaxQuota;
+ Fcb->InboundQuota = Vcb->MaxQuota;
}
}
}
{
if (Buffer->OutboundQuota == 0)
{
- Fcb->OutboundQuota = DeviceExt->DefaultQuota;
+ Fcb->OutboundQuota = Vcb->DefaultQuota;
}
else
{
Fcb->OutboundQuota = PAGE_ROUND_UP(Buffer->OutboundQuota);
- if (Fcb->OutboundQuota < DeviceExt->MinQuota)
+ if (Fcb->OutboundQuota < Vcb->MinQuota)
{
- Fcb->OutboundQuota = DeviceExt->MinQuota;
+ Fcb->OutboundQuota = Vcb->MinQuota;
}
- else if (Fcb->OutboundQuota > DeviceExt->MaxQuota)
+ else if (Fcb->OutboundQuota > Vcb->MaxQuota)
{
- Fcb->OutboundQuota = DeviceExt->MaxQuota;
+ Fcb->OutboundQuota = Vcb->MaxQuota;
}
}
}
Fcb->OutboundQuota = 0;
}
- InsertTailList(&DeviceExt->PipeListHead, &Fcb->PipeListEntry);
- KeUnlockMutex(&DeviceExt->PipeListLock);
+ InsertTailList(&Vcb->PipeListHead, &Fcb->PipeListEntry);
+ KeUnlockMutex(&Vcb->PipeListLock);
}
if (Fcb->InboundQuota)
if (NewPipe)
{
- KeLockMutex(&DeviceExt->PipeListLock);
+ KeLockMutex(&Vcb->PipeListLock);
RemoveEntryList(&Fcb->PipeListEntry);
- KeUnlockMutex(&DeviceExt->PipeListLock);
+ KeUnlockMutex(&Vcb->PipeListLock);
RtlFreeUnicodeString(&Fcb->PipeName);
ExFreePool(Fcb);
}
NpfsCleanup(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
- PNPFS_DEVICE_EXTENSION DeviceExt;
+ PNPFS_VCB Vcb;
PIO_STACK_LOCATION IoStack;
PFILE_OBJECT FileObject;
PNPFS_CCB Ccb, OtherSide;
DPRINT("NpfsCleanup(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
IoStack = IoGetCurrentIrpStackLocation(Irp);
- DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
FileObject = IoStack->FileObject;
Ccb = FileObject->FsContext2;
return STATUS_SUCCESS;
}
+ if (Ccb->Type == CCB_DIRECTORY)
+ {
+ DPRINT("Cleanup the root directory!\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;
NpfsClose(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
- PNPFS_DEVICE_EXTENSION DeviceExt;
PIO_STACK_LOCATION IoStack;
PFILE_OBJECT FileObject;
+ PNPFS_VCB Vcb;
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;
+ Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
FileObject = IoStack->FileObject;
Ccb = FileObject->FsContext2;
return STATUS_SUCCESS;
}
+ if (Ccb->Type == CCB_DIRECTORY)
+ {
+ DPRINT("Closing the root directory!\n");
+
+ ExFreePool(Ccb);
+ FileObject->FsContext = NULL;
+ FileObject->FsContext2 = NULL;
+
+ 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;
IsListEmpty(&Fcb->ClientCcbListHead))
{
RtlFreeUnicodeString(&Fcb->PipeName);
- KeLockMutex(&DeviceExt->PipeListLock);
+ KeLockMutex(&Vcb->PipeListLock);
RemoveEntryList(&Fcb->PipeListEntry);
- KeUnlockMutex(&DeviceExt->PipeListLock);
+ KeUnlockMutex(&Vcb->PipeListLock);
ExFreePool(Fcb);
FileObject->FsContext = NULL;
}
PIO_STACK_LOCATION IoStack;
FILE_INFORMATION_CLASS FileInformationClass;
PFILE_OBJECT FileObject;
- PNPFS_DEVICE_EXTENSION DeviceExtension;
+ PNPFS_VCB Vcb;
PNPFS_FCB Fcb;
PNPFS_CCB Ccb;
PVOID SystemBuffer;
IoStack = IoGetCurrentIrpStackLocation (Irp);
FileInformationClass = IoStack->Parameters.QueryFile.FileInformationClass;
- DeviceExtension = DeviceObject->DeviceExtension;
+ Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
FileObject = IoStack->FileObject;
Ccb = (PNPFS_CCB)FileObject->FsContext2;
Fcb = Ccb->Fcb;
PNPFS_CCB Ccb)
{
PLIST_ENTRY current_entry;
+ PNPFS_VCB Vcb;
PNPFS_FCB Fcb;
PNPFS_CCB ServerCcb;
PFILE_PIPE_WAIT_FOR_BUFFER WaitPipe;
- NTSTATUS Status;
LARGE_INTEGER TimeOut;
+ UNICODE_STRING PipeName;
+ NTSTATUS Status;
DPRINT("NpfsWaitPipe\n");
WaitPipe = (PFILE_PIPE_WAIT_FOR_BUFFER)Irp->AssociatedIrp.SystemBuffer;
- Fcb = Ccb->Fcb;
- if (Ccb->PipeState != 0)
+ /* Fail, if the CCB does not represent the root directory */
+ if (Ccb->Type != CCB_DIRECTORY)
+ return STATUS_ILLEGAL_FUNCTION;
+
+ /* Calculate the pipe name length and allocate the buffer */
+ PipeName.Length = WaitPipe->NameLength + sizeof(WCHAR);
+ PipeName.MaximumLength = PipeName.Length + sizeof(WCHAR);
+ PipeName.Buffer = ExAllocatePool(NonPagedPool, PipeName.MaximumLength);
+ if (PipeName.Buffer == NULL)
{
- DPRINT("Pipe is not in passive (waiting) state!\n");
- return STATUS_UNSUCCESSFUL;
+ DPRINT1("Could not allocate memory for the pipe name!\n");
+ return STATUS_NO_MEMORY;
}
+ /* Copy the pipe name into the buffer, prepend a backslash and append a 0 character */
+ PipeName.Buffer[0] = L'\\';
+ RtlCopyMemory(&PipeName.Buffer[1],
+ &WaitPipe->Name[0],
+ WaitPipe->NameLength);
+ PipeName.Buffer[PipeName.Length / sizeof(WCHAR)] = 0;
+
+ DPRINT("Waiting for Pipe %wZ\n", &PipeName);
+
+ /* Get the VCB */
+ Vcb = Ccb->Fcb->Vcb;
+
+ /* Lock the pipe list */
+ KeLockMutex(&Vcb->PipeListLock);
+
+ /* File a pipe with the given name */
+ Fcb = NpfsFindPipe(Vcb,
+ &PipeName);
+
+ /* Unlock the pipe list */
+ KeUnlockMutex(&Vcb->PipeListLock);
+
+ /* Release the pipe name buffer */
+ ExFreePool(PipeName.Buffer);
+
+ /* Fail if not pipe was found */
+ if (Fcb == NULL)
+ {
+ DPRINT("No pipe found!\n", Fcb);
+ return STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ DPRINT("Fcb %p\n", Fcb);
+
/* search for listening server */
current_entry = Fcb->ServerCcbListHead.Flink;
while (current_entry != &Fcb->ServerCcbListHead)
PIO_STACK_LOCATION IoStack;
PFILE_OBJECT FileObject;
NTSTATUS Status;
- PNPFS_DEVICE_EXTENSION DeviceExt;
+ PNPFS_VCB Vcb;
PNPFS_FCB Fcb;
PNPFS_CCB Ccb;
DPRINT("NpfsFileSystemContol(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
- DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
IoStack = IoGetCurrentIrpStackLocation(Irp);
DPRINT("IoStack: %p\n", IoStack);
FileObject = IoStack->FileObject;
DriverEntry(PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath)
{
- PNPFS_DEVICE_EXTENSION DeviceExtension;
PDEVICE_OBJECT DeviceObject;
UNICODE_STRING DeviceName;
+ PNPFS_VCB Vcb;
+ PNPFS_FCB Fcb;
NTSTATUS Status;
DPRINT("Named Pipe FSD 0.0.2\n");
RtlInitUnicodeString(&DeviceName, L"\\Device\\NamedPipe");
Status = IoCreateDevice(DriverObject,
- sizeof(NPFS_DEVICE_EXTENSION),
+ sizeof(NPFS_VCB),
&DeviceName,
FILE_DEVICE_NAMED_PIPE,
0,
return Status;
}
- /* initialize the device object */
+ /* Initialize the device object */
DeviceObject->Flags |= DO_DIRECT_IO;
DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
- /* initialize the device extension */
- DeviceExtension = DeviceObject->DeviceExtension;
- InitializeListHead(&DeviceExtension->PipeListHead);
- InitializeListHead(&DeviceExtension->ThreadListHead);
- KeInitializeMutex(&DeviceExtension->PipeListLock, 0);
- DeviceExtension->EmptyWaiterCount = 0;
+ /* Initialize the Volume Control Block (VCB) */
+ Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
+ InitializeListHead(&Vcb->PipeListHead);
+ InitializeListHead(&Vcb->ThreadListHead);
+ KeInitializeMutex(&Vcb->PipeListLock, 0);
+ Vcb->EmptyWaiterCount = 0;
/* set the size quotas */
- DeviceExtension->MinQuota = PAGE_SIZE;
- DeviceExtension->DefaultQuota = 8 * PAGE_SIZE;
- DeviceExtension->MaxQuota = 64 * PAGE_SIZE;
+ Vcb->MinQuota = PAGE_SIZE;
+ Vcb->DefaultQuota = 8 * PAGE_SIZE;
+ Vcb->MaxQuota = 64 * PAGE_SIZE;
+
+ Fcb = ExAllocatePool(NonPagedPool, sizeof(NPFS_FCB));
+ Fcb->Type = FCB_DIRECTORY;
+ Fcb->Vcb = Vcb;
+
+
+
+ Vcb->RootFcb = Fcb;
return STATUS_SUCCESS;
}
#include <ntifs.h>
#include <ndk/iotypes.h>
-typedef struct _NPFS_DEVICE_EXTENSION
+typedef enum _FCB_TYPE
+{
+ FCB_DEVICE,
+ FCB_DIRECTORY,
+ FCB_PIPE
+} FCB_TYPE;
+
+typedef enum _CCB_TYPE
+{
+ CCB_DEVICE,
+ CCB_DIRECTORY,
+ CCB_PIPE
+} CCB_TYPE;
+
+/* Volume Control Block (VCB) aka Device Extension */
+typedef struct _NPFS_VCB
{
LIST_ENTRY PipeListHead;
LIST_ENTRY ThreadListHead;
ULONG MinQuota;
ULONG DefaultQuota;
ULONG MaxQuota;
-} NPFS_DEVICE_EXTENSION, *PNPFS_DEVICE_EXTENSION;
+ struct _NPFS_FCB *RootFcb;
+} NPFS_VCB, *PNPFS_VCB;
typedef struct _NPFS_FCB
{
- FSRTL_COMMON_FCB_HEADER RFCB;
+ FCB_TYPE Type;
+ PNPFS_VCB Vcb;
UNICODE_STRING PipeName;
LIST_ENTRY PipeListEntry;
KMUTEX CcbListLock;
typedef struct _NPFS_CCB
{
LIST_ENTRY CcbListEntry;
+ CCB_TYPE Type;
+ PNPFS_FCB Fcb;
+
struct _NPFS_CCB* OtherSide;
struct ETHREAD *Thread;
- PNPFS_FCB Fcb;
KEVENT ConnectEvent;
KEVENT ReadEvent;
KEVENT WriteEvent;
{
ULONG Count;
KEVENT Event;
- PNPFS_DEVICE_EXTENSION DeviceExt;
+ PNPFS_VCB Vcb;
LIST_ENTRY ListEntry;
PVOID WaitObjectArray[MAXIMUM_WAIT_OBJECTS];
KWAIT_BLOCK WaitBlockArray[MAXIMUM_WAIT_OBJECTS];
DriverEntry(PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath);
+PNPFS_FCB
+NpfsFindPipe(PNPFS_VCB Vcb,
+ PUNICODE_STRING PipeName);
+
+
#endif /* __DRIVERS_FS_NP_NPFS_H */
IN PIRP Irp)
{
PNPFS_CONTEXT Context;
- PNPFS_DEVICE_EXTENSION DeviceExt;
PIO_STACK_LOCATION IoStack;
+ PNPFS_VCB Vcb;
PNPFS_CCB Ccb;
PLIST_ENTRY ListEntry;
PNPFS_THREAD_CONTEXT ThreadContext;
IoReleaseCancelSpinLock(Irp->CancelIrql);
Context = (PNPFS_CONTEXT)&Irp->Tail.Overlay.DriverContext;
- DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
IoStack = IoGetCurrentIrpStackLocation(Irp);
Ccb = IoStack->FileObject->FsContext2;
- KeLockMutex(&DeviceExt->PipeListLock);
+ KeLockMutex(&Vcb->PipeListLock);
ExAcquireFastMutex(&Ccb->DataListLock);
switch(IoStack->MajorFunction)
{
case IRP_MJ_READ:
- ListEntry = DeviceExt->ThreadListHead.Flink;
- while (ListEntry != &DeviceExt->ThreadListHead)
+ ListEntry = Vcb->ThreadListHead.Flink;
+ while (ListEntry != &Vcb->ThreadListHead)
{
ThreadContext = CONTAINING_RECORD(ListEntry, NPFS_THREAD_CONTEXT, ListEntry);
/* Real events start at index 1 */
KeSetEvent(&ThreadContext->Event, IO_NO_INCREMENT, FALSE);
ExReleaseFastMutex(&Ccb->DataListLock);
- KeUnlockMutex(&DeviceExt->PipeListLock);
+ KeUnlockMutex(&Vcb->PipeListLock);
return;
}
RemoveEntryList(&Context->ListEntry);
ExReleaseFastMutex(&Ccb->DataListLock);
- KeUnlockMutex(&DeviceExt->PipeListLock);
+ KeUnlockMutex(&Vcb->PipeListLock);
Irp->IoStatus.Status = STATUS_CANCELLED;
Irp->IoStatus.Information = 0;
PIO_STACK_LOCATION IoStack = NULL;
KIRQL OldIrql;
- KeLockMutex(&ThreadContext->DeviceExt->PipeListLock);
+ KeLockMutex(&ThreadContext->Vcb->PipeListLock);
while (1)
{
CurrentCount = ThreadContext->Count;
- KeUnlockMutex(&ThreadContext->DeviceExt->PipeListLock);
+ KeUnlockMutex(&ThreadContext->Vcb->PipeListLock);
IoAcquireCancelSpinLock(&OldIrql);
if (Irp && IoSetCancelRoutine(Irp, NULL) != NULL)
{
{
ASSERT(FALSE);
}
- KeLockMutex(&ThreadContext->DeviceExt->PipeListLock);
+ KeLockMutex(&ThreadContext->Vcb->PipeListLock);
Count = Status - STATUS_WAIT_0;
ASSERT (Count < CurrentCount);
if (Count > 0)
{
Irp = ThreadContext->WaitIrpArray[Count];
ThreadContext->Count--;
- ThreadContext->DeviceExt->EmptyWaiterCount++;
+ ThreadContext->Vcb->EmptyWaiterCount++;
ThreadContext->WaitObjectArray[Count] = ThreadContext->WaitObjectArray[ThreadContext->Count];
ThreadContext->WaitIrpArray[Count] = ThreadContext->WaitIrpArray[ThreadContext->Count];
}
if (ThreadContext->WaitIrpArray[i] == NULL)
{
ThreadContext->Count--;
- ThreadContext->DeviceExt->EmptyWaiterCount++;
+ ThreadContext->Vcb->EmptyWaiterCount++;
ThreadContext->WaitObjectArray[i] = ThreadContext->WaitObjectArray[ThreadContext->Count];
ThreadContext->WaitIrpArray[i] = ThreadContext->WaitIrpArray[ThreadContext->Count];
}
}
}
- if (ThreadContext->Count == 1 && ThreadContext->DeviceExt->EmptyWaiterCount >= MAXIMUM_WAIT_OBJECTS)
+ if (ThreadContext->Count == 1 && ThreadContext->Vcb->EmptyWaiterCount >= MAXIMUM_WAIT_OBJECTS)
{
/* it exist an other thread with empty wait slots, we can remove our thread from the list */
RemoveEntryList(&ThreadContext->ListEntry);
- ThreadContext->DeviceExt->EmptyWaiterCount -= MAXIMUM_WAIT_OBJECTS - 1;
- KeUnlockMutex(&ThreadContext->DeviceExt->PipeListLock);
+ ThreadContext->Vcb->EmptyWaiterCount -= MAXIMUM_WAIT_OBJECTS - 1;
+ KeUnlockMutex(&ThreadContext->Vcb->PipeListLock);
break;
}
}
{
PLIST_ENTRY ListEntry;
PNPFS_THREAD_CONTEXT ThreadContext = NULL;
- NTSTATUS Status;
+ PNPFS_CONTEXT Context;
HANDLE hThread;
+ PNPFS_VCB Vcb;
KIRQL oldIrql;
+ NTSTATUS Status;
- PNPFS_CONTEXT Context = (PNPFS_CONTEXT)&Irp->Tail.Overlay.DriverContext;
- PNPFS_DEVICE_EXTENSION DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ Context = (PNPFS_CONTEXT)&Irp->Tail.Overlay.DriverContext;
+ Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
DPRINT("NpfsAddWaitingReadWriteRequest(DeviceObject %p, Irp %p)\n", DeviceObject, Irp);
- KeLockMutex(&DeviceExt->PipeListLock);
+ KeLockMutex(&Vcb->PipeListLock);
- ListEntry = DeviceExt->ThreadListHead.Flink;
- while (ListEntry != &DeviceExt->ThreadListHead)
+ ListEntry = Vcb->ThreadListHead.Flink;
+ while (ListEntry != &Vcb->ThreadListHead)
{
ThreadContext = CONTAINING_RECORD(ListEntry, NPFS_THREAD_CONTEXT, ListEntry);
if (ThreadContext->Count < MAXIMUM_WAIT_OBJECTS)
}
ListEntry = ListEntry->Flink;
}
- if (ListEntry == &DeviceExt->ThreadListHead)
+
+ if (ListEntry == &Vcb->ThreadListHead)
{
ThreadContext = ExAllocatePool(NonPagedPool, sizeof(NPFS_THREAD_CONTEXT));
if (ThreadContext == NULL)
{
- KeUnlockMutex(&DeviceExt->PipeListLock);
+ KeUnlockMutex(&Vcb->PipeListLock);
return STATUS_NO_MEMORY;
}
- ThreadContext->DeviceExt = DeviceExt;
+
+ ThreadContext->Vcb = Vcb;
KeInitializeEvent(&ThreadContext->Event, SynchronizationEvent, FALSE);
ThreadContext->Count = 1;
ThreadContext->WaitObjectArray[0] = &ThreadContext->Event;
-
DPRINT("Creating a new system thread for waiting read/write requests\n");
Status = PsCreateSystemThread(&hThread,
if (!NT_SUCCESS(Status))
{
ExFreePool(ThreadContext);
- KeUnlockMutex(&DeviceExt->PipeListLock);
+ KeUnlockMutex(&Vcb->PipeListLock);
return Status;
}
- InsertHeadList(&DeviceExt->ThreadListHead, &ThreadContext->ListEntry);
- DeviceExt->EmptyWaiterCount += MAXIMUM_WAIT_OBJECTS - 1;
+
+ InsertHeadList(&Vcb->ThreadListHead, &ThreadContext->ListEntry);
+ Vcb->EmptyWaiterCount += MAXIMUM_WAIT_OBJECTS - 1;
}
IoMarkIrpPending(Irp);
ThreadContext->WaitObjectArray[ThreadContext->Count] = Context->WaitEvent;
ThreadContext->WaitIrpArray[ThreadContext->Count] = Irp;
ThreadContext->Count++;
- DeviceExt->EmptyWaiterCount--;
+ Vcb->EmptyWaiterCount--;
KeSetEvent(&ThreadContext->Event, IO_NO_INCREMENT, FALSE);
Status = STATUS_SUCCESS;
}
- KeUnlockMutex(&DeviceExt->PipeListLock);
+ KeUnlockMutex(&Vcb->PipeListLock);
return Status;
}