diff --git a/reactos/drivers/filesystems/CMakeLists.txt b/reactos/drivers/filesystems/CMakeLists.txt index 1dd2bc7f115..bf46a8b3486 100644 --- a/reactos/drivers/filesystems/CMakeLists.txt +++ b/reactos/drivers/filesystems/CMakeLists.txt @@ -7,4 +7,5 @@ add_subdirectory(fs_rec) add_subdirectory(msfs) add_subdirectory(mup) add_subdirectory(npfs) +add_subdirectory(npfs_new) add_subdirectory(ntfs) diff --git a/reactos/drivers/filesystems/npfs_new/CMakeLists.txt b/reactos/drivers/filesystems/npfs_new/CMakeLists.txt new file mode 100644 index 00000000000..03ba64409fd --- /dev/null +++ b/reactos/drivers/filesystems/npfs_new/CMakeLists.txt @@ -0,0 +1,17 @@ + +list(APPEND SOURCE + create.c + datasup.c + fileobsup.c + main.c + prefxsup.c + secursup.c + statesup.c + strucsup.c + waitsup.c) + +add_library(npfs_new SHARED ${SOURCE}) +set_module_type(npfs_new kernelmodedriver) +add_importlibs(npfs_new ntoskrnl hal) +add_pch(npfs_new npfs.h) +add_cd_file(TARGET npfs_new DESTINATION reactos/system32/drivers FOR all) diff --git a/reactos/drivers/filesystems/npfs_new/create.c b/reactos/drivers/filesystems/npfs_new/create.c new file mode 100644 index 00000000000..6a2acc84d39 --- /dev/null +++ b/reactos/drivers/filesystems/npfs_new/create.c @@ -0,0 +1,726 @@ +#include "npfs.h" + +VOID +NTAPI +NpCheckForNotify(IN PNP_DCB Dcb, + IN BOOLEAN SecondList, + IN PLIST_ENTRY List) +{ + PLIST_ENTRY NextEntry, ListHead; + PIRP Irp; + ULONG i; + PAGED_CODE(); + + ListHead = &Dcb->NotifyList; + for (i = 0; i < 2; i++) + { + while (!IsListEmpty(ListHead)) + { + NextEntry = RemoveHeadList(ListHead); + + Irp = CONTAINING_RECORD(NextEntry, IRP, Tail.Overlay.ListEntry); + + if (IoSetCancelRoutine(Irp, NULL)) + { + Irp->IoStatus.Status = STATUS_SUCCESS; + InsertTailList(List, NextEntry); + } + else + { + InitializeListHead(NextEntry); + } + } + + if (!SecondList) break; + ListHead = &Dcb->NotifyList2; + } +} + +IO_STATUS_BLOCK +NTAPI +NpOpenNamedPipeFileSystem(IN PFILE_OBJECT FileObject, + IN ACCESS_MASK DesiredAccess) +{ + IO_STATUS_BLOCK Status; + PAGED_CODE(); + + NpSetFileObject(FileObject, NpVcb, NULL, FALSE); + ++NpVcb->ReferenceCount; + + Status.Information = 1; + Status.Status = STATUS_SUCCESS; + return Status; +} + +IO_STATUS_BLOCK +NTAPI +NpOpenNamedPipeRootDirectory(IN PNP_DCB Dcb, + IN PFILE_OBJECT FileObject, + IN ACCESS_MASK DesiredAccess, + IN PLIST_ENTRY List) +{ + IO_STATUS_BLOCK Status; + PNP_ROOT_DCB_FCB Ccb; + PAGED_CODE(); + + Status.Status = NpCreateRootDcbCcb(&Ccb); + if (NT_SUCCESS(Status.Status)) + { + NpSetFileObject(FileObject, Dcb, Ccb, FALSE); + ++Dcb->CurrentInstances; + + Status.Information = 1; + Status.Status = STATUS_SUCCESS; + } + else + { + Status.Information = 0; + } + + return Status; +} + +IO_STATUS_BLOCK +NTAPI +NpCreateClientEnd(IN PNP_FCB Fcb, + IN PFILE_OBJECT FileObject, + IN ACCESS_MASK DesiredAccess, + IN PSECURITY_QUALITY_OF_SERVICE SecurityQos, + IN PACCESS_STATE AccessState, + IN KPROCESSOR_MODE PreviousMode, + IN PETHREAD Thread, + IN PLIST_ENTRY List) +{ + PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext; + BOOLEAN AccessGranted; + ACCESS_MASK GrantedAccess; + PPRIVILEGE_SET Privileges; + UNICODE_STRING ObjectTypeName; + IO_STATUS_BLOCK IoStatus; + USHORT NamedPipeConfiguration; + PLIST_ENTRY NextEntry, ListHead; + PNP_CCB Ccb = NULL; + + IoStatus.Status = STATUS_SUCCESS; + IoStatus.Information = 0; + Privileges = NULL; + + NamedPipeConfiguration = Fcb->NamedPipeConfiguration; + + SubjectSecurityContext = &AccessState->SubjectSecurityContext; + SeLockSubjectContext(SubjectSecurityContext); + + AccessGranted = SeAccessCheck(Fcb->SecurityDescriptor, + SubjectSecurityContext, + TRUE, + DesiredAccess & ~4, + 0, + &Privileges, + IoGetFileObjectGenericMapping(), + PreviousMode, + &GrantedAccess, + &IoStatus.Status); + + if (Privileges) + { + SeAppendPrivileges(AccessState, Privileges); + SeFreePrivileges(Privileges); + } + + if (AccessGranted) + { + AccessState->PreviouslyGrantedAccess |= GrantedAccess; + AccessState->RemainingDesiredAccess &= ~(GrantedAccess | 0x2000000); + } + + ObjectTypeName.Buffer = L"NamedPipe"; + ObjectTypeName.Length = 18; + SeOpenObjectAuditAlarm(&ObjectTypeName, + NULL, + &FileObject->FileName, + Fcb->SecurityDescriptor, + AccessState, + FALSE, + AccessGranted, + PreviousMode, + &AccessState->GenerateOnClose); + SeUnlockSubjectContext(SubjectSecurityContext); + if (!AccessGranted) return IoStatus; + + if (((GrantedAccess & 1) && (NamedPipeConfiguration == FILE_PIPE_INBOUND)) || + ((GrantedAccess & 2) && (NamedPipeConfiguration == FILE_PIPE_OUTBOUND))) + { + IoStatus.Status = STATUS_ACCESS_DENIED; + return IoStatus; + } + + if (!(GrantedAccess & 3)) SecurityQos = NULL; + + ListHead = &Fcb->CcbList; + NextEntry = ListHead->Flink; + while (NextEntry != ListHead) + { + Ccb = CONTAINING_RECORD(NextEntry, NP_CCB, CcbEntry); + if (Ccb->NamedPipeState == FILE_PIPE_LISTENING_STATE) break; + + NextEntry = NextEntry->Flink; + } + + if (NextEntry == ListHead) + { + IoStatus.Status = STATUS_PIPE_NOT_AVAILABLE; + return IoStatus; + } + + IoStatus.Status = NpInitializeSecurity(Ccb, SecurityQos, Thread); + if (!NT_SUCCESS(IoStatus.Status)) return IoStatus; + + IoStatus.Status = NpSetConnectedPipeState(Ccb, FileObject, List); + if (!NT_SUCCESS(IoStatus.Status)) + { + NpUninitializeSecurity(Ccb); + return IoStatus; + } + + Ccb->ClientSession = NULL; + Ccb->Process = IoThreadToProcess(Thread); + + IoStatus.Information = 1; + IoStatus.Status = STATUS_SUCCESS; + return IoStatus; +} + +NTSTATUS +NTAPI +NpFsdCreate(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PEXTENDED_IO_STACK_LOCATION IoStack; + UNICODE_STRING FileName; + PFILE_OBJECT FileObject; + PFILE_OBJECT RelatedFileObject; + NODE_TYPE_CODE Type; + PNP_CCB Ccb; + PNP_FCB Fcb; + PNP_DCB Dcb; + ACCESS_MASK DesiredAccess; + LIST_ENTRY List; + UNICODE_STRING Prefix; + + InitializeListHead(&List); + IoStack = (PEXTENDED_IO_STACK_LOCATION)IoGetCurrentIrpStackLocation(Irp); + FileObject = IoStack->FileObject; + RelatedFileObject = FileObject->RelatedFileObject; + FileName = FileObject->FileName; + DesiredAccess = IoStack->Parameters.CreatePipe.SecurityContext->DesiredAccess; + + DPRINT1("NpfsCreate(DeviceObject %p Irp %p)\n", DeviceObject, Irp); + DPRINT1("FileObject %p\n", FileObject); + DPRINT1("FileName %wZ\n", &FileObject->FileName); + DPRINT1("FileName->Length: %hu RelatedFileObject: %p\n", FileName.Length, RelatedFileObject); + + FsRtlEnterFileSystem(); + ExAcquireResourceExclusiveLite(&NpVcb->Lock, TRUE); + + if (RelatedFileObject) + { + Type = NpDecodeFileObject(RelatedFileObject, (PVOID*)&Fcb, &Ccb, FALSE); + } + else + { + Type = 0; + Fcb = NULL; + Ccb = NULL; + } + + if (FileName.Length) + { + if ((FileName.Length == sizeof(WCHAR)) && + (FileName.Buffer[0] == OBJ_NAME_PATH_SEPARATOR) && + !(RelatedFileObject)) + { + Irp->IoStatus = NpOpenNamedPipeRootDirectory(NpVcb->RootDcb, + FileObject, + DesiredAccess, + &List); + } + } + else if (!(RelatedFileObject) || (Type == NPFS_NTC_VCB)) + { + Irp->IoStatus = NpOpenNamedPipeFileSystem(FileObject, + DesiredAccess); + } + else if (Type == NPFS_NTC_ROOT_DCB) + { + Irp->IoStatus = NpOpenNamedPipeRootDirectory(NpVcb->RootDcb, + FileObject, + DesiredAccess, + &List); + } + else + { + // Status = NpTranslateAlias(&FileName);; // ignore this for now + // if (!NT_SUCCESS(Status)) goto Quickie; + + if (RelatedFileObject) + { + if (Type == NPFS_NTC_ROOT_DCB) + { + Dcb = (PNP_DCB)Ccb; + Irp->IoStatus.Status = NpFindRelativePrefix(Dcb, + &FileName, + 1, + &Prefix, + &Fcb); + if (!NT_SUCCESS(Irp->IoStatus.Status)) goto Quickie; + } + else if ((Type != NPFS_NTC_CCB) || (FileName.Length)) + { + Irp->IoStatus.Status = STATUS_OBJECT_NAME_INVALID; + goto Quickie; + } + else + { + Prefix.Length = 0; + } + } + else + { + if ((FileName.Length <= sizeof(WCHAR)) || + (FileName.Buffer[0] != OBJ_NAME_PATH_SEPARATOR)) + { + Irp->IoStatus.Status = STATUS_OBJECT_NAME_INVALID; + goto Quickie; + } + + Fcb = NpFindPrefix(&FileName, 1, &Prefix); + } + + if (Prefix.Length) + { + Irp->IoStatus.Status = Fcb->NodeType != NPFS_NTC_FCB ? + STATUS_OBJECT_NAME_NOT_FOUND : + STATUS_OBJECT_NAME_INVALID; + } + + if (!Fcb->CurrentInstances) + { + Irp->IoStatus.Status = STATUS_OBJECT_NAME_NOT_FOUND; + } + else + { + Irp->IoStatus = NpCreateClientEnd(Fcb, + FileObject, + DesiredAccess, + IoStack->Parameters.CreatePipe. + SecurityContext->SecurityQos, + IoStack->Parameters.CreatePipe. + SecurityContext->AccessState, + IoStack->Flags & + SL_FORCE_ACCESS_CHECK ? + UserMode : Irp->RequestorMode, + Irp->Tail.Overlay.Thread, + &List); + } + } + +Quickie: + ExReleaseResourceLite(&NpVcb->Lock); + ASSERT(IsListEmpty(&List) == TRUE); + FsRtlExitFileSystem(); + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Irp->IoStatus.Status; +} + +IO_STATUS_BLOCK +NTAPI +NpCreateExistingNamedPipe(IN PNP_FCB Fcb, + IN PFILE_OBJECT FileObject, + IN ACCESS_MASK DesiredAccess, + IN PACCESS_STATE AccessState, + IN KPROCESSOR_MODE PreviousMode, + IN ULONG Disposition, + IN ULONG ShareAccess, + IN PNAMED_PIPE_CREATE_PARAMETERS Parameters, + IN PEPROCESS Process, + OUT PLIST_ENTRY List) +{ + PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext; + IO_STATUS_BLOCK IoStatus; + UNICODE_STRING ObjectTypeName; + ACCESS_MASK GrantedAccess; + PNP_CCB Ccb; + PPRIVILEGE_SET Privileges; + USHORT NamedPipeConfiguration, CheckShareAccess; + BOOLEAN AccessGranted; + PAGED_CODE(); + + Privileges = NULL; + + NamedPipeConfiguration = Fcb->NamedPipeConfiguration; + + SubjectSecurityContext = &AccessState->SubjectSecurityContext; + SeLockSubjectContext(SubjectSecurityContext); + + AccessGranted = SeAccessCheck(Fcb->SecurityDescriptor, + SubjectSecurityContext, + TRUE, + DesiredAccess | 4, + 0, + &Privileges, + IoGetFileObjectGenericMapping(), + PreviousMode, + &GrantedAccess, + &IoStatus.Status); + + if (Privileges) + { + SeAppendPrivileges(AccessState, Privileges); + SeFreePrivileges(Privileges); + } + + if (AccessGranted) + { + AccessState->PreviouslyGrantedAccess |= GrantedAccess; + AccessState->RemainingDesiredAccess &= ~(GrantedAccess | 0x2000000); + } + + + ObjectTypeName.Buffer = L"NamedPipe"; + ObjectTypeName.Length = 18; + SeOpenObjectAuditAlarm(&ObjectTypeName, + NULL, + &FileObject->FileName, + Fcb->SecurityDescriptor, + AccessState, + FALSE, + AccessGranted, + PreviousMode, + &AccessState->GenerateOnClose); + + SeUnlockSubjectContext(SubjectSecurityContext); + if ( !AccessGranted ) return IoStatus; + + if ( Fcb->CurrentInstances >= Fcb->MaximumInstances ) + { + IoStatus.Status = STATUS_INSTANCE_NOT_AVAILABLE; + return IoStatus; + } + + if ( Disposition == FILE_CREATE ) + { + IoStatus.Status = STATUS_ACCESS_DENIED; + return IoStatus; + } + + CheckShareAccess = 0; + if (NamedPipeConfiguration == FILE_PIPE_FULL_DUPLEX) + { + CheckShareAccess = FILE_SHARE_READ | FILE_SHARE_WRITE; + } + else if (NamedPipeConfiguration == FILE_PIPE_OUTBOUND) + { + CheckShareAccess = FILE_SHARE_READ; + } + else if (NamedPipeConfiguration == FILE_PIPE_INBOUND) + { + CheckShareAccess = FILE_SHARE_WRITE; + } + + if ( CheckShareAccess != ShareAccess ) + { + IoStatus.Status = STATUS_ACCESS_DENIED; + return IoStatus; + } + + IoStatus.Status = NpCreateCcb(Fcb, + FileObject, + FILE_PIPE_LISTENING_STATE, + Parameters->ReadMode & 0xFF, + Parameters->CompletionMode & 0xFF, + Parameters->InboundQuota, + Parameters->OutboundQuota, + &Ccb); + if (!NT_SUCCESS(IoStatus.Status)) return IoStatus; + + IoStatus.Status = NpCancelWaiter(&NpVcb->WaitQueue, + &Fcb->FullName, + FALSE, + List); + if (!NT_SUCCESS(IoStatus.Status)) + { + --Ccb->Fcb->CurrentInstances; + NpDeleteCcb(Ccb, List); + return IoStatus; + } + + NpSetFileObject(FileObject, Ccb, Ccb->NonPagedCcb, TRUE); + Ccb->ServerFileObject = FileObject; + NpCheckForNotify(Fcb->ParentDcb, 0, List); + + IoStatus.Status = STATUS_SUCCESS; + IoStatus.Information = 1; + return IoStatus; +} + +NTSTATUS +NTAPI +NpCreateNewNamedPipe(IN PNP_DCB Dcb, + IN PFILE_OBJECT FileObject, + IN UNICODE_STRING PipeName, + IN ACCESS_MASK DesiredAccess, + IN PACCESS_STATE AccessState, + IN USHORT Disposition, + IN USHORT ShareAccess, + IN PNAMED_PIPE_CREATE_PARAMETERS Parameters, + IN PEPROCESS Process, + IN PLIST_ENTRY List, + IN PIO_STATUS_BLOCK IoStatus) +{ + NTSTATUS Status; + USHORT NamedPipeConfiguration; + PSECURITY_SUBJECT_CONTEXT SecurityContext; + PSECURITY_DESCRIPTOR SecurityDescriptor, CachedSecurityDescriptor; + PNP_CCB Ccb; + PNP_FCB Fcb; + PAGED_CODE(); + + if (!(Parameters->TimeoutSpecified) || + !(Parameters->MaximumInstances) || + (Parameters->DefaultTimeout.HighPart >= 0)) + { + Status = STATUS_INVALID_PARAMETER; + goto Quickie; + } + + if (Disposition == FILE_OPEN) + { + Status = STATUS_OBJECT_NAME_NOT_FOUND; + goto Quickie; + } + + if (ShareAccess == (FILE_SHARE_READ | FILE_SHARE_WRITE)) + { + NamedPipeConfiguration = FILE_PIPE_FULL_DUPLEX; + } + else if (ShareAccess == FILE_SHARE_READ) + { + NamedPipeConfiguration = FILE_PIPE_OUTBOUND; + } + else if (ShareAccess == FILE_SHARE_WRITE) + { + NamedPipeConfiguration = FILE_PIPE_INBOUND; + } + else + { + Status = STATUS_INVALID_PARAMETER; + goto Quickie; + } + + if ( !Parameters->NamedPipeType && Parameters->ReadMode == 1 ) + { + Status = STATUS_INVALID_PARAMETER; + goto Quickie; + } + + Status = NpCreateFcb(Dcb, + &PipeName, + Parameters->MaximumInstances, + Parameters->DefaultTimeout, + NamedPipeConfiguration, + Parameters->NamedPipeType & 0xFFFF, + &Fcb); + if (!NT_SUCCESS(Status)) goto Quickie; + + Status = NpCreateCcb(Fcb, + FileObject, + FILE_PIPE_LISTENING_STATE, + Parameters->ReadMode & 0xFF, + Parameters->CompletionMode & 0xFF, + Parameters->InboundQuota, + Parameters->OutboundQuota, + &Ccb); + if (!NT_SUCCESS(Status)) + { + NpDeleteFcb(Fcb, List); + goto Quickie; + } + + SecurityContext = &AccessState->SubjectSecurityContext; + SeLockSubjectContext(&AccessState->SubjectSecurityContext); + + Status = SeAssignSecurity(0, + AccessState->SecurityDescriptor, + &SecurityDescriptor, + 0, + SecurityContext, + IoGetFileObjectGenericMapping(), + PagedPool); + SeUnlockSubjectContext(SecurityContext); + if (!NT_SUCCESS(Status)) + { + NpDeleteCcb(Ccb, List); + NpDeleteFcb(Fcb, List); + goto Quickie; + } + + Status = ObLogSecurityDescriptor(SecurityDescriptor, + &CachedSecurityDescriptor, + 1); + ExFreePool(SecurityDescriptor); + + if (!NT_SUCCESS(Status)) + { + NpDeleteCcb(Ccb, List); + NpDeleteFcb(Fcb, List); + goto Quickie; + } + + Fcb->SecurityDescriptor = CachedSecurityDescriptor; + + NpSetFileObject(FileObject, Ccb, Ccb->NonPagedCcb, TRUE); + Ccb->ServerFileObject = FileObject; + + NpCheckForNotify(Dcb, 1, List); + + IoStatus->Status = 0; + IoStatus->Information = 2; + return STATUS_SUCCESS; + +Quickie: + IoStatus->Information = 0; + IoStatus->Status = Status; + return Status; +} + +NTSTATUS +NTAPI +NpFsdCreateNamedPipe(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PEXTENDED_IO_STACK_LOCATION IoStack; + PFILE_OBJECT FileObject; + PFILE_OBJECT RelatedFileObject; + USHORT Disposition, ShareAccess; + PEPROCESS Process; + LIST_ENTRY LocalList; + UNICODE_STRING FileName; + PNP_FCB Fcb; + UNICODE_STRING Prefix; + PNAMED_PIPE_CREATE_PARAMETERS Parameters; + IO_STATUS_BLOCK IoStatus; + + DPRINT1("NpFsdCreateNamedPipe(DeviceObject %p Irp %p)\n", DeviceObject, Irp); + + InitializeListHead(&LocalList); + Process = IoGetRequestorProcess(Irp); + + IoStack = (PEXTENDED_IO_STACK_LOCATION) IoGetCurrentIrpStackLocation(Irp); + FileObject = IoStack->FileObject; + RelatedFileObject = FileObject->RelatedFileObject; + + Disposition = (IoStack->Parameters.CreatePipe.Options >> 24) & 0xFF; + ShareAccess = IoStack->Parameters.CreatePipe.ShareAccess & 0xFFFF; + Parameters = IoStack->Parameters.CreatePipe.Parameters; + + FileName.Buffer = FileObject->FileName.Buffer; + FileName.Length = FileObject->FileName.Length; + FileName.MaximumLength = FileObject->FileName.MaximumLength; + + IoStatus.Status = STATUS_SUCCESS; + IoStatus.Information = 0; + + FsRtlEnterFileSystem(); + ExAcquireResourceExclusiveLite(&NpVcb->Lock, TRUE); + + DPRINT1("FileObject %p\n", FileObject); + DPRINT1("FileName %wZ\n", &FileObject->FileName); + DPRINT1("FileName->Length: %hu RelatedFileObject: %p\n", FileName.Length, RelatedFileObject); + + if ( RelatedFileObject ) + { + Fcb = (PNP_FCB)((ULONG_PTR)RelatedFileObject->FsContext & ~1); + if (!(Fcb) || + (Fcb->NodeType != NPFS_NTC_ROOT_DCB) || + (FileName.Length < sizeof(WCHAR)) || + (FileName.Buffer[0] == OBJ_NAME_PATH_SEPARATOR)) + { + IoStatus.Status = STATUS_OBJECT_NAME_INVALID; + goto Quickie; + } + + IoStatus.Status = NpFindRelativePrefix(RelatedFileObject->FsContext, + &FileName, + TRUE, + &Prefix, + &Fcb); + if (!NT_SUCCESS(IoStatus.Status)) goto Quickie; + } + else + { + if ( FileName.Length <= 2u || *FileName.Buffer != '\\' ) + { + IoStatus.Status = STATUS_OBJECT_NAME_INVALID; + goto Quickie; + } + Fcb = NpFindPrefix(&FileName, 1u, &Prefix); + } + + if ( Prefix.Length ) + { + if (Fcb->NodeType == NPFS_NTC_ROOT_DCB ) + { + IoStatus.Status = NpCreateNewNamedPipe((PNP_DCB)Fcb, + FileObject, + FileName, + IoStack->Parameters.CreatePipe. + SecurityContext->DesiredAccess, + IoStack->Parameters.CreatePipe. + SecurityContext->AccessState, + Disposition, + ShareAccess, + Parameters, + Process, + &LocalList, + &Irp->IoStatus); + goto Quickie; + } + else + { + IoStatus.Status = STATUS_OBJECT_NAME_INVALID; + goto Quickie; + } + } + if (Fcb->NodeType != NPFS_NTC_FCB ) + { + IoStatus.Status = STATUS_OBJECT_NAME_INVALID; + goto Quickie; + } + + Irp->IoStatus = NpCreateExistingNamedPipe(Fcb, + FileObject, + IoStack->Parameters.CreatePipe. + SecurityContext->DesiredAccess, + IoStack->Parameters.CreatePipe. + SecurityContext->AccessState, + IoStack->Flags & + SL_FORCE_ACCESS_CHECK ? + UserMode : Irp->RequestorMode, + Disposition, + ShareAccess, + Parameters, + Process, + &LocalList); + +Quickie: + ExReleaseResourceLite(&NpVcb->Lock); + ASSERT(IsListEmpty(&LocalList)); + + FsRtlExitFileSystem(); + + Irp->IoStatus = IoStatus; + IoCompleteRequest(Irp, IO_DISK_INCREMENT); + return IoStatus.Status; +} + diff --git a/reactos/drivers/filesystems/npfs_new/datasup.c b/reactos/drivers/filesystems/npfs_new/datasup.c new file mode 100644 index 00000000000..3c7794d8a87 --- /dev/null +++ b/reactos/drivers/filesystems/npfs_new/datasup.c @@ -0,0 +1,30 @@ +#include "npfs.h" + +NTSTATUS +NTAPI +NpUninitializeDataQueue(IN PNP_DATA_QUEUE DataQueue) +{ + PAGED_CODE(); + + ASSERT(DataQueue->QueueState == Empty); + + RtlZeroMemory(DataQueue, sizeof(*DataQueue)); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +NpInitializeDataQueue(IN PNP_DATA_QUEUE DataQueue, + IN ULONG Quota) +{ + PAGED_CODE(); + + DataQueue->BytesInQueue = 0; + DataQueue->EntriesInQueue = 0; + DataQueue->QuotaUsed = 0; + DataQueue->ByteOffset = 0; + DataQueue->QueueState = Empty; + DataQueue->Quota = Quota; + InitializeListHead(&DataQueue->List); + return STATUS_SUCCESS; +} diff --git a/reactos/drivers/filesystems/npfs_new/fileobsup.c b/reactos/drivers/filesystems/npfs_new/fileobsup.c new file mode 100644 index 00000000000..23495e04e8f --- /dev/null +++ b/reactos/drivers/filesystems/npfs_new/fileobsup.c @@ -0,0 +1,72 @@ +#include "npfs.h" + +NODE_TYPE_CODE +NTAPI +NpDecodeFileObject(IN PFILE_OBJECT FileObject, + OUT PVOID* PrimaryContext OPTIONAL, + OUT PNP_CCB* Ccb, + OUT PBOOLEAN ServerSide OPTIONAL) +{ + ULONG_PTR Context; + PNP_CCB Node; + PAGED_CODE(); + + Context = (ULONG_PTR)FileObject->FsContext; + if ((Context) && (Context != 1)) + { + if (ServerSide) *ServerSide = Context & 1; + + Node = (PVOID)(Context & ~1); + + switch (Node->NodeType) + { + case NPFS_NTC_VCB: + return NPFS_NTC_VCB; + + case NPFS_NTC_ROOT_DCB: + *Ccb = FileObject->FsContext2; + if (PrimaryContext) *PrimaryContext = Node; + return NPFS_NTC_ROOT_DCB; + + case NPFS_NTC_CCB: + *Ccb = Node; + if (PrimaryContext) *PrimaryContext = Node->Fcb; + return NPFS_NTC_CCB; + + default: + KeBugCheckEx(NPFS_FILE_SYSTEM, 0xB0108, Node->NodeType, 0, 0); + break; + } + } + + return 0; +} + +VOID +NTAPI +NpSetFileObject(IN PFILE_OBJECT FileObject, + IN PVOID PrimaryContext, + IN PVOID Ccb, + IN BOOLEAN ServerSide) +{ + BOOLEAN FileIsPipe; + PAGED_CODE(); + + if (!FileObject) return; + + if ((PrimaryContext) && (((PNP_CCB)PrimaryContext)->NodeType == NPFS_NTC_CCB)) + { + FileIsPipe = TRUE; + if (ServerSide) PrimaryContext = (PVOID)((ULONG_PTR)PrimaryContext | 1); + } + else + { + FileIsPipe = FALSE; + } + + FileObject->FsContext = PrimaryContext; + FileObject->FsContext2 = Ccb; + FileObject->PrivateCacheMap = (PVOID)1; + if (FileIsPipe) FileObject->Flags |= FO_NAMED_PIPE; +} + diff --git a/reactos/drivers/filesystems/npfs_new/main.c b/reactos/drivers/filesystems/npfs_new/main.c new file mode 100644 index 00000000000..a69c91b053e --- /dev/null +++ b/reactos/drivers/filesystems/npfs_new/main.c @@ -0,0 +1,201 @@ +#include "npfs.h" + +PDEVICE_OBJECT NpfsDeviceObject; + +NTSTATUS +NTAPI +NpFsdClose(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + UNIMPLEMENTED; + + Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +NpFsdRead(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + UNIMPLEMENTED; + + Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +NpFsdWrite(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + UNIMPLEMENTED; + + Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +NpFsdQueryInformation(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + UNIMPLEMENTED; + + Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +NpFsdSetInformation(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + UNIMPLEMENTED; + + Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +NpFsdQueryVolumeInformation(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + UNIMPLEMENTED; + + Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +NpFsdCleanup(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + UNIMPLEMENTED; + + Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +NpFsdFlushBuffers(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + UNIMPLEMENTED; + + Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +NpFsdDirectoryControl(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + UNIMPLEMENTED; + + Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +NpFsdFileSystemControl(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + UNIMPLEMENTED; + + Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +DriverEntry(IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath) +{ + PDEVICE_OBJECT DeviceObject; + UNICODE_STRING DeviceName; + NTSTATUS Status; + UNREFERENCED_PARAMETER(RegistryPath); + + DPRINT1("Next-Generation NPFS-Lite\n"); + + DriverObject->MajorFunction[IRP_MJ_CREATE] = NpFsdCreate; + DriverObject->MajorFunction[IRP_MJ_CREATE_NAMED_PIPE] = NpFsdCreateNamedPipe; + DriverObject->MajorFunction[IRP_MJ_CLOSE] = NpFsdClose; + DriverObject->MajorFunction[IRP_MJ_READ] = NpFsdRead; + DriverObject->MajorFunction[IRP_MJ_WRITE] = NpFsdWrite; + DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = NpFsdQueryInformation; + DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = NpFsdSetInformation; + DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = NpFsdQueryVolumeInformation; + DriverObject->MajorFunction[IRP_MJ_CLEANUP] = NpFsdCleanup; + DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = NpFsdFlushBuffers; + DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = NpFsdDirectoryControl; + DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = NpFsdFileSystemControl; + // DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] = + // NpfsQuerySecurity; + // DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] = + // NpfsSetSecurity; + + DriverObject->DriverUnload = NULL; + + RtlInitUnicodeString(&DeviceName, L"\\Device\\NamedPipe"); + Status = IoCreateDevice(DriverObject, + sizeof(NP_VCB), + &DeviceName, + FILE_DEVICE_NAMED_PIPE, + 0, + FALSE, + &DeviceObject); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to create named pipe device! (Status %lx)\n", Status); + return Status; + } + + /* Initialize the device object */ + NpfsDeviceObject = DeviceObject; + DeviceObject->Flags |= DO_DIRECT_IO; + DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; + + /* Initialize the Volume Control Block (VCB) */ + NpVcb = DeviceObject->DeviceExtension; + NpInitializeVcb(); + Status = NpCreateRootDcb(); + ASSERT(Status == STATUS_SUCCESS); + return STATUS_SUCCESS; +} diff --git a/reactos/drivers/filesystems/npfs_new/npfs.h b/reactos/drivers/filesystems/npfs_new/npfs.h new file mode 100644 index 00000000000..10ab7336870 --- /dev/null +++ b/reactos/drivers/filesystems/npfs_new/npfs.h @@ -0,0 +1,318 @@ +// +// System Headers +// +#include +#include +#define UNIMPLEMENTED +#define DPRINT1 DbgPrint + +// +// Allow Microsoft Extensions +// +#ifdef _MSC_VER +#pragma warning(disable:4201) +#pragma warning(disable:4214) +#pragma warning(disable:4100) +#endif + +// +// Node Type Codes for NPFS +// +#define NPFS_NTC_VCB 1 +#define NPFS_NTC_ROOT_DCB 2 +#define NPFS_NTC_FCB 4 +#define NPFS_NTC_CCB 6 +#define NPFS_NTC_NONPAGED_CCB 7 +#define NPFS_NTC_ROOT_DCB_CCB 8 +typedef USHORT NODE_TYPE_CODE, *PNODE_TYPE_CODE; + +// +// Data Queue States +// +typedef enum _NP_DATA_QUEUE_STATE +{ + Empty = 2 +} NP_DATA_QUEUE_STATE; + +// +// An Input or Output Data Queue. Each CCB has two of these. +// +typedef struct _NP_DATA_QUEUE +{ + LIST_ENTRY List; + ULONG QueueState; + ULONG BytesInQueue; + ULONG EntriesInQueue; + ULONG QuotaUsed; + ULONG ByteOffset; + ULONG Quota; +} NP_DATA_QUEUE, *PNP_DATA_QUEUE; + +// +// A Wait Queue. Only the VCB has one of these. +// +typedef struct _NP_WAIT_QUEUE +{ + LIST_ENTRY WaitList; + KSPIN_LOCK WaitLock; +} NP_WAIT_QUEUE, *PNP_WAIT_QUEUE; + +// +// The CCB for the Root DCB +// +typedef struct _NP_ROOT_DCB_CCB +{ + NODE_TYPE_CODE NodeType; + PVOID Unknown; + ULONG Unknown2; +} NP_ROOT_DCB_CCB, *PNP_ROOT_DCB_FCB; + +// +// The header that both FCB and DCB share +// +typedef struct _NP_CB_HEADER +{ + NODE_TYPE_CODE NodeType; + LIST_ENTRY DcbEntry; + PVOID ParentDcb; + ULONG CurrentInstances; + ULONG OtherCount; + PSECURITY_DESCRIPTOR SecurityDescriptor; +} NP_CB_HEADER, *PNP_CB_HEADER; + +// +// The footer that both FCB and DCB share +// +typedef struct _NP_CB_FOOTER +{ + UNICODE_STRING FullName; + UNICODE_STRING ShortName; + UNICODE_PREFIX_TABLE_ENTRY PrefixTableEntry; +} NP_CB_FOOTER; + +// +// A Directory Control Block (DCB) +// +typedef struct _NP_DCB +{ + // + // Common Header + // + NP_CB_HEADER; + + // + // DCB-specific data + // + LIST_ENTRY NotifyList; + LIST_ENTRY NotifyList2; + LIST_ENTRY FcbList; + + // + // Common Footer + // + NP_CB_FOOTER; +} NP_DCB, *PNP_DCB; + +// +// A File Control BLock (FCB) +// +typedef struct _NP_FCB +{ + // + // Common Header + // + NP_CB_HEADER; + + // + // FCB-specific fields + // + ULONG MaximumInstances; + USHORT NamedPipeConfiguration; + USHORT NamedPipeType; + LARGE_INTEGER Timeout; + LIST_ENTRY CcbList; + + // + // Common Footer + // + NP_CB_FOOTER; +} NP_FCB, *PNP_FCB; + +// +// The nonpaged portion of the CCB +// +typedef struct _NP_NONPAGED_CCB +{ + NODE_TYPE_CODE NodeType; + PVOID EventBufferClient; + PVOID EventBufferServer; + ERESOURCE Lock; +} NP_NONPAGED_CCB, *PNP_NONPAGED_CCB; + +// +// A Client Control Block (CCB) +// +typedef struct _NP_CCB +{ + NODE_TYPE_CODE NodeType; + UCHAR NamedPipeState; + UCHAR ClientReadMode:1; + UCHAR ClientCompletionMode:1; + UCHAR ServerReadMode:1; + UCHAR ClientReservedFlags:6; + UCHAR ServerCompletionMode:1; + UCHAR ServerReservedFlags:6; + SECURITY_QUALITY_OF_SERVICE ClientQos; + LIST_ENTRY CcbEntry; + PNP_FCB Fcb; + PFILE_OBJECT ClientFileObject; + PFILE_OBJECT ServerFileObject; + PEPROCESS Process; + PVOID ClientSession; + PNP_NONPAGED_CCB NonPagedCcb; + NP_DATA_QUEUE InQueue; + NP_DATA_QUEUE OutQueue; + PSECURITY_CLIENT_CONTEXT ClientContext; + LIST_ENTRY IrpList; +} NP_CCB, *PNP_CCB; + +// +// A Volume Control Block (VCB) +// +typedef struct _NP_VCB +{ + NODE_TYPE_CODE NodeType; + ULONG ReferenceCount; + PNP_DCB RootDcb; + UNICODE_PREFIX_TABLE PrefixTable; + ERESOURCE Lock; + RTL_GENERIC_TABLE EventTable; + NP_WAIT_QUEUE WaitQueue; +} NP_VCB, *PNP_VCB; + +extern PNP_VCB NpVcb; + +VOID +NTAPI +NpInitializeWaitQueue(IN PNP_WAIT_QUEUE WaitQueue); + + +NTSTATUS +NTAPI +NpUninitializeDataQueue(IN PNP_DATA_QUEUE DataQueue); + +NTSTATUS +NTAPI +NpInitializeDataQueue(IN PNP_DATA_QUEUE DataQueue, + IN ULONG Quota); + +NTSTATUS +NTAPI +NpCreateCcb(IN PNP_FCB Fcb, + IN PFILE_OBJECT FileObject, + IN UCHAR State, + IN UCHAR ReadMode, + IN UCHAR CompletionMode, + IN ULONG InQuota, + IN ULONG OutQuota, + OUT PNP_CCB* NewCcb); + +NTSTATUS +NTAPI +NpCreateFcb(IN PNP_DCB Dcb, + IN PUNICODE_STRING PipeName, + IN ULONG MaximumInstances, + IN LARGE_INTEGER Timeout, + IN USHORT NamedPipeConfiguration, + IN USHORT NamedPipeType, + OUT PNP_FCB *NewFcb); + +NTSTATUS +NTAPI +NpCreateRootDcb(VOID); + +NTSTATUS +NTAPI +NpCreateRootDcbCcb(IN PNP_ROOT_DCB_FCB* NewRootCcb); + +VOID +NTAPI +NpInitializeVcb(VOID); + +VOID +NTAPI +NpDeleteCcb(IN PNP_CCB Ccb, + IN PLIST_ENTRY ListEntry); + +VOID +NTAPI +NpDeleteFcb(IN PNP_FCB Fcb, + IN PLIST_ENTRY ListEntry); + +NTSTATUS +NTAPI +NpFsdCreateNamedPipe(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +NTSTATUS +NTAPI +NpFsdCreate(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +NTSTATUS +NTAPI +NpSetConnectedPipeState(IN PNP_CCB Ccb, + IN PFILE_OBJECT FileObject, + IN PLIST_ENTRY List); + +VOID +NTAPI +NpUninitializeSecurity(IN PNP_CCB Ccb); + +NTSTATUS +NTAPI +NpInitializeSecurity(IN PNP_CCB Ccb, + IN PSECURITY_QUALITY_OF_SERVICE SecurityQos, + IN PETHREAD Thread); + +VOID +NTAPI +NpSetFileObject(IN PFILE_OBJECT FileObject, + IN PVOID PrimaryContext, + IN PVOID Ccb, + IN BOOLEAN ServerSide); + +NODE_TYPE_CODE +NTAPI +NpDecodeFileObject(IN PFILE_OBJECT FileObject, + OUT PVOID* PrimaryContext OPTIONAL, + OUT PNP_CCB* Ccb, + OUT PBOOLEAN ServerSide OPTIONAL); + +PNP_FCB +NTAPI +NpFindPrefix(IN PUNICODE_STRING Name, + IN ULONG CaseInsensitiveIndex, + IN PUNICODE_STRING Prefix); + +NTSTATUS +NTAPI +NpFindRelativePrefix(IN PNP_DCB Dcb, + IN PUNICODE_STRING Name, + IN ULONG CaseInsensitiveIndex, + IN PUNICODE_STRING Prefix, + OUT PNP_FCB *FoundFcb); + +VOID +NTAPI +NpCheckForNotify(IN PNP_DCB Dcb, + IN BOOLEAN SecondList, + IN PLIST_ENTRY List); + +NTSTATUS +NTAPI +NpCancelWaiter(IN PNP_WAIT_QUEUE WaitQueue, + IN PUNICODE_STRING PipeName, + IN NTSTATUS Status, + IN PLIST_ENTRY ListEntry); + diff --git a/reactos/drivers/filesystems/npfs_new/prefxsup.c b/reactos/drivers/filesystems/npfs_new/prefxsup.c new file mode 100644 index 00000000000..ff6e97d2a20 --- /dev/null +++ b/reactos/drivers/filesystems/npfs_new/prefxsup.c @@ -0,0 +1,77 @@ +#include "npfs.h" + +PNP_FCB +NTAPI +NpFindPrefix(IN PUNICODE_STRING Name, + IN ULONG CaseInsensitiveIndex, + IN PUNICODE_STRING Prefix) +{ + PUNICODE_PREFIX_TABLE_ENTRY Entry; + PNP_FCB Fcb; + PAGED_CODE(); + + Entry = RtlFindUnicodePrefix(&NpVcb->PrefixTable, + Name, + CaseInsensitiveIndex); + if (!Entry) KeBugCheckEx(NPFS_FILE_SYSTEM, 0x100065u, 0, 0, 0); + + Fcb = CONTAINING_RECORD(Entry, NP_FCB, PrefixTableEntry); + + Prefix->Length = Name->Length - Fcb->FullName.Length; + Prefix->MaximumLength = Prefix->Length; + Prefix->Buffer = &Name->Buffer[Fcb->FullName.Length / sizeof(WCHAR)]; + + if ((Prefix->Length) && (Prefix->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)) + { + Prefix->Length -= sizeof(WCHAR); + Prefix->MaximumLength -= sizeof(WCHAR); + ++Prefix->Buffer; + } + + return Fcb; +} + +NTSTATUS +NTAPI +NpFindRelativePrefix(IN PNP_DCB Dcb, + IN PUNICODE_STRING Name, + IN ULONG CaseInsensitiveIndex, + IN PUNICODE_STRING Prefix, + OUT PNP_FCB *FoundFcb) +{ + PWCHAR Buffer; + PNP_FCB Fcb; + UNICODE_STRING RootName; + USHORT Length, MaximumLength; + PAGED_CODE(); + + Length = Name->Length; + MaximumLength = Length + sizeof(OBJ_NAME_PATH_SEPARATOR) + sizeof(UNICODE_NULL); + if (MaximumLength < Length) return STATUS_INVALID_PARAMETER; + + ASSERT(Dcb->NodeType == NPFS_NTC_ROOT_DCB); + + Buffer = ExAllocatePoolWithTag(PagedPool, MaximumLength, 'nFpN'); + if (!Buffer) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + + *Buffer = OBJ_NAME_PATH_SEPARATOR; + RtlCopyMemory(Buffer + 1, Name->Buffer, Length); + Buffer[(Length / sizeof(WCHAR)) + 1] = UNICODE_NULL; + + RootName.Length = Length + sizeof(OBJ_NAME_PATH_SEPARATOR); + RootName.MaximumLength = MaximumLength; + RootName.Buffer = Buffer; + + Fcb = NpFindPrefix(&RootName, CaseInsensitiveIndex, Prefix); + + ExFreePool(Buffer); + + Prefix->Buffer = &Name->Buffer[(Length - Prefix->Length) / sizeof(WCHAR)]; + *FoundFcb = Fcb; + + return STATUS_SUCCESS; +} + diff --git a/reactos/drivers/filesystems/npfs_new/secursup.c b/reactos/drivers/filesystems/npfs_new/secursup.c new file mode 100644 index 00000000000..5b0c47e522e --- /dev/null +++ b/reactos/drivers/filesystems/npfs_new/secursup.c @@ -0,0 +1,65 @@ +#include "npfs.h" + +VOID +NTAPI +NpUninitializeSecurity(IN PNP_CCB Ccb) +{ + PACCESS_TOKEN ClientToken; + PSECURITY_CLIENT_CONTEXT ClientContext; + TOKEN_TYPE TokenType; + PAGED_CODE(); + + ClientContext = Ccb->ClientContext; + if (!ClientContext) return; + + TokenType = SeTokenType(ClientContext->ClientToken); + ClientToken = Ccb->ClientContext->ClientToken; + if ((TokenType == TokenPrimary) || (ClientToken)) + { + ObfDereferenceObject(ClientToken); + } + ExFreePool(Ccb->ClientContext); + Ccb->ClientContext = 0; +} + +NTSTATUS +NTAPI +NpInitializeSecurity(IN PNP_CCB Ccb, + IN PSECURITY_QUALITY_OF_SERVICE SecurityQos, + IN PETHREAD Thread) +{ + PSECURITY_CLIENT_CONTEXT ClientContext; + NTSTATUS Status; + PAGED_CODE(); + + if (SecurityQos) + { + Ccb->ClientQos = *SecurityQos; + } + else + { + Ccb->ClientQos.Length = 12; + Ccb->ClientQos.ImpersonationLevel = 2; + Ccb->ClientQos.ContextTrackingMode = 1; + Ccb->ClientQos.EffectiveOnly = 1; + } + + NpUninitializeSecurity(Ccb); + + if (Ccb->ClientQos.ContextTrackingMode) + { + Status = 0; + Ccb->ClientContext = 0; + return Status; + } + + ClientContext = ExAllocatePoolWithTag(PagedPool, sizeof(*ClientContext), 'sFpN'); + Ccb->ClientContext = ClientContext; + if (!ClientContext) return STATUS_INSUFFICIENT_RESOURCES; + + Status = SeCreateClientSecurity(Thread, &Ccb->ClientQos, 0, ClientContext); + if (Status >= 0) return Status; + ExFreePool(Ccb->ClientContext); + Ccb->ClientContext = 0; + return Status; +} diff --git a/reactos/drivers/filesystems/npfs_new/statesup.c b/reactos/drivers/filesystems/npfs_new/statesup.c new file mode 100644 index 00000000000..7e45b33dfbb --- /dev/null +++ b/reactos/drivers/filesystems/npfs_new/statesup.c @@ -0,0 +1,39 @@ +#include "npfs.h" + +NTSTATUS +NTAPI +NpSetConnectedPipeState(IN PNP_CCB Ccb, + IN PFILE_OBJECT FileObject, + IN PLIST_ENTRY List) +{ + PLIST_ENTRY NextEntry; + PIRP Irp; + + ASSERT(Ccb->NamedPipeState == FILE_PIPE_LISTENING_STATE); + + Ccb->ClientReadMode = FILE_PIPE_BYTE_STREAM_MODE; + Ccb->ClientCompletionMode = FILE_PIPE_QUEUE_OPERATION; + Ccb->NamedPipeState = FILE_PIPE_CONNECTED_STATE; + Ccb->ClientFileObject = FileObject; + + NpSetFileObject(FileObject, Ccb, Ccb->NonPagedCcb, FALSE); + + while (!IsListEmpty(&Ccb->IrpList)) + { + NextEntry = RemoveHeadList(&Ccb->IrpList); + + Irp = CONTAINING_RECORD(NextEntry, IRP, Tail.Overlay.ListEntry); + + if (IoSetCancelRoutine(Irp, NULL)) + { + Irp->IoStatus.Status = STATUS_SUCCESS; + InsertTailList(List, NextEntry); + } + else + { + InitializeListHead(NextEntry); + } + } + + return STATUS_SUCCESS; +} diff --git a/reactos/drivers/filesystems/npfs_new/strucsup.c b/reactos/drivers/filesystems/npfs_new/strucsup.c new file mode 100644 index 00000000000..5faf02215cc --- /dev/null +++ b/reactos/drivers/filesystems/npfs_new/strucsup.c @@ -0,0 +1,339 @@ +#include "npfs.h" + +#define UNIMPLEMENTED + +PWCHAR NpRootDCBName = L"\\"; +PNP_VCB NpVcb; + +RTL_GENERIC_COMPARE_RESULTS +NTAPI +NpEventTableCompareRoutine(IN PRTL_GENERIC_TABLE Table, + IN PVOID FirstStruct, + IN PVOID SecondStruct) +{ + UNIMPLEMENTED; + return GenericEqual; +} + +PVOID +NTAPI +NpEventTableAllocate(IN PRTL_GENERIC_TABLE Table, + IN CLONG ByteSize) +{ + UNIMPLEMENTED; + return NULL; +} + +VOID +NTAPI +NpEventTableDeallocate(IN PRTL_GENERIC_TABLE Table, + IN PVOID Buffer) +{ + UNIMPLEMENTED; +} + +BOOLEAN +NTAPI +NpDeleteEventTableEntry(IN PRTL_GENERIC_TABLE Table, + IN PVOID Buffer) +{ + UNIMPLEMENTED; + return FALSE; +} + +VOID +NTAPI +NpDeleteFcb(IN PNP_FCB Fcb, + IN PLIST_ENTRY ListEntry) +{ + PNP_DCB Dcb; + + PAGED_CODE(); + + Dcb = Fcb->ParentDcb; + if (!Fcb->CurrentInstances) KeBugCheckEx(NPFS_FILE_SYSTEM, 0x17025F, 0, 0, 0); + + NpCancelWaiter(&NpVcb->WaitQueue, + &Fcb->FullName, + STATUS_OBJECT_NAME_NOT_FOUND, + ListEntry); + + RemoveEntryList(&Fcb->DcbEntry); + + if ( Fcb->SecurityDescriptor ) + { + ObDereferenceSecurityDescriptor(Fcb->SecurityDescriptor, 1); + } + + RtlRemoveUnicodePrefix(&NpVcb->PrefixTable, &Fcb->PrefixTableEntry); + ExFreePool(Fcb->FullName.Buffer); + ExFreePool(Fcb); + NpCheckForNotify(Dcb, TRUE, ListEntry); +} + +VOID +NTAPI +NpDeleteCcb(IN PNP_CCB Ccb, + IN PLIST_ENTRY ListEntry) +{ + PNP_ROOT_DCB_FCB RootDcbCcb; + PAGED_CODE(); + + RootDcbCcb = (PNP_ROOT_DCB_FCB)Ccb; + if ( Ccb->NodeType == NPFS_NTC_CCB ) + { + RemoveEntryList(&Ccb->CcbEntry); + --Ccb->Fcb->CurrentInstances; + + NpDeleteEventTableEntry(&NpVcb->EventTable, + Ccb->NonPagedCcb->EventBufferClient); + NpDeleteEventTableEntry(&NpVcb->EventTable, + Ccb->NonPagedCcb->EventBufferServer); + NpUninitializeDataQueue(&Ccb->InQueue); + NpUninitializeDataQueue(&Ccb->OutQueue); + NpCheckForNotify(Ccb->Fcb->ParentDcb, 0, ListEntry); + ExDeleteResourceLite(&Ccb->NonPagedCcb->Lock); + NpUninitializeSecurity(Ccb); + if ( Ccb->ClientSession ) + { + ExFreePool(Ccb->ClientSession); + Ccb->ClientSession = 0; + } + ExFreePool(Ccb->NonPagedCcb); + } + else if ( RootDcbCcb->NodeType == NPFS_NTC_ROOT_DCB_CCB && RootDcbCcb->Unknown) + { + ExFreePool(RootDcbCcb->Unknown); + } + + ExFreePool(Ccb); +} + +VOID +NTAPI +NpInitializeVcb(VOID) +{ + PAGED_CODE(); + + RtlZeroMemory(NpVcb, sizeof(*NpVcb)); + + NpVcb->NodeType = NPFS_NTC_VCB; + RtlInitializeUnicodePrefix(&NpVcb->PrefixTable); + ExInitializeResourceLite(&NpVcb->Lock); + RtlInitializeGenericTable(&NpVcb->EventTable, + NpEventTableCompareRoutine, + NpEventTableAllocate, + NpEventTableDeallocate, + 0); + NpInitializeWaitQueue(&NpVcb->WaitQueue); +} + +NTSTATUS +NTAPI +NpCreateRootDcbCcb(IN PNP_ROOT_DCB_FCB* NewRootCcb) +{ + PNP_ROOT_DCB_FCB RootCcb; + PAGED_CODE(); + + RootCcb = ExAllocatePoolWithTag(PagedPool, sizeof(*RootCcb), 'CFpN'); + if (!RootCcb) return STATUS_INSUFFICIENT_RESOURCES; + + RtlZeroMemory(RootCcb, sizeof(*RootCcb)); + RootCcb->NodeType = NPFS_NTC_ROOT_DCB_CCB; + *NewRootCcb = RootCcb; + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +NpCreateRootDcb(VOID) +{ + PNP_DCB Dcb; + PAGED_CODE(); + + if (NpVcb->RootDcb) + { + KeBugCheckEx(0x25, 0x1700F3, 0, 0, 0); + } + + NpVcb->RootDcb = ExAllocatePoolWithTag(PagedPool, sizeof(*Dcb), 'DFpN'); + if (!NpVcb->RootDcb) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + + Dcb = NpVcb->RootDcb; + RtlZeroMemory(Dcb, sizeof(*Dcb)); + Dcb->NodeType = NPFS_NTC_ROOT_DCB; + + InitializeListHead(&Dcb->DcbEntry); + InitializeListHead(&Dcb->NotifyList); + InitializeListHead(&Dcb->NotifyList2); + InitializeListHead(&Dcb->FcbList); + + Dcb->FullName.Buffer = NpRootDCBName; + Dcb->FullName.Length = 2; + Dcb->FullName.MaximumLength = 4; + + Dcb->ShortName.Length = Dcb->FullName.Length; + Dcb->ShortName.MaximumLength = Dcb->FullName.MaximumLength; + Dcb->ShortName.Buffer = Dcb->FullName.Buffer; + + if (!RtlInsertUnicodePrefix(&NpVcb->PrefixTable, + &Dcb->FullName, + &Dcb->PrefixTableEntry)) + { + KeBugCheckEx(0x25u, 0x170128, 0, 0, 0); + } + + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +NpCreateFcb(IN PNP_DCB Dcb, + IN PUNICODE_STRING PipeName, + IN ULONG MaximumInstances, + IN LARGE_INTEGER Timeout, + IN USHORT NamedPipeConfiguration, + IN USHORT NamedPipeType, + OUT PNP_FCB *NewFcb) +{ + PNP_FCB Fcb; + BOOLEAN RootPipe; + PWCHAR NameBuffer; + ULONG BufferOffset; + USHORT PipeNameLength; + PAGED_CODE(); + + PipeNameLength = PipeName->Length; + + if ((PipeNameLength < sizeof(WCHAR)) || + ((PipeNameLength + sizeof(WCHAR)) < PipeNameLength) || + (PipeName->Buffer[0] != OBJ_NAME_PATH_SEPARATOR)) + { + return STATUS_INVALID_PARAMETER; + } + + RootPipe = FALSE; + if (PipeNameLength == sizeof(WCHAR)) + { + RootPipe = TRUE; + PipeNameLength += sizeof(WCHAR); + } + + Fcb = ExAllocatePoolWithTag(PagedPool, sizeof(*Fcb), 'FfpN'); + if (!Fcb) return STATUS_INSUFFICIENT_RESOURCES; + + RtlZeroMemory(Fcb, sizeof(*Fcb)); + Fcb->MaximumInstances = MaximumInstances; + Fcb->Timeout = Timeout; + Fcb->NodeType = NPFS_NTC_FCB; + Fcb->ParentDcb = Dcb; + InitializeListHead(&Fcb->CcbList); + + NameBuffer = ExAllocatePoolWithTag(PagedPool, + PipeName->Length + (RootPipe ? 4 : 2), + 'nFpN'); + if (!NameBuffer) + { + ExFreePool(Fcb); + return STATUS_INSUFFICIENT_RESOURCES; + } + + InsertTailList(&Dcb->FcbList, &Fcb->DcbEntry); + + BufferOffset = 0; + if (RootPipe) + { + *NameBuffer = OBJ_NAME_PATH_SEPARATOR; + BufferOffset = 1; + } + + RtlCopyMemory(NameBuffer + BufferOffset, PipeName->Buffer, PipeNameLength); + NameBuffer[BufferOffset + (PipeNameLength / sizeof(WCHAR))] = UNICODE_NULL; + + Fcb->FullName.Length = PipeNameLength - sizeof(WCHAR); + Fcb->FullName.MaximumLength = PipeNameLength; + Fcb->FullName.Buffer = NameBuffer; + + Fcb->ShortName.MaximumLength = PipeNameLength - sizeof(WCHAR); + Fcb->ShortName.Length = PipeNameLength - 2 * sizeof(WCHAR); + Fcb->ShortName.Buffer = NameBuffer + 1; + + if (!RtlInsertUnicodePrefix(&NpVcb->PrefixTable, + &Fcb->FullName, + &Fcb->PrefixTableEntry)) + { + KeBugCheckEx(NPFS_FILE_SYSTEM, 0x170222, 0, 0, 0); + } + + Fcb->NamedPipeConfiguration = NamedPipeConfiguration; + Fcb->NamedPipeType = NamedPipeType; + *NewFcb = Fcb; + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +NpCreateCcb(IN PNP_FCB Fcb, + IN PFILE_OBJECT FileObject, + IN UCHAR State, + IN UCHAR ReadMode, + IN UCHAR CompletionMode, + IN ULONG InQuota, + IN ULONG OutQuota, + OUT PNP_CCB* NewCcb) +{ + PNP_CCB Ccb; + PNP_NONPAGED_CCB CcbNonPaged; + NTSTATUS Status; + PAGED_CODE(); + + Ccb = ExAllocatePoolWithTag(PagedPool, sizeof(*Ccb), 'cFpN'); + if (!Ccb) return STATUS_INSUFFICIENT_RESOURCES; + + CcbNonPaged = ExAllocatePoolWithTag(NonPagedPool, sizeof(*CcbNonPaged), 'cFpN'); + if (!CcbNonPaged) + { + ExFreePool(Ccb); + return STATUS_INSUFFICIENT_RESOURCES; + } + + RtlZeroMemory(CcbNonPaged, sizeof(*CcbNonPaged)); + CcbNonPaged->NodeType = NPFS_NTC_NONPAGED_CCB; + + RtlZeroMemory(Ccb, sizeof(*Ccb)); + Ccb->NodeType = NPFS_NTC_CCB; + Ccb->NonPagedCcb = CcbNonPaged; + Ccb->ServerFileObject = FileObject; + Ccb->Fcb = Fcb; + Ccb->NamedPipeState = State; + Ccb->ServerReadMode = ReadMode; + Ccb->ServerCompletionMode = CompletionMode; + + Status = NpInitializeDataQueue(&Ccb->InQueue, InQuota); + if (!NT_SUCCESS(Status)) + { + ExFreePool(CcbNonPaged); + ExFreePool(Ccb); + return STATUS_INSUFFICIENT_RESOURCES; + } + + Status = NpInitializeDataQueue(&Ccb->OutQueue, InQuota); + if (!NT_SUCCESS(Status)) + { + NpUninitializeDataQueue(&Ccb->InQueue); + ExFreePool(CcbNonPaged); + ExFreePool(Ccb); + return STATUS_INSUFFICIENT_RESOURCES; + } + + InsertTailList(&Fcb->CcbList, &Ccb->CcbEntry); + + InitializeListHead(&Ccb->IrpList); + ExInitializeResourceLite(&Ccb->NonPagedCcb->Lock); + *NewCcb = Ccb; + return STATUS_SUCCESS; +} + diff --git a/reactos/drivers/filesystems/npfs_new/waitsup.c b/reactos/drivers/filesystems/npfs_new/waitsup.c new file mode 100644 index 00000000000..fbbd3907db1 --- /dev/null +++ b/reactos/drivers/filesystems/npfs_new/waitsup.c @@ -0,0 +1,35 @@ +#include "npfs.h" + +VOID +NTAPI +NpInitializeWaitQueue(IN PNP_WAIT_QUEUE WaitQueue) +{ + InitializeListHead(&WaitQueue->WaitList); + KeInitializeSpinLock(&WaitQueue->WaitLock); +} + +NTSTATUS +NTAPI +NpCancelWaiter(IN PNP_WAIT_QUEUE WaitQueue, + IN PUNICODE_STRING PipeName, + IN NTSTATUS Status, + IN PLIST_ENTRY ListEntry) +{ + UNICODE_STRING DestinationString; + KIRQL OldIrql; + PWCHAR Buffer; + + Buffer = ExAllocatePoolWithTag(NonPagedPool, PipeName->Length,'tFpN'); + if (!Buffer) return STATUS_INSUFFICIENT_RESOURCES; + + RtlInitEmptyUnicodeString(&DestinationString, Buffer, PipeName->Length); + RtlUpcaseUnicodeString(&DestinationString, PipeName, FALSE); + + OldIrql = KfAcquireSpinLock(&WaitQueue->WaitLock); + + ASSERT(IsListEmpty(&WaitQueue->WaitList) == TRUE); + + KfReleaseSpinLock(&WaitQueue->WaitLock, OldIrql); + ExFreePool(DestinationString.Buffer); + return STATUS_SUCCESS; +}