Author: tkreuzer Date: Sat Feb 1 20:41:16 2014 New Revision: 61906
URL: http://svn.reactos.org/svn/reactos?rev=61906&view=rev Log: [NPFS] - Implement NpQueryClientProcess and NpSetClientProcess - Add a fast I/O dispatch table and implement NpFastRead and NpFastWrite The NPFS driver is now good enough to boot Windows 2003 to desktop!
Modified: trunk/reactos/drivers/filesystems/npfs/fsctrl.c trunk/reactos/drivers/filesystems/npfs/main.c trunk/reactos/drivers/filesystems/npfs/npfs.h trunk/reactos/drivers/filesystems/npfs/read.c trunk/reactos/drivers/filesystems/npfs/write.c
Modified: trunk/reactos/drivers/filesystems/npfs/fsctrl.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/npfs/fs... ============================================================================== --- trunk/reactos/drivers/filesystems/npfs/fsctrl.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/npfs/fsctrl.c [iso-8859-1] Sat Feb 1 20:41:16 2014 @@ -53,10 +53,86 @@ NTSTATUS NTAPI NpQueryClientProcess(IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + IN PIRP Irp) +{ + PIO_STACK_LOCATION IoStackLocation; + NODE_TYPE_CODE NodeTypeCode; + PNP_CCB Ccb; + PNP_CLIENT_PROCESS ClientSession, QueryBuffer; + ULONG Length; + PAGED_CODE(); + + /* Get the current stack location */ + IoStackLocation = IoGetCurrentIrpStackLocation(Irp); + + /* Decode the file object and check the node type */ + NodeTypeCode = NpDecodeFileObject(IoStackLocation->FileObject, 0, &Ccb, 0); + if (NodeTypeCode != NPFS_NTC_CCB) + { + return STATUS_PIPE_DISCONNECTED; + } + + /* Get the length of the query buffer */ + Length = IoStackLocation->Parameters.QueryFile.Length; + if (Length < 8) + { + return STATUS_INVALID_PARAMETER; + } + + QueryBuffer = Irp->AssociatedIrp.SystemBuffer; + + /* Lock the Ccb */ + ExAcquireResourceExclusiveLite(&Ccb->NonPagedCcb->Lock, TRUE); + + /* Get the CCBs client session and check if it's set */ + ClientSession = Ccb->ClientSession; + if (ClientSession != NULL) + { + /* Copy first 2 fields */ + QueryBuffer->Unknown = ClientSession->Unknown; + QueryBuffer->Process = ClientSession->Process; + } + else + { + /* Copy the process from the CCB */ + QueryBuffer->Unknown = NULL; + QueryBuffer->Process = Ccb->Process; + } + + /* Does the caller provide a large enough buffer for the full data? */ + if (Length >= sizeof(NP_CLIENT_PROCESS)) + { + Irp->IoStatus.Information = sizeof(NP_CLIENT_PROCESS); + + /* Do we have a ClientSession structure? */ + if (ClientSession != NULL) + { + /* Copy length and the data */ + QueryBuffer->DataLength = ClientSession->DataLength; + RtlCopyMemory(QueryBuffer->Buffer, + ClientSession->Buffer, + ClientSession->DataLength); + + /* NULL terminate the buffer */ + NT_ASSERT(QueryBuffer->DataLength <= 30); + QueryBuffer->Buffer[QueryBuffer->DataLength / sizeof(WCHAR)] = 0; + } + else + { + /* No data */ + QueryBuffer->DataLength = 0; + QueryBuffer->Buffer[0] = 0; + } + } + else + { + Irp->IoStatus.Information = FIELD_OFFSET(NP_CLIENT_PROCESS, DataLength); + } + + /* Unlock the Ccb */ + ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock); + + return STATUS_SUCCESS; }
NTSTATUS @@ -64,8 +140,72 @@ NpSetClientProcess(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + PIO_STACK_LOCATION IoStackLocation; + NODE_TYPE_CODE NodeTypeCode; + PNP_CCB Ccb; + ULONG Length; + PNP_CLIENT_PROCESS InputBuffer, ClientSession, OldClientSession; + PAGED_CODE(); + + /* Get the current stack location */ + IoStackLocation = IoGetCurrentIrpStackLocation(Irp); + + /* Only kernel calls are allowed! */ + if (IoStackLocation->MinorFunction != IRP_MN_KERNEL_CALL) + { + return STATUS_ACCESS_DENIED; + } + + /* Decode the file object and check the node type */ + NodeTypeCode = NpDecodeFileObject(IoStackLocation->FileObject, 0, &Ccb, 0); + if (NodeTypeCode != NPFS_NTC_CCB) + { + return STATUS_PIPE_DISCONNECTED; + } + + /* Get the length of the query buffer and check if it's valid */ + Length = IoStackLocation->Parameters.QueryFile.Length; + if (Length != sizeof(NP_CLIENT_PROCESS)) + { + return STATUS_INVALID_PARAMETER; + } + + /* Get the buffer and check if the data Length is valid */ + InputBuffer = Irp->AssociatedIrp.SystemBuffer; + if (InputBuffer->DataLength > 30) + { + return STATUS_INVALID_PARAMETER; + } + + /* Allocate a new structure */ + ClientSession = ExAllocatePoolWithQuotaTag(PagedPool, + sizeof(NP_CLIENT_PROCESS), + 'iFpN'); + + /* Copy the full input buffer */ + RtlCopyMemory(ClientSession, InputBuffer, sizeof(NP_CLIENT_PROCESS)); + + /* Lock the Ccb */ + ExAcquireResourceExclusiveLite(&Ccb->NonPagedCcb->Lock, TRUE); + + /* Get the old ClientSession and set the new */ + OldClientSession = Ccb->ClientSession; + Ccb->ClientSession = ClientSession; + + /* Copy the process to the CCB */ + Ccb->Process = ClientSession->Process; + + /* Unlock the Ccb */ + ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock); + + /* Check if there was already a ClientSession */ + if (OldClientSession != NULL) + { + /* Free it */ + ExFreePoolWithTag(OldClientSession, 'iFpN'); + } + + return STATUS_SUCCESS; }
NTSTATUS @@ -201,7 +341,7 @@ NTSTATUS NTAPI NpPeek(IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, + IN PIRP Irp, IN PLIST_ENTRY List) { PIO_STACK_LOCATION IoStack; @@ -490,7 +630,7 @@ }
if (!NT_SUCCESS(Status)) goto Quickie; - + if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE); ASSERT(ReadQueue->QueueState == Empty); Status = NpAddDataQueueEntry(NamedPipeEnd, @@ -648,7 +788,7 @@ NpAcquireSharedVcb(); Status = NpInternalTransceive(DeviceObject, Irp, &DeferredList); break; - + case FSCTL_PIPE_INTERNAL_READ_OVFLOW: Overflow = TRUE; // on purpose
Modified: trunk/reactos/drivers/filesystems/npfs/main.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/npfs/ma... ============================================================================== --- trunk/reactos/drivers/filesystems/npfs/main.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/npfs/main.c [iso-8859-1] Sat Feb 1 20:41:16 2014 @@ -19,6 +19,14 @@ PVOID NpAliases; PNPFS_ALIAS NpAliasList; PNPFS_ALIAS NpAliasListByLength[MAX_INDEXED_LENGTH + 1 - MIN_INDEXED_LENGTH]; + +FAST_IO_DISPATCH NpFastIoDispatch = +{ + sizeof(FAST_IO_DISPATCH), + NULL, + NpFastRead, + NpFastWrite, +};
/* FUNCTIONS ******************************************************************/
@@ -311,6 +319,7 @@ return STATUS_NOT_IMPLEMENTED; }
+ NTSTATUS NTAPI DriverEntry(IN PDRIVER_OBJECT DriverObject, @@ -321,7 +330,7 @@ NTSTATUS Status; UNREFERENCED_PARAMETER(RegistryPath);
- DPRINT1("Next-Generation NPFS-Lite\n"); + DPRINT1("Next-Generation NPFS-Advanced\n");
Status = NpInitializeAliases(); if (!NT_SUCCESS(Status)) @@ -347,6 +356,8 @@
DriverObject->DriverUnload = NULL;
+ DriverObject->FastIoDispatch = &NpFastIoDispatch; + RtlInitUnicodeString(&DeviceName, L"\Device\NamedPipe"); Status = IoCreateDevice(DriverObject, sizeof(NP_VCB),
Modified: trunk/reactos/drivers/filesystems/npfs/npfs.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/npfs/np... ============================================================================== --- trunk/reactos/drivers/filesystems/npfs/npfs.h [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/npfs/npfs.h [iso-8859-1] Sat Feb 1 20:41:16 2014 @@ -360,6 +360,18 @@ extern PNPFS_ALIAS NpAliasList; extern PNPFS_ALIAS NpAliasListByLength[MAX_INDEXED_LENGTH + 1 - MIN_INDEXED_LENGTH];
+// +// This structure is actually a user-mode structure and should go into a share header +// +typedef struct _NP_CLIENT_PROCESS +{ + PVOID Unknown; + PVOID Process; + USHORT DataLength; + WCHAR Buffer[17]; +} NP_CLIENT_PROCESS, *PNP_CLIENT_PROCESS; + + /* FUNCTIONS ******************************************************************/
// @@ -674,6 +686,34 @@ NpFsdRead(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
+_Function_class_(FAST_IO_READ) +_IRQL_requires_same_ +BOOLEAN +NTAPI +NpFastRead( + _In_ PFILE_OBJECT FileObject, + _In_ PLARGE_INTEGER FileOffset, + _In_ ULONG Length, + _In_ BOOLEAN Wait, + _In_ ULONG LockKey, + _Out_ PVOID Buffer, + _Out_ PIO_STATUS_BLOCK IoStatus, + _In_ PDEVICE_OBJECT DeviceObject); + +_Function_class_(FAST_IO_WRITE) +_IRQL_requires_same_ +BOOLEAN +NTAPI +NpFastWrite( + _In_ PFILE_OBJECT FileObject, + _In_ PLARGE_INTEGER FileOffset, + _In_ ULONG Length, + _In_ BOOLEAN Wait, + _In_ ULONG LockKey, + _In_ PVOID Buffer, + _Out_ PIO_STATUS_BLOCK IoStatus, + _In_ PDEVICE_OBJECT DeviceObject); +
NTSTATUS NTAPI
Modified: trunk/reactos/drivers/filesystems/npfs/read.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/npfs/re... ============================================================================== --- trunk/reactos/drivers/filesystems/npfs/read.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/npfs/read.c [iso-8859-1] Sat Feb 1 20:41:16 2014 @@ -16,6 +16,8 @@ /* GLOBALS ********************************************************************/
LONG NpSlowReadCalls; +ULONG NpFastReadTrue; +ULONG NpFastReadFalse;
/* FUNCTIONS ******************************************************************/
@@ -23,8 +25,8 @@ NTAPI NpCommonRead(IN PFILE_OBJECT FileObject, IN PVOID Buffer, - IN ULONG BufferSize, - OUT PIO_STATUS_BLOCK IoStatus, + IN ULONG BufferSize, + OUT PIO_STATUS_BLOCK IoStatus, IN PIRP Irp, IN PLIST_ENTRY List) { @@ -190,4 +192,46 @@ return IoStatus.Status; }
+ +_Function_class_(FAST_IO_READ) +_IRQL_requires_same_ +BOOLEAN +NTAPI +NpFastRead( + _In_ PFILE_OBJECT FileObject, + _In_ PLARGE_INTEGER FileOffset, + _In_ ULONG Length, + _In_ BOOLEAN Wait, + _In_ ULONG LockKey, + _Out_ PVOID Buffer, + _Out_ PIO_STATUS_BLOCK IoStatus, + _In_ PDEVICE_OBJECT DeviceObject) +{ + LIST_ENTRY DeferredList; + BOOLEAN Result; + PAGED_CODE(); + + InitializeListHead(&DeferredList); + + FsRtlEnterFileSystem(); + NpAcquireSharedVcb(); + + Result = NpCommonRead(FileObject, + Buffer, + Length, + IoStatus, + NULL, + &DeferredList); + if (Result) + ++NpFastReadTrue; + else + ++NpFastReadFalse; + + NpReleaseVcb(); + NpCompleteDeferredIrps(&DeferredList); + FsRtlExitFileSystem(); + + return Result; +} + /* EOF */
Modified: trunk/reactos/drivers/filesystems/npfs/write.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/npfs/wr... ============================================================================== --- trunk/reactos/drivers/filesystems/npfs/write.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/npfs/write.c [iso-8859-1] Sat Feb 1 20:41:16 2014 @@ -16,6 +16,8 @@ /* GLOBALS ********************************************************************/
LONG NpSlowWriteCalls; +ULONG NpFastWriteTrue; +ULONG NpFastWriteFalse;
/* FUNCTIONS ******************************************************************/
@@ -23,10 +25,10 @@ NTAPI NpCommonWrite(IN PFILE_OBJECT FileObject, IN PVOID Buffer, - IN ULONG DataSize, - IN PETHREAD Thread, - IN PIO_STATUS_BLOCK IoStatus, - IN PIRP Irp, + IN ULONG DataSize, + IN PETHREAD Thread, + IN PIO_STATUS_BLOCK IoStatus, + IN PIRP Irp, IN PLIST_ENTRY List) { NODE_TYPE_CODE NodeType; @@ -207,4 +209,47 @@ return IoStatus.Status; }
+ +_Function_class_(FAST_IO_WRITE) +_IRQL_requires_same_ +BOOLEAN +NTAPI +NpFastWrite( + _In_ PFILE_OBJECT FileObject, + _In_ PLARGE_INTEGER FileOffset, + _In_ ULONG Length, + _In_ BOOLEAN Wait, + _In_ ULONG LockKey, + _In_ PVOID Buffer, + _Out_ PIO_STATUS_BLOCK IoStatus, + _In_ PDEVICE_OBJECT DeviceObject) +{ + LIST_ENTRY DeferredList; + BOOLEAN Result; + PAGED_CODE(); + + InitializeListHead(&DeferredList); + + FsRtlEnterFileSystem(); + NpAcquireSharedVcb(); + + Result = NpCommonWrite(FileObject, + Buffer, + Length, + PsGetCurrentThread(), + IoStatus, + NULL, + &DeferredList); + if (Result) + ++NpFastWriteTrue; + else + ++NpFastWriteFalse; + + NpReleaseVcb(); + NpCompleteDeferredIrps(&DeferredList); + FsRtlExitFileSystem(); + + return Result; +} + /* EOF */