Author: ion
Date: Mon Sep 9 01:16:06 2013
New Revision: 59998
URL:
http://svn.reactos.org/svn/reactos?rev=59998&view=rev
Log:
[NPFS-NEW]: Add data queue management routines, and add read support. Implement NpFsdRead
& NpfsCommonRead (Peek is inherently implemented too, just didn't write the FSCTL
handlers yet). Next up will be Write/Peek/Close/Cleanup. Code is WIP.
Added:
trunk/reactos/drivers/filesystems/npfs_new/read.c (with props)
trunk/reactos/drivers/filesystems/npfs_new/readsup.c (with props)
Modified:
trunk/reactos/drivers/filesystems/npfs_new/CMakeLists.txt
trunk/reactos/drivers/filesystems/npfs_new/datasup.c
trunk/reactos/drivers/filesystems/npfs_new/main.c
trunk/reactos/drivers/filesystems/npfs_new/npfs.h
trunk/reactos/drivers/filesystems/npfs_new/secursup.c
Modified: trunk/reactos/drivers/filesystems/npfs_new/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/npfs_n…
==============================================================================
--- trunk/reactos/drivers/filesystems/npfs_new/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/npfs_new/CMakeLists.txt [iso-8859-1] Mon Sep 9
01:16:06 2013
@@ -1,17 +1,20 @@
list(APPEND SOURCE
- create.c
- datasup.c
- fileobsup.c
- main.c
- prefxsup.c
- secursup.c
- statesup.c
- strucsup.c
- waitsup.c)
+ create.c
+ datasup.c
+ fileobsup.c
+ main.c
+ prefxsup.c
+ read.c
+ readsup.c
+ secursup.c
+ statesup.c
+ strucsup.c
+ waitsup.c)
add_library(npfs_new SHARED ${SOURCE})
set_module_type(npfs_new kernelmodedriver)
+target_link_libraries(npfs_new ${PSEH_LIB})
add_importlibs(npfs_new ntoskrnl hal)
add_pch(npfs_new npfs.h)
add_cd_file(TARGET npfs_new DESTINATION reactos/system32/drivers FOR all)
Modified: trunk/reactos/drivers/filesystems/npfs_new/datasup.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/npfs_n…
==============================================================================
--- trunk/reactos/drivers/filesystems/npfs_new/datasup.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/npfs_new/datasup.c [iso-8859-1] Mon Sep 9 01:16:06
2013
@@ -25,6 +25,435 @@
DataQueue->ByteOffset = 0;
DataQueue->QueueState = Empty;
DataQueue->Quota = Quota;
- InitializeListHead(&DataQueue->List);
+ InitializeListHead(&DataQueue->Queue);
return STATUS_SUCCESS;
}
+
+VOID
+NTAPI
+NpCompleteStalledWrites(IN PNP_DATA_QUEUE DataQueue,
+ IN PLIST_ENTRY List)
+{
+ ULONG QuotaLeft, ByteOffset, DataLeft, NewQuotaLeft;
+ PNP_DATA_QUEUE_ENTRY DataQueueEntry;
+ PIRP Irp;
+ PLIST_ENTRY NextEntry;
+
+ QuotaLeft = DataQueue->Quota - DataQueue->QuotaUsed;
+ ByteOffset = DataQueue->ByteOffset;
+
+ NextEntry = DataQueue->Queue.Flink;
+ while (NextEntry != &DataQueue->Queue)
+ {
+ if ( !QuotaLeft ) break;
+
+ DataQueueEntry = CONTAINING_RECORD(NextEntry, NP_DATA_QUEUE_ENTRY, Irp);
+
+ Irp = DataQueueEntry->Irp;
+
+ if ((DataQueueEntry->DataEntryType == 0) && (Irp))
+ {
+ DataLeft = DataQueueEntry->DataSize - ByteOffset;
+
+ if ( DataQueueEntry->QuotaInEntry < DataLeft )
+ {
+ NewQuotaLeft = DataLeft - DataQueueEntry->QuotaInEntry;
+ if ( NewQuotaLeft > QuotaLeft ) NewQuotaLeft = QuotaLeft;
+
+ QuotaLeft -= NewQuotaLeft;
+ DataQueueEntry->QuotaInEntry += NewQuotaLeft;
+
+ if (DataQueueEntry->QuotaInEntry == DataLeft &&
+ IoSetCancelRoutine(Irp, NULL))
+ {
+ DataQueueEntry->Irp = NULL;
+
+ Irp->IoStatus.Status = 0;
+ Irp->IoStatus.Information = DataQueueEntry->DataSize;
+
+ InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
+ }
+ }
+ }
+
+ NextEntry = NextEntry->Flink;
+ ByteOffset = 0;
+ }
+
+ DataQueue->QuotaUsed = DataQueue->Quota - QuotaLeft;
+}
+
+PIRP
+NTAPI
+NpRemoveDataQueueEntry(IN PNP_DATA_QUEUE DataQueue,
+ IN BOOLEAN Flag,
+ IN PLIST_ENTRY List)
+{
+ PIRP Irp;
+ PNP_DATA_QUEUE_ENTRY QueueEntry;
+ BOOLEAN HasWrites;
+
+ if ( DataQueue->QueueState == Empty)
+ {
+ Irp = NULL;
+ ASSERT(IsListEmpty(&DataQueue->Queue));
+ ASSERT(DataQueue->EntriesInQueue == 0);
+ ASSERT(DataQueue->BytesInQueue == 0);
+ ASSERT(DataQueue->QuotaUsed == 0);
+ }
+ else
+ {
+ QueueEntry = CONTAINING_RECORD(RemoveHeadList(&DataQueue->Queue),
+ NP_DATA_QUEUE_ENTRY,
+ QueueEntry);
+
+ DataQueue->BytesInQueue -= QueueEntry->DataSize;
+ --DataQueue->EntriesInQueue;
+
+ HasWrites = 1;
+ if ( !DataQueue->QueueState != WriteEntries || DataQueue->QuotaUsed <
DataQueue->Quota || !QueueEntry->QuotaInEntry )
+ {
+ HasWrites = 0;
+ }
+
+ DataQueue->QuotaUsed -= QueueEntry->QuotaInEntry;
+
+ if (DataQueue->Queue.Flink == &DataQueue->Queue)
+ {
+ DataQueue->QueueState = Empty;
+ HasWrites = 0;
+ }
+
+ Irp = QueueEntry->Irp;
+ NpFreeClientSecurityContext(QueueEntry->ClientSecurityContext);
+
+ if (Irp && IoSetCancelRoutine(Irp, NULL))
+ {
+ Irp->Tail.Overlay.DriverContext[3] = 0;
+ }
+
+ ExFreePool(QueueEntry);
+
+ if ( Flag )
+ {
+ NpGetNextRealDataQueueEntry(DataQueue, List);
+ }
+
+ if ( HasWrites )
+ {
+ NpCompleteStalledWrites(DataQueue, List);
+ }
+ }
+
+ DataQueue->ByteOffset = 0;
+ return Irp;
+}
+
+PNP_DATA_QUEUE_ENTRY
+NTAPI
+NpGetNextRealDataQueueEntry(IN PNP_DATA_QUEUE DataQueue,
+ IN PLIST_ENTRY List)
+{
+ PNP_DATA_QUEUE_ENTRY DataEntry;
+ ULONG Type;
+ PIRP Irp;
+ PLIST_ENTRY NextEntry;
+ PAGED_CODE();
+
+ DataEntry = NULL;
+
+ NextEntry = DataQueue->Queue.Flink;
+ while (NextEntry != &DataQueue->Queue)
+ {
+ DataEntry = CONTAINING_RECORD(NextEntry, NP_DATA_QUEUE_ENTRY, QueueEntry);
+
+ Type = DataEntry->DataEntryType;
+ if ( Type == Buffered || Type == Unbuffered ) break;
+
+ Irp = NpRemoveDataQueueEntry(DataQueue, 0, List);
+ if ( Irp )
+ {
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
+ }
+ }
+
+ return DataEntry;
+}
+
+VOID
+NTAPI
+NpCancelDataQueueIrp(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ PNP_DATA_QUEUE DataQueue;
+ PNP_DATA_QUEUE_ENTRY DataEntry;
+ LIST_ENTRY List;
+ PSECURITY_CLIENT_CONTEXT ClientSecurityContext;
+ BOOLEAN CompleteWrites, FirstEntry;
+ PLIST_ENTRY NextEntry, ThisEntry;
+
+ if ( DeviceObject ) IoReleaseCancelSpinLock(Irp->CancelIrql);
+
+ InitializeListHead(&List);
+
+ DataQueue = (PNP_DATA_QUEUE)Irp->Tail.Overlay.DriverContext[2];
+ ClientSecurityContext = NULL;
+
+ if ( DeviceObject )
+ {
+ FsRtlEnterFileSystem();
+ ExAcquireResourceExclusiveLite(&NpVcb->Lock, TRUE);
+ }
+
+ DataEntry = (PNP_DATA_QUEUE_ENTRY)Irp->Tail.Overlay.DriverContext[3];
+ if ( DataEntry )
+ {
+ if (DataEntry->QueueEntry.Blink == &DataQueue->Queue )
+ {
+ DataQueue->ByteOffset = 0;
+ FirstEntry = 1;
+ }
+ else
+ {
+ FirstEntry = 0;
+ }
+
+ RemoveEntryList(&DataEntry->QueueEntry);
+
+ ClientSecurityContext = DataEntry->ClientSecurityContext;
+
+ CompleteWrites = 1;
+ if ( !DataQueue->QueueState != WriteEntries || DataQueue->QuotaUsed <
DataQueue->Quota || !DataEntry->QuotaInEntry )
+ {
+ CompleteWrites = 0;
+ }
+
+ DataQueue->BytesInQueue -= DataEntry->DataSize;
+ DataQueue->QuotaUsed -= DataEntry->QuotaInEntry;
+ --DataQueue->EntriesInQueue;
+
+ if (DataQueue->Queue.Flink == &DataQueue->Queue )
+ {
+ DataQueue->QueueState = Empty;
+ ASSERT(DataQueue->BytesInQueue == 0);
+ ASSERT(DataQueue->EntriesInQueue == 0);
+ ASSERT(DataQueue->QuotaUsed == 0);
+ }
+ else
+ {
+ if ( FirstEntry )
+ {
+ NpGetNextRealDataQueueEntry(DataQueue, &List);
+ }
+ if ( CompleteWrites )
+ {
+ NpCompleteStalledWrites(DataQueue, &List);
+ }
+ }
+ }
+
+ if ( DeviceObject )
+ {
+ ExReleaseResourceLite(&NpVcb->Lock);
+ FsRtlExitFileSystem();
+ }
+
+ if ( DataEntry ) ExFreePool(DataEntry);
+
+ NpFreeClientSecurityContext(ClientSecurityContext);
+ Irp->IoStatus.Status = STATUS_CANCELLED;
+ IofCompleteRequest(Irp, IO_DISK_INCREMENT);
+
+ NextEntry = List.Flink;
+ while (NextEntry != &List)
+ {
+ ThisEntry = NextEntry;
+ NextEntry = NextEntry->Flink;
+
+ Irp = CONTAINING_RECORD(ThisEntry, IRP, Tail.Overlay.ListEntry);
+ IoCompleteRequest(Irp, IO_DISK_INCREMENT);
+ }
+}
+
+NTSTATUS
+NTAPI
+NpAddDataQueueEntry(IN BOOLEAN ServerSide,
+ IN PNP_CCB Ccb,
+ IN PNP_DATA_QUEUE DataQueue,
+ IN ULONG Who,
+ IN ULONG Type,
+ IN ULONG DataSize,
+ IN PIRP Irp,
+ IN PVOID Buffer,
+ IN ULONG ByteOffset)
+{
+ NTSTATUS Status;
+ PNP_DATA_QUEUE_ENTRY DataEntry;
+ SIZE_T EntrySize;
+ ULONG QuotaInEntry;
+ PSECURITY_CLIENT_CONTEXT ClientContext;
+ BOOLEAN HasSpace;
+
+ ClientContext = NULL;
+ ASSERT((DataQueue->QueueState == Empty) || (DataQueue->QueueState == Who));
+
+ Status = STATUS_SUCCESS;
+
+ if ((Type != 2) && (Who == WriteEntries))
+ {
+ Status = NpGetClientSecurityContext(ServerSide,
+ Ccb,
+ Irp ? Irp->Tail.Overlay.Thread :
+ PsGetCurrentThread(),
+ &ClientContext);
+ if (!NT_SUCCESS(Status)) return Status;
+ }
+
+ switch (Type)
+ {
+ case Unbuffered:
+ case 2:
+ case 3:
+
+ ASSERT(Irp != NULL);
+ DataEntry = ExAllocatePoolWithQuotaTag(NonPagedPool, sizeof(*DataEntry),
'rFpN');
+ if ( DataEntry )
+ {
+ DataEntry->DataEntryType = Type;
+ DataEntry->QuotaInEntry = 0;
+ DataEntry->Irp = Irp;
+ DataEntry->DataSize = DataSize;
+ DataEntry->ClientSecurityContext = ClientContext;
+ ASSERT((DataQueue->QueueState == Empty) || (DataQueue->QueueState
== Who));
+ Status = STATUS_PENDING;
+ break;
+ }
+
+ NpFreeClientSecurityContext(ClientContext);
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ case Buffered:
+
+ EntrySize = sizeof(*DataEntry);
+ if ( Who != Empty)
+ {
+ EntrySize = DataSize + sizeof(*DataEntry);
+ if ((DataSize + sizeof(*DataEntry)) < DataSize )
+ {
+ NpFreeClientSecurityContext(ClientContext);
+ return STATUS_INVALID_PARAMETER;
+ }
+ }
+
+ QuotaInEntry = DataSize - ByteOffset;
+ if ( DataQueue->Quota - DataQueue->QuotaUsed < QuotaInEntry )
+ {
+ QuotaInEntry = DataQueue->Quota - DataQueue->QuotaUsed;
+ HasSpace = 1;
+ }
+ else
+ {
+ HasSpace = 0;
+ }
+
+ DataEntry = ExAllocatePoolWithQuotaTag(NonPagedPool, EntrySize,
'rFpN');
+ if ( !DataEntry )
+ {
+ NpFreeClientSecurityContext(ClientContext);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ DataEntry->QuotaInEntry = QuotaInEntry;
+ DataEntry->Irp = Irp;
+ DataEntry->DataEntryType = Buffered;
+ DataEntry->ClientSecurityContext = ClientContext;
+ DataEntry->DataSize = DataSize;
+
+ if ( Who == ReadEntries)
+ {
+ ASSERT(Irp);
+
+ Status = STATUS_PENDING;
+ ASSERT((DataQueue->QueueState == Empty) ||
+ (DataQueue->QueueState == Who));
+ }
+ else
+ {
+ _SEH2_TRY
+ {
+ RtlCopyMemory(DataEntry + 1,
+ Irp ? Irp->UserBuffer: Buffer,
+ DataSize);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ NpFreeClientSecurityContext(ClientContext);
+ return _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ if ( HasSpace && Irp )
+ {
+ Status = STATUS_PENDING;
+ }
+ else
+ {
+ DataEntry->Irp = 0;
+ Status = STATUS_SUCCESS;
+ }
+
+ ASSERT((DataQueue->QueueState == Empty) || (DataQueue->QueueState
== Who));
+ }
+
+ default:
+ ASSERT(FALSE);
+ NpFreeClientSecurityContext(ClientContext);
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ ASSERT((DataQueue->QueueState == Empty) || (DataQueue->QueueState == Who));
+ if ( DataQueue->QueueState == Empty )
+ {
+ ASSERT(DataQueue->BytesInQueue == 0);
+ ASSERT(DataQueue->EntriesInQueue == 0);
+ ASSERT(IsListEmpty (&DataQueue->Queue));
+ }
+ else
+ {
+ ASSERT(DataQueue->QueueState == Who);
+ ASSERT(DataQueue->QueueState != Empty);
+ ASSERT(DataQueue->EntriesInQueue != 0);
+ }
+
+ DataQueue->QuotaUsed += DataEntry->QuotaInEntry;
+ DataQueue->QueueState = Who;
+ DataQueue->BytesInQueue += DataEntry->DataSize;
+ ++DataQueue->EntriesInQueue;
+ if ( ByteOffset )
+ {
+ DataQueue->ByteOffset = ByteOffset;
+ ASSERT(Who == WriteEntries);
+ ASSERT(ByteOffset < DataEntry->DataSize);
+ ASSERT(DataQueue->EntriesInQueue == 1);
+ }
+
+ InsertTailList(&DataQueue->Queue, &DataEntry->QueueEntry);
+
+ if ( Status == STATUS_PENDING )
+ {
+ IoMarkIrpPending(Irp);
+ Irp->Tail.Overlay.DriverContext[2] = DataQueue;
+ Irp->Tail.Overlay.DriverContext[3] = DataEntry;
+
+ IoSetCancelRoutine(Irp, NpCancelDataQueueIrp);
+
+ if ( Irp->Cancel )
+ {
+ IoSetCancelRoutine(Irp, NULL);
+ NpCancelDataQueueIrp(0, Irp);
+ }
+ }
+
+ return Status;
+}
Modified: trunk/reactos/drivers/filesystems/npfs_new/main.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/npfs_n…
==============================================================================
--- trunk/reactos/drivers/filesystems/npfs_new/main.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/npfs_new/main.c [iso-8859-1] Mon Sep 9 01:16:06
2013
@@ -5,20 +5,6 @@
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;
Modified: trunk/reactos/drivers/filesystems/npfs_new/npfs.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/npfs_n…
==============================================================================
--- trunk/reactos/drivers/filesystems/npfs_new/npfs.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/npfs_new/npfs.h [iso-8859-1] Mon Sep 9 01:16:06
2013
@@ -3,6 +3,7 @@
//
#include <ntifs.h>
#include <ntndk.h>
+#include <pseh/pseh2.h>
#define UNIMPLEMENTED
#define DPRINT1 DbgPrint
@@ -31,15 +32,26 @@
//
typedef enum _NP_DATA_QUEUE_STATE
{
+ ReadEntries = 0,
+ WriteEntries = 1,
Empty = 2
} NP_DATA_QUEUE_STATE;
//
+// Data Queue Entry Types
+//
+typedef enum _NP_DATA_QUEUE_ENTRY_TYPE
+{
+ Buffered = 0,
+ Unbuffered
+} NP_DATA_QUEUE_ENTRY_TYPE;
+
+//
// An Input or Output Data Queue. Each CCB has two of these.
//
typedef struct _NP_DATA_QUEUE
{
- LIST_ENTRY List;
+ LIST_ENTRY Queue;
ULONG QueueState;
ULONG BytesInQueue;
ULONG EntriesInQueue;
@@ -49,6 +61,19 @@
} NP_DATA_QUEUE, *PNP_DATA_QUEUE;
//
+// The Entries that go into the Queue
+//
+typedef struct _NP_DATA_QUEUE_ENTRY
+{
+ LIST_ENTRY QueueEntry;
+ ULONG DataEntryType;
+ PIRP Irp;
+ ULONG QuotaInEntry;
+ PSECURITY_CLIENT_CONTEXT ClientSecurityContext;
+ ULONG DataSize;
+} NP_DATA_QUEUE_ENTRY, *PNP_DATA_QUEUE_ENTRY;
+
+//
// A Wait Queue. Only the VCB has one of these.
//
typedef struct _NP_WAIT_QUEUE
@@ -56,6 +81,14 @@
LIST_ENTRY WaitList;
KSPIN_LOCK WaitLock;
} NP_WAIT_QUEUE, *PNP_WAIT_QUEUE;
+
+//
+// The event buffer in the NonPaged CCB
+//
+typedef struct _NP_EVENT_BUFFER
+{
+ PKEVENT Event;
+} NP_EVENT_BUFFER, *PNP_EVENT_BUFFER;
//
// The CCB for the Root DCB
@@ -76,7 +109,7 @@
LIST_ENTRY DcbEntry;
PVOID ParentDcb;
ULONG CurrentInstances;
- ULONG OtherCount;
+ ULONG ServerOpenCount;
PSECURITY_DESCRIPTOR SecurityDescriptor;
} NP_CB_HEADER, *PNP_CB_HEADER;
@@ -144,8 +177,8 @@
typedef struct _NP_NONPAGED_CCB
{
NODE_TYPE_CODE NodeType;
- PVOID EventBufferClient;
- PVOID EventBufferServer;
+ PNP_EVENT_BUFFER EventBufferClient;
+ PNP_EVENT_BUFFER EventBufferServer;
ERESOURCE Lock;
} NP_NONPAGED_CCB, *PNP_NONPAGED_CCB;
@@ -201,6 +234,34 @@
NTAPI
NpUninitializeDataQueue(IN PNP_DATA_QUEUE DataQueue);
+PNP_DATA_QUEUE_ENTRY
+NTAPI
+NpGetNextRealDataQueueEntry(IN PNP_DATA_QUEUE DataQueue,
+ IN PLIST_ENTRY List);
+
+PIRP
+NTAPI
+NpRemoveDataQueueEntry(IN PNP_DATA_QUEUE DataQueue,
+ IN BOOLEAN Flag,
+ IN PLIST_ENTRY List);
+
+NTSTATUS
+NTAPI
+NpAddDataQueueEntry(IN BOOLEAN ServerSide,
+ IN PNP_CCB Ccb,
+ IN PNP_DATA_QUEUE DataQueue,
+ IN ULONG Who,
+ IN ULONG Type,
+ IN ULONG DataSize,
+ IN PIRP Irp,
+ IN PVOID Buffer,
+ IN ULONG ByteOffset);
+
+VOID
+NTAPI
+NpCompleteStalledWrites(IN PNP_DATA_QUEUE DataQueue,
+ IN PLIST_ENTRY List);
+
NTSTATUS
NTAPI
NpInitializeDataQueue(IN PNP_DATA_QUEUE DataQueue,
@@ -267,6 +328,15 @@
VOID
NTAPI
+NpFreeClientSecurityContext(IN PSECURITY_CLIENT_CONTEXT ClientContext);
+
+VOID
+NTAPI
+NpCopyClientContext(IN PNP_CCB Ccb,
+ IN PNP_DATA_QUEUE_ENTRY DataQueueEntry);
+
+VOID
+NTAPI
NpUninitializeSecurity(IN PNP_CCB Ccb);
NTSTATUS
@@ -274,6 +344,13 @@
NpInitializeSecurity(IN PNP_CCB Ccb,
IN PSECURITY_QUALITY_OF_SERVICE SecurityQos,
IN PETHREAD Thread);
+
+NTSTATUS
+NTAPI
+NpGetClientSecurityContext(IN BOOLEAN ServerSide,
+ IN PNP_CCB Ccb,
+ IN PETHREAD Thread,
+ IN PSECURITY_CLIENT_CONTEXT *Context);
VOID
NTAPI
@@ -316,3 +393,20 @@
IN NTSTATUS Status,
IN PLIST_ENTRY ListEntry);
+
+IO_STATUS_BLOCK
+NTAPI
+NpReadDataQueue(IN PNP_DATA_QUEUE DataQueue,
+ IN BOOLEAN Peek,
+ IN BOOLEAN ReadOverflowOperation,
+ IN PVOID Buffer,
+ IN ULONG BufferSize,
+ IN ULONG Mode,
+ IN PNP_CCB Ccb,
+ IN PLIST_ENTRY List);
+
+NTSTATUS
+NTAPI
+NpFsdRead(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
+
Added: trunk/reactos/drivers/filesystems/npfs_new/read.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/npfs_n…
==============================================================================
--- trunk/reactos/drivers/filesystems/npfs_new/read.c (added)
+++ trunk/reactos/drivers/filesystems/npfs_new/read.c [iso-8859-1] Mon Sep 9 01:16:06
2013
@@ -0,0 +1,189 @@
+#include "npfs.h"
+
+LONG NpSlowReadCalls;
+
+BOOLEAN
+NTAPI
+NpCommonRead(IN PFILE_OBJECT FileObject,
+ IN PVOID Buffer,
+ IN ULONG BufferSize,
+ OUT PIO_STATUS_BLOCK IoStatus,
+ IN PIRP Irp,
+ IN PLIST_ENTRY List)
+{
+ NODE_TYPE_CODE NodeType;
+ ULONG NamedPipeConfiguation;
+ PNP_DATA_QUEUE Queue;
+ PNP_EVENT_BUFFER EventBuffer;
+ NTSTATUS Status;
+ BOOLEAN ServerSide;
+ PNP_CCB Ccb;
+ PNP_NONPAGED_CCB NonPagedCcb;
+ BOOLEAN ReadOk;
+ PAGED_CODE();
+
+ IoStatus->Information = 0;
+ NodeType = NpDecodeFileObject(FileObject, NULL, &Ccb, &ServerSide);
+
+ if (!NodeType)
+ {
+ IoStatus->Status = STATUS_PIPE_DISCONNECTED;
+ return TRUE;
+ }
+
+ if ( NodeType != NPFS_NTC_CCB )
+ {
+ IoStatus->Status = STATUS_INVALID_PARAMETER;
+ return TRUE;
+ }
+
+ NonPagedCcb = Ccb->NonPagedCcb;
+ ExAcquireResourceExclusiveLite(&NonPagedCcb->Lock, TRUE);
+
+ //ms_exc.registration.TryLevel = 0;
+
+ if ( Ccb->NamedPipeState == FILE_PIPE_DISCONNECTED_STATE || Ccb->NamedPipeState
== FILE_PIPE_LISTENING_STATE )
+ {
+ IoStatus->Status = Ccb->NamedPipeState != FILE_PIPE_DISCONNECTED_STATE ?
STATUS_PIPE_LISTENING : STATUS_PIPE_DISCONNECTED;
+ ReadOk = TRUE;
+ goto Quickie;
+ }
+
+ ASSERT((Ccb->NamedPipeState == FILE_PIPE_CONNECTED_STATE) ||
(Ccb->NamedPipeState == FILE_PIPE_CLOSING_STATE));
+
+ NamedPipeConfiguation = Ccb->Fcb->NamedPipeConfiguration;
+
+ if ((ServerSide == 1 && NamedPipeConfiguation == FILE_PIPE_OUTBOUND) ||
+ (ServerSide == 0 && NamedPipeConfiguation == FILE_PIPE_INBOUND) )
+ {
+ IoStatus->Status = STATUS_INVALID_PARAMETER;
+ ReadOk = TRUE;
+ goto Quickie;
+ }
+
+ if ( ServerSide == 1 )
+ {
+ Queue = &Ccb->InQueue;
+ EventBuffer = NonPagedCcb->EventBufferClient;
+ }
+ else
+ {
+ Queue = &Ccb->OutQueue;
+ EventBuffer = NonPagedCcb->EventBufferServer;
+ }
+
+ if ( Queue->QueueState == WriteEntries )
+ {
+ *IoStatus = NpReadDataQueue(Queue,
+ FALSE,
+ FALSE,
+ Buffer,
+ BufferSize,
+ ServerSide ? Ccb->ServerReadMode :
Ccb->ClientReadMode,
+ Ccb,
+ List);
+ if (!NT_SUCCESS(IoStatus->Status))
+ {
+ ReadOk = TRUE;
+ goto Quickie;
+ }
+
+ ReadOk = TRUE;
+ if ( EventBuffer ) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
+ goto Quickie;
+ }
+
+ if ( Ccb->NamedPipeState == FILE_PIPE_CLOSING_STATE )
+ {
+ IoStatus->Status = STATUS_PIPE_BROKEN;
+ ReadOk = TRUE;
+ if ( EventBuffer ) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
+ goto Quickie;
+ }
+
+ if ((ServerSide ? Ccb->ServerCompletionMode : Ccb->ServerCompletionMode) ==
FILE_PIPE_COMPLETE_OPERATION)
+ {
+ IoStatus->Status = STATUS_PIPE_EMPTY;
+ ReadOk = TRUE;
+ if ( EventBuffer ) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
+ goto Quickie;
+ }
+
+ if ( Irp )
+ {
+ Status = NpAddDataQueueEntry(ServerSide,
+ Ccb,
+ Queue,
+ 0,
+ 0,
+ BufferSize,
+ Irp,
+ 0,
+ 0);
+ IoStatus->Status = Status;
+ if (!NT_SUCCESS(Status))
+ {
+ ReadOk = FALSE;
+ goto Quickie;
+ }
+
+ ReadOk = TRUE;
+ if ( EventBuffer ) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
+ goto Quickie;
+ }
+
+ ReadOk = FALSE;
+Quickie:
+ //ms_exc.registration.TryLevel = -1;
+ ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock);
+ return ReadOk;
+}
+
+NTSTATUS
+NTAPI
+NpFsdRead(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ PIO_STACK_LOCATION IoStack;
+ IO_STATUS_BLOCK IoStatus;
+ LIST_ENTRY List;
+ PLIST_ENTRY NextEntry, ThisEntry;
+ PAGED_CODE();
+ NpSlowReadCalls++;
+
+ InitializeListHead(&List);
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+ FsRtlEnterFileSystem();
+ ExAcquireResourceSharedLite(&NpVcb->Lock, TRUE);
+
+ NpCommonRead(IoStack->FileObject,
+ Irp->UserBuffer,
+ IoStack->Parameters.Read.Length,
+ &IoStatus,
+ Irp,
+ &List);
+
+ ExReleaseResourceLite(&NpVcb->Lock);
+
+ NextEntry = List.Flink;
+ while (NextEntry != &List)
+ {
+ ThisEntry = NextEntry;
+ NextEntry = NextEntry->Flink;
+
+ Irp = CONTAINING_RECORD(ThisEntry, IRP, Tail.Overlay.ListEntry);
+ IoCompleteRequest(Irp, IO_DISK_INCREMENT);
+ }
+
+ FsRtlExitFileSystem();
+
+ if ( IoStatus.Status != STATUS_PENDING )
+ {
+ Irp->IoStatus.Information = IoStatus.Information;
+ Irp->IoStatus.Status = IoStatus.Status;
+ IofCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
+ }
+
+ return IoStatus.Status;
+}
Propchange: trunk/reactos/drivers/filesystems/npfs_new/read.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/drivers/filesystems/npfs_new/readsup.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/npfs_n…
==============================================================================
--- trunk/reactos/drivers/filesystems/npfs_new/readsup.c (added)
+++ trunk/reactos/drivers/filesystems/npfs_new/readsup.c [iso-8859-1] Mon Sep 9 01:16:06
2013
@@ -0,0 +1,138 @@
+#include "npfs.h"
+
+IO_STATUS_BLOCK
+NTAPI
+NpReadDataQueue(IN PNP_DATA_QUEUE DataQueue,
+ IN BOOLEAN Peek,
+ IN BOOLEAN ReadOverflowOperation,
+ IN PVOID Buffer,
+ IN ULONG BufferSize,
+ IN ULONG Mode,
+ IN PNP_CCB Ccb,
+ IN PLIST_ENTRY List)
+{
+ PNP_DATA_QUEUE_ENTRY DataEntry, TempDataEntry;
+ PVOID DataBuffer;
+ ULONG DataSize, DataLength, TotalBytesCopied, RemainingSize, Offset;
+ PIRP Irp;
+ IO_STATUS_BLOCK Status;
+ BOOLEAN CompleteWrites = FALSE;
+ PAGED_CODE();
+
+ if ( ReadOverflowOperation ) Peek = TRUE;
+
+ RemainingSize = BufferSize;
+ Status.Status = 0;
+ TotalBytesCopied = 0;
+
+ if ( Peek )
+ {
+ DataEntry = CONTAINING_RECORD(DataQueue->Queue.Flink,
+ NP_DATA_QUEUE_ENTRY,
+ QueueEntry);
+ }
+ else
+ {
+ DataEntry = NpGetNextRealDataQueueEntry(DataQueue, List);
+ }
+
+ while (&DataEntry->QueueEntry != &DataQueue->Queue &&
RemainingSize )
+ {
+ if ( !Peek || (DataEntry->DataEntryType == Buffered ||
DataEntry->DataEntryType == Unbuffered ))
+ {
+ if ( DataEntry->DataEntryType == Unbuffered )
+ {
+ DataBuffer = DataEntry->Irp->AssociatedIrp.SystemBuffer;
+ }
+ else
+ {
+ DataBuffer = &DataEntry[1];
+ }
+ DataSize = DataEntry->DataSize;
+ Offset = DataSize;
+
+ if (&DataEntry->QueueEntry == DataQueue->Queue.Flink)
+ {
+ Offset = DataSize - DataQueue->ByteOffset;
+ }
+
+ DataLength = Offset;
+ if ( Offset >= RemainingSize ) DataLength = RemainingSize;
+
+ _SEH2_TRY
+ {
+ RtlCopyMemory((PVOID)((ULONG_PTR)Buffer + BufferSize - RemainingSize),
+ (PVOID)((ULONG_PTR)DataBuffer + DataSize - Offset),
+ DataLength);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ ASSERT(FALSE);
+ }
+ _SEH2_END;
+
+
+ RemainingSize -= DataLength;
+ Offset -= DataLength;
+ TotalBytesCopied += DataLength;
+ if ( !Peek )
+ {
+ DataEntry->QuotaInEntry -= DataLength;
+ DataQueue->QuotaUsed -= DataLength;
+ DataQueue->ByteOffset += DataLength;
+ CompleteWrites = TRUE;;
+ }
+
+ NpCopyClientContext(Ccb, DataEntry);
+
+ if ( Offset || (ReadOverflowOperation && !TotalBytesCopied ))
+ {
+ if ( Mode == FILE_PIPE_MESSAGE_MODE )
+ {
+ Status.Status = STATUS_BUFFER_OVERFLOW;
+ break;
+ }
+ }
+ else
+ {
+ if ( !Peek || ReadOverflowOperation )
+ {
+ if ( ReadOverflowOperation)
+ {
+ TempDataEntry = NpGetNextRealDataQueueEntry(DataQueue, List);
+ ASSERT(TempDataEntry == DataEntry);
+ }
+
+ Irp = NpRemoveDataQueueEntry(DataQueue, TRUE, List);
+ if ( Irp )
+ {
+ Irp->IoStatus.Information = DataSize;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
+ }
+ }
+ if ( Mode == FILE_PIPE_MESSAGE_MODE )
+ {
+ Status.Status = STATUS_SUCCESS;
+ break;
+ }
+ ASSERT(!ReadOverflowOperation);
+ }
+ }
+ if ( Peek )
+ {
+ DataEntry = CONTAINING_RECORD(DataEntry->QueueEntry.Flink,
+ NP_DATA_QUEUE_ENTRY,
+ QueueEntry);
+ }
+ else
+ {
+ DataEntry = NpGetNextRealDataQueueEntry(DataQueue, List);
+ }
+ }
+
+ Status.Information = TotalBytesCopied;
+ if ( CompleteWrites ) NpCompleteStalledWrites(DataQueue, List);
+ return Status;
+}
+
Propchange: trunk/reactos/drivers/filesystems/npfs_new/readsup.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/drivers/filesystems/npfs_new/secursup.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/npfs_n…
==============================================================================
--- trunk/reactos/drivers/filesystems/npfs_new/secursup.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/npfs_new/secursup.c [iso-8859-1] Mon Sep 9 01:16:06
2013
@@ -1,25 +1,45 @@
#include "npfs.h"
+
+VOID
+NTAPI
+NpFreeClientSecurityContext(IN PSECURITY_CLIENT_CONTEXT ClientContext)
+{
+ TOKEN_TYPE TokenType;
+ PVOID ClientToken;
+
+ if (!ClientContext) return;
+
+ TokenType = SeTokenType(ClientContext->ClientToken);
+ ClientToken = ClientContext->ClientToken;
+ if ((TokenType == TokenPrimary) || (ClientToken))
+ {
+ ObfDereferenceObject(ClientToken);
+ }
+ ExFreePool(ClientContext);
+}
+
+VOID
+NTAPI
+NpCopyClientContext(IN PNP_CCB Ccb,
+ IN PNP_DATA_QUEUE_ENTRY DataQueueEntry)
+{
+ PAGED_CODE();
+
+ if (!DataQueueEntry->ClientSecurityContext) return;
+
+ NpFreeClientSecurityContext(Ccb->ClientContext);
+ Ccb->ClientContext = DataQueueEntry->ClientSecurityContext;
+ DataQueueEntry->ClientSecurityContext = NULL;
+}
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;
+ NpFreeClientSecurityContext(Ccb->ClientContext);
+ Ccb->ClientContext = NULL;
}
NTSTATUS
@@ -63,3 +83,36 @@
Ccb->ClientContext = 0;
return Status;
}
+
+NTSTATUS
+NTAPI
+NpGetClientSecurityContext(IN BOOLEAN ServerSide,
+ IN PNP_CCB Ccb,
+ IN PETHREAD Thread,
+ IN PSECURITY_CLIENT_CONTEXT *Context)
+{
+
+ PSECURITY_CLIENT_CONTEXT NewContext;
+ NTSTATUS Status;
+ PAGED_CODE();
+
+ if ( ServerSide || Ccb->ClientQos.ContextTrackingMode != 1 )
+ {
+ NewContext = NULL;
+ Status = STATUS_SUCCESS;
+ }
+ else
+ {
+ NewContext = ExAllocatePoolWithQuotaTag(PagedPool, sizeof(*NewContext),
'sFpN');
+ if ( !NewContext ) return STATUS_INSUFFICIENT_RESOURCES;
+
+ Status = SeCreateClientSecurity(Thread, &Ccb->ClientQos, 0, NewContext);
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePool(NewContext);
+ NewContext = NULL;
+ }
+ }
+ *Context = NewContext;
+ return Status;
+}