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/f…
==============================================================================
--- 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/m…
==============================================================================
--- 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/n…
==============================================================================
--- 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/r…
==============================================================================
--- 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/w…
==============================================================================
--- 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 */