diff --git a/reactos/drivers/filesystems/npfs/create.c b/reactos/drivers/filesystems/npfs/create.c index 8dac8e9f393..fe6834a04ca 100644 --- a/reactos/drivers/filesystems/npfs/create.c +++ b/reactos/drivers/filesystems/npfs/create.c @@ -121,6 +121,8 @@ NpfsOpenFileSystem(PNPFS_FCB Fcb, return; } + RtlZeroMemory(Ccb, sizeof(NPFS_CCB)); + Ccb->Type = CCB_DEVICE; Ccb->Fcb = Fcb; @@ -150,6 +152,8 @@ NpfsOpenRootDirectory(PNPFS_FCB Fcb, return; } + RtlZeroMemory(Ccb, sizeof(NPFS_CCB)); + Ccb->Type = CCB_DIRECTORY; Ccb->Fcb = Fcb; @@ -881,6 +885,9 @@ NpfsClose(PDEVICE_OBJECT DeviceObject, { DPRINT("Closing the root directory!\n"); + if (Ccb->u.Directory.SearchPattern.Buffer != NULL) + ExFreePool(Ccb->u.Directory.SearchPattern.Buffer); + ExFreePool(Ccb); FileObject->FsContext = NULL; FileObject->FsContext2 = NULL; diff --git a/reactos/drivers/filesystems/npfs/dirctl.c b/reactos/drivers/filesystems/npfs/dirctl.c new file mode 100644 index 00000000000..24370e1dbc6 --- /dev/null +++ b/reactos/drivers/filesystems/npfs/dirctl.c @@ -0,0 +1,250 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: drivers/filesastems/npfs/dirctl.c + * PURPOSE: Named pipe filesystem + * PROGRAMMER: Eric Kohl + */ + +/* INCLUDES ******************************************************************/ + +#include "npfs.h" + +#define NDEBUG +#include + +/* FUNCTIONS *****************************************************************/ + +static NTSTATUS +NpfsQueryDirectory(PNPFS_CCB Ccb, + PIRP Irp, + PULONG Size) +{ + PIO_STACK_LOCATION Stack; + LONG BufferLength = 0; + PUNICODE_STRING SearchPattern = NULL; + FILE_INFORMATION_CLASS FileInformationClass; + ULONG FileIndex = 0; + PUCHAR Buffer = NULL; + BOOLEAN First = FALSE; + PLIST_ENTRY CurrentEntry; + PNPFS_VCB Vcb; + PNPFS_FCB PipeFcb; + ULONG PipeIndex; + BOOLEAN Found = FALSE; + NTSTATUS Status = STATUS_SUCCESS; + PFILE_NAMES_INFORMATION NamesBuffer; + PFILE_DIRECTORY_INFORMATION DirectoryBuffer; + + Stack = IoGetCurrentIrpStackLocation(Irp); + + /* Obtain the callers parameters */ + BufferLength = Stack->Parameters.QueryDirectory.Length; + SearchPattern = Stack->Parameters.QueryDirectory.FileName; + FileInformationClass = Stack->Parameters.QueryDirectory.FileInformationClass; + FileIndex = Stack->Parameters.QueryDirectory.FileIndex; + + DPRINT("SearchPattern: %p '%wZ'\n", SearchPattern, SearchPattern); + + /* Determine Buffer for result */ + if (Irp->MdlAddress) + { + Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress); + } + else + { + Buffer = Irp->UserBuffer; + } + + /* Build the search pattern string */ + DPRINT("Ccb->u.Directory.SearchPattern.Buffer: %p\n", Ccb->u.Directory.SearchPattern.Buffer); + if (Ccb->u.Directory.SearchPattern.Buffer == NULL) + { + First = TRUE; + + if (SearchPattern != NULL) + { + Ccb->u.Directory.SearchPattern.Buffer = + ExAllocatePool(NonPagedPool, SearchPattern->Length + sizeof(WCHAR)); + if (Ccb->u.Directory.SearchPattern.Buffer == NULL) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + + Ccb->u.Directory.SearchPattern.Length = SearchPattern->Length; + Ccb->u.Directory.SearchPattern.MaximumLength = SearchPattern->Length + sizeof(WCHAR); + RtlCopyMemory(Ccb->u.Directory.SearchPattern.Buffer, + SearchPattern->Buffer, + SearchPattern->Length); + Ccb->u.Directory.SearchPattern.Buffer[SearchPattern->Length / sizeof(WCHAR)] = 0; + } + else + { + Ccb->u.Directory.SearchPattern.Buffer = + ExAllocatePool(NonPagedPool, 2 * sizeof(WCHAR)); + if (Ccb->u.Directory.SearchPattern.Buffer == NULL) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + + Ccb->u.Directory.SearchPattern.Length = sizeof(WCHAR); + Ccb->u.Directory.SearchPattern.MaximumLength = 2 * sizeof(WCHAR); + Ccb->u.Directory.SearchPattern.Buffer[0] = L'*'; + Ccb->u.Directory.SearchPattern.Buffer[1] = 0; + } + } + DPRINT("Search pattern: '%wZ'\n", &Ccb->u.Directory.SearchPattern); + + /* Determine the file index */ + if (First || (Stack->Flags & SL_RESTART_SCAN)) + { + FileIndex = 0; + } else if ((Stack->Flags & SL_INDEX_SPECIFIED) == 0) + { + FileIndex = Ccb->u.Directory.FileIndex + 1; + } + DPRINT("FileIndex: %lu\n", FileIndex); + + DPRINT("Buffer = %p tofind = %wZ\n", Buffer, &Ccb->u.Directory.SearchPattern); + + PipeIndex = 0; + + Vcb = Ccb->Fcb->Vcb; + CurrentEntry = Vcb->PipeListHead.Flink; + while (CurrentEntry != &Vcb->PipeListHead && Found == FALSE) + { + /* Get the FCB of the next pipe */ + PipeFcb = CONTAINING_RECORD(CurrentEntry, + NPFS_FCB, + PipeListEntry); + + /* Make sure it is a pipe FCB */ + ASSERT(PipeFcb->Type == FCB_PIPE); + + DPRINT("PipeName: %wZ\n", &PipeFcb->PipeName); + + if (FsRtlIsNameInExpression(&Ccb->u.Directory.SearchPattern, + &PipeFcb->PipeName, + TRUE, + NULL)) + { + DPRINT("Found pipe: %wZ\n", &PipeFcb->PipeName); + + if (PipeIndex >= FileIndex) + { + switch (FileInformationClass) + { + case FileDirectoryInformation: + DirectoryBuffer = (PFILE_DIRECTORY_INFORMATION)Buffer; + DirectoryBuffer->NextEntryOffset = 0; + DirectoryBuffer->FileIndex = PipeIndex; + DirectoryBuffer->FileAttributes = FILE_ATTRIBUTE_NORMAL; + DirectoryBuffer->EndOfFile.QuadPart = PipeFcb->CurrentInstances; + DirectoryBuffer->AllocationSize.LowPart = PipeFcb->MaximumInstances; + DirectoryBuffer->FileNameLength = PipeFcb->PipeName.Length; + RtlCopyMemory(DirectoryBuffer->FileName, + PipeFcb->PipeName.Buffer, + PipeFcb->PipeName.Length); + *Size = sizeof(FILE_DIRECTORY_INFORMATION) + PipeFcb->PipeName.Length - 1; + Status = STATUS_SUCCESS; + break; + + case FileNamesInformation: + NamesBuffer = (PFILE_NAMES_INFORMATION)Buffer; + NamesBuffer->NextEntryOffset = 0; + NamesBuffer->FileIndex = PipeIndex; + NamesBuffer->FileNameLength = PipeFcb->PipeName.Length; + RtlCopyMemory(NamesBuffer->FileName, + PipeFcb->PipeName.Buffer, + PipeFcb->PipeName.Length); + *Size = sizeof(FILE_NAMES_INFORMATION) + PipeFcb->PipeName.Length - 1; + Status = STATUS_SUCCESS; + break; + + default: + DPRINT1("Invalid information class: %lu\n", FileInformationClass); + Status = STATUS_INVALID_INFO_CLASS; + break; + } + + Ccb->u.Directory.FileIndex = PipeIndex; + Found = TRUE; + +// if (Stack->Flags & SL_RETURN_SINGLE_ENTRY) +// return STATUS_SUCCESS; + + break; + } + + PipeIndex++; + } + + CurrentEntry = CurrentEntry->Flink; + } + + if (Found == FALSE) + Status = STATUS_NO_MORE_FILES; + + return Status; +} + + +NTSTATUS NTAPI +NpfsDirectoryControl(PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + PFILE_OBJECT FileObject; + PNPFS_CCB Ccb; + PNPFS_FCB Fcb; + NTSTATUS Status; + ULONG Size = 0; + + DPRINT("NpfsDirectoryControl() called\n"); + + IoStack = IoGetCurrentIrpStackLocation(Irp); + + FileObject = IoStack->FileObject; + + if (NpfsGetCcb(FileObject, &Ccb) != CCB_DIRECTORY) + { + Status = STATUS_INVALID_PARAMETER; + + Irp->IoStatus.Status = Status; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return Status; + } + + Fcb = Ccb->Fcb; + + switch (IoStack->MinorFunction) + { + case IRP_MN_QUERY_DIRECTORY: + Status = NpfsQueryDirectory(Ccb, + Irp, + &Size); + break; + + case IRP_MN_NOTIFY_CHANGE_DIRECTORY: + DPRINT1("IRP_MN_NOTIFY_CHANGE_DIRECTORY\n"); + Status = STATUS_NOT_IMPLEMENTED; + break; + + default: + DPRINT1("NPFS: MinorFunction %d\n", IoStack->MinorFunction); + Status = STATUS_INVALID_DEVICE_REQUEST; + break; + } + + Irp->IoStatus.Status = Status; + Irp->IoStatus.Information = Size; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return Status; +} + +/* EOF */ diff --git a/reactos/drivers/filesystems/npfs/npfs.c b/reactos/drivers/filesystems/npfs/npfs.c index 74fe99baeb6..dfe4ed9e4b1 100644 --- a/reactos/drivers/filesystems/npfs/npfs.c +++ b/reactos/drivers/filesystems/npfs/npfs.c @@ -44,8 +44,8 @@ DriverEntry(PDRIVER_OBJECT DriverObject, NpfsQueryVolumeInformation; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = NpfsCleanup; DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = NpfsFlushBuffers; - // DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = - // NpfsDirectoryControl; + DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = + NpfsDirectoryControl; DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = NpfsFileSystemControl; // DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] = @@ -100,4 +100,54 @@ DriverEntry(PDRIVER_OBJECT DriverObject, return STATUS_SUCCESS; } + +FCB_TYPE +NpfsGetFcb(PFILE_OBJECT FileObject, + PNPFS_FCB *Fcb) +{ + PNPFS_FCB LocalFcb = NULL; + FCB_TYPE FcbType = FCB_INVALID; + + _SEH2_TRY + { + LocalFcb = (PNPFS_FCB)FileObject->FsContext; + FcbType = LocalFcb->Type; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + LocalFcb = NULL; + FcbType = FCB_INVALID; + } + _SEH2_END; + + *Fcb = LocalFcb; + + return FcbType; +} + + +CCB_TYPE +NpfsGetCcb(PFILE_OBJECT FileObject, + PNPFS_CCB *Ccb) +{ + PNPFS_CCB LocalCcb = NULL; + CCB_TYPE CcbType = CCB_INVALID; + + _SEH2_TRY + { + LocalCcb = (PNPFS_CCB)FileObject->FsContext2; + CcbType = LocalCcb->Type; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + LocalCcb = NULL; + CcbType = CCB_INVALID; + } + _SEH2_END; + + *Ccb = LocalCcb; + + return CcbType; +} + /* EOF */ diff --git a/reactos/drivers/filesystems/npfs/npfs.h b/reactos/drivers/filesystems/npfs/npfs.h index 2e47e6858c4..0049fd3fdac 100644 --- a/reactos/drivers/filesystems/npfs/npfs.h +++ b/reactos/drivers/filesystems/npfs/npfs.h @@ -3,9 +3,11 @@ #include #include +#include typedef enum _FCB_TYPE { + FCB_INVALID, FCB_DEVICE, FCB_DIRECTORY, FCB_PIPE @@ -13,6 +15,7 @@ typedef enum _FCB_TYPE typedef enum _CCB_TYPE { + CCB_INVALID, CCB_DEVICE, CCB_DIRECTORY, CCB_PIPE @@ -55,6 +58,14 @@ typedef struct _NPFS_FCB LARGE_INTEGER TimeOut; } NPFS_FCB, *PNPFS_FCB; + +typedef struct _NPFS_CCB_DIRECTORY_DATA +{ + UNICODE_STRING SearchPattern; + ULONG FileIndex; +} NPFS_CCB_DIRECTORY_DATA, *PNPFS_CCB_DIRECTORY_DATA; + + typedef struct _NPFS_CCB { LIST_ENTRY CcbListEntry; @@ -79,6 +90,12 @@ typedef struct _NPFS_CCB ULONG MaxDataLength; FAST_MUTEX DataListLock; /* Data queue lock */ + + union + { + NPFS_CCB_DIRECTORY_DATA Directory; + } u; + } NPFS_CCB, *PNPFS_CCB; typedef struct _NPFS_CONTEXT @@ -130,6 +147,9 @@ NTSTATUS NTAPI NpfsCleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp); DRIVER_DISPATCH NpfsClose; NTSTATUS NTAPI NpfsClose(PDEVICE_OBJECT DeviceObject, PIRP Irp); +DRIVER_DISPATCH NpfsDirectoryControl; +NTSTATUS NTAPI NpfsDirectoryControl(PDEVICE_OBJECT DeviceObject, PIRP Irp); + DRIVER_DISPATCH NpfsRead; NTSTATUS NTAPI NpfsRead(PDEVICE_OBJECT DeviceObject, PIRP Irp); @@ -159,5 +179,12 @@ PNPFS_FCB NpfsFindPipe(PNPFS_VCB Vcb, PUNICODE_STRING PipeName); +FCB_TYPE +NpfsGetFcb(PFILE_OBJECT FileObject, + PNPFS_FCB *Fcb); + +CCB_TYPE +NpfsGetCcb(PFILE_OBJECT FileObject, + PNPFS_CCB *Ccb); #endif /* __DRIVERS_FS_NP_NPFS_H */ diff --git a/reactos/drivers/filesystems/npfs/npfs.rbuild b/reactos/drivers/filesystems/npfs/npfs.rbuild index a9030bfc8e6..945dd4cb8ce 100644 --- a/reactos/drivers/filesystems/npfs/npfs.rbuild +++ b/reactos/drivers/filesystems/npfs/npfs.rbuild @@ -4,7 +4,9 @@ . ntoskrnl hal + pseh create.c + dirctl.c finfo.c fsctrl.c npfs.c