- 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!

svn path=/trunk/; revision=61906
This commit is contained in:
Timo Kreuzer 2014-02-01 20:41:16 +00:00
parent e61f3d956b
commit 005703c2dc
5 changed files with 295 additions and 15 deletions

View file

@ -53,10 +53,86 @@ NpInternalWrite(IN PDEVICE_OBJECT DeviceObject,
NTSTATUS
NTAPI
NpQueryClientProcess(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
IN PIRP Irp)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
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 @@ NTAPI
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 @@ NpListen(IN PDEVICE_OBJECT DeviceObject,
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 @@ NpTransceive(IN PDEVICE_OBJECT DeviceObject,
}
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 @@ NpCommonFileSystemControl(IN PDEVICE_OBJECT DeviceObject,
NpAcquireSharedVcb();
Status = NpInternalTransceive(DeviceObject, Irp, &DeferredList);
break;
case FSCTL_PIPE_INTERNAL_READ_OVFLOW:
Overflow = TRUE;
// on purpose

View file

@ -20,6 +20,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 ******************************************************************/
NTSTATUS
@ -311,6 +319,7 @@ NpFsdDirectoryControl(IN PDEVICE_OBJECT DeviceObject,
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
NTAPI
DriverEntry(IN PDRIVER_OBJECT DriverObject,
@ -321,7 +330,7 @@ DriverEntry(IN PDRIVER_OBJECT DriverObject,
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 @@ DriverEntry(IN PDRIVER_OBJECT DriverObject,
DriverObject->DriverUnload = NULL;
DriverObject->FastIoDispatch = &NpFastIoDispatch;
RtlInitUnicodeString(&DeviceName, L"\\Device\\NamedPipe");
Status = IoCreateDevice(DriverObject,
sizeof(NP_VCB),

View file

@ -360,6 +360,18 @@ typedef struct _NPFS_QUERY_VALUE_CONTEXT
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 @@ NTAPI
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

View file

@ -16,6 +16,8 @@
/* GLOBALS ********************************************************************/
LONG NpSlowReadCalls;
ULONG NpFastReadTrue;
ULONG NpFastReadFalse;
/* FUNCTIONS ******************************************************************/
@ -23,8 +25,8 @@ BOOLEAN
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 @@ NpFsdRead(IN PDEVICE_OBJECT DeviceObject,
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 */

View file

@ -16,6 +16,8 @@
/* GLOBALS ********************************************************************/
LONG NpSlowWriteCalls;
ULONG NpFastWriteTrue;
ULONG NpFastWriteFalse;
/* FUNCTIONS ******************************************************************/
@ -23,10 +25,10 @@ BOOLEAN
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 @@ NpFsdWrite(IN PDEVICE_OBJECT DeviceObject,
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 */