[ros-diffs] [fireball] 26631: - Prepare a playground for a new NPFS driver implementation.

fireball at svn.reactos.org fireball at svn.reactos.org
Fri May 4 12:15:00 CEST 2007


Author: fireball
Date: Fri May  4 14:15:00 2007
New Revision: 26631

URL: http://svn.reactos.org/svn/reactos?rev=26631&view=rev
Log:
- Prepare a playground for a new NPFS driver implementation.

Added:
    trunk/reactos/drivers/filesystems/npfs_new/   (with props)
    trunk/reactos/drivers/filesystems/npfs_new/create.c   (with props)
    trunk/reactos/drivers/filesystems/npfs_new/finfo.c   (with props)
    trunk/reactos/drivers/filesystems/npfs_new/fsctrl.c   (with props)
    trunk/reactos/drivers/filesystems/npfs_new/npfs.c   (with props)
    trunk/reactos/drivers/filesystems/npfs_new/npfs.h   (with props)
    trunk/reactos/drivers/filesystems/npfs_new/npfs.rbuild   (with props)
    trunk/reactos/drivers/filesystems/npfs_new/npfs.rc
    trunk/reactos/drivers/filesystems/npfs_new/rw.c   (with props)
    trunk/reactos/drivers/filesystems/npfs_new/volume.c   (with props)

Propchange: trunk/reactos/drivers/filesystems/npfs_new/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Fri May  4 14:15:00 2007
@@ -1,0 +1,13 @@
+base.tmp
+junk.tmp
+temp.exp
+npfs.coff
+*.d
+*.o
+*.a
+*.sym
+*.sys
+*.map
+GNUmakefile
+*.vcproj
+*.user

Added: trunk/reactos/drivers/filesystems/npfs_new/create.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/npfs_new/create.c?rev=26631&view=auto
==============================================================================
--- trunk/reactos/drivers/filesystems/npfs_new/create.c (added)
+++ trunk/reactos/drivers/filesystems/npfs_new/create.c Fri May  4 14:15:00 2007
@@ -1,0 +1,18 @@
+/*
+ * PROJECT:         ReactOS Drivers
+ * LICENSE:         GPL - See COPYING in the top level directory
+ * FILE:            drivers/filesystems/npfs/create.c
+ * PURPOSE:         Named pipe filesystem
+ * PROGRAMMERS:     
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include "npfs.h"
+
+//#define NDEBUG
+#include <debug.h>
+
+/* FUNCTIONS *****************************************************************/
+
+/* EOF */

Propchange: trunk/reactos/drivers/filesystems/npfs_new/create.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: trunk/reactos/drivers/filesystems/npfs_new/finfo.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/npfs_new/finfo.c?rev=26631&view=auto
==============================================================================
--- trunk/reactos/drivers/filesystems/npfs_new/finfo.c (added)
+++ trunk/reactos/drivers/filesystems/npfs_new/finfo.c Fri May  4 14:15:00 2007
@@ -1,0 +1,18 @@
+/*
+ * PROJECT:         ReactOS Drivers
+ * LICENSE:         GPL - See COPYING in the top level directory
+ * FILE:            drivers/filesystems/npfs/finfo.c
+ * PURPOSE:         Named pipe filesystem
+ * PROGRAMMERS:     
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include "npfs.h"
+
+//#define NDEBUG
+#include <debug.h>
+
+/* FUNCTIONS *****************************************************************/
+
+/* EOF */

Propchange: trunk/reactos/drivers/filesystems/npfs_new/finfo.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: trunk/reactos/drivers/filesystems/npfs_new/fsctrl.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/npfs_new/fsctrl.c?rev=26631&view=auto
==============================================================================
--- trunk/reactos/drivers/filesystems/npfs_new/fsctrl.c (added)
+++ trunk/reactos/drivers/filesystems/npfs_new/fsctrl.c Fri May  4 14:15:00 2007
@@ -1,0 +1,19 @@
+/*
+ * PROJECT:         ReactOS Drivers
+ * LICENSE:         GPL - See COPYING in the top level directory
+ * FILE:            drivers/filesystems/npfs/fsctrl.c
+ * PURPOSE:         Named pipe filesystem
+ * PROGRAMMERS:     
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include "npfs.h"
+
+//#define NDEBUG
+#include <debug.h>
+
+/* FUNCTIONS *****************************************************************/
+
+
+/* EOF */

Propchange: trunk/reactos/drivers/filesystems/npfs_new/fsctrl.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: trunk/reactos/drivers/filesystems/npfs_new/npfs.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/npfs_new/npfs.c?rev=26631&view=auto
==============================================================================
--- trunk/reactos/drivers/filesystems/npfs_new/npfs.c (added)
+++ trunk/reactos/drivers/filesystems/npfs_new/npfs.c Fri May  4 14:15:00 2007
@@ -1,0 +1,89 @@
+/*
+ * PROJECT:         ReactOS Drivers
+ * LICENSE:         GPL - See COPYING in the top level directory
+ * FILE:            drivers/filesystems/npfs/npfs.c
+ * PURPOSE:         Named pipe filesystem
+ * PROGRAMMERS:     
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include "npfs.h"
+
+//#define NDEBUG
+#include <debug.h>
+
+/* FUNCTIONS *****************************************************************/
+
+NTSTATUS STDCALL
+DriverEntry(PDRIVER_OBJECT DriverObject,
+			PUNICODE_STRING RegistryPath)
+{
+	PNPFS_DEVICE_EXTENSION DeviceExtension;
+	PDEVICE_OBJECT DeviceObject;
+	UNICODE_STRING DeviceName;
+	NTSTATUS Status;
+
+	DPRINT("Named Pipe FSD 0.0.2\n");
+
+	ASSERT (sizeof(NPFS_CONTEXT) <= FIELD_OFFSET(IRP, Tail.Overlay.DriverContext));
+	ASSERT (sizeof(NPFS_WAITER_ENTRY) <= FIELD_OFFSET(IRP, Tail.Overlay.DriverContext));
+
+	DriverObject->MajorFunction[IRP_MJ_CREATE] = NpfsCreate;
+	DriverObject->MajorFunction[IRP_MJ_CREATE_NAMED_PIPE] =
+		NpfsCreateNamedPipe;
+	DriverObject->MajorFunction[IRP_MJ_CLOSE] = NpfsClose;
+	DriverObject->MajorFunction[IRP_MJ_READ] = NpfsRead;
+	DriverObject->MajorFunction[IRP_MJ_WRITE] = NpfsWrite;
+	DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] =
+		NpfsQueryInformation;
+	DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] =
+		NpfsSetInformation;
+	DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] =
+		NpfsQueryVolumeInformation;
+	DriverObject->MajorFunction[IRP_MJ_CLEANUP] = NpfsCleanup;
+	DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = NpfsFlushBuffers;
+	//   DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] =
+	//     NpfsDirectoryControl;
+	DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
+		NpfsFileSystemControl;
+	//   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(NPFS_DEVICE_EXTENSION),
+		&DeviceName,
+		FILE_DEVICE_NAMED_PIPE,
+		0,
+		FALSE,
+		&DeviceObject);
+	if (!NT_SUCCESS(Status))
+	{
+		DPRINT("Failed to create named pipe device! (Status %x)\n", Status);
+		return Status;
+	}
+
+	/* initialize the device object */
+	DeviceObject->Flags = DO_DIRECT_IO;
+
+	/* initialize the device extension */
+	DeviceExtension = DeviceObject->DeviceExtension;
+	InitializeListHead(&DeviceExtension->PipeListHead);
+	InitializeListHead(&DeviceExtension->ThreadListHead);
+	KeInitializeMutex(&DeviceExtension->PipeListLock, 0);
+	DeviceExtension->EmptyWaiterCount = 0;
+
+	/* set the size quotas */
+	DeviceExtension->MinQuota = PAGE_SIZE;
+	DeviceExtension->DefaultQuota = 8 * PAGE_SIZE;
+	DeviceExtension->MaxQuota = 64 * PAGE_SIZE;
+
+	return STATUS_SUCCESS;
+}
+
+/* EOF */

Propchange: trunk/reactos/drivers/filesystems/npfs_new/npfs.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: trunk/reactos/drivers/filesystems/npfs_new/npfs.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/npfs_new/npfs.h?rev=26631&view=auto
==============================================================================
--- trunk/reactos/drivers/filesystems/npfs_new/npfs.h (added)
+++ trunk/reactos/drivers/filesystems/npfs_new/npfs.h Fri May  4 14:15:00 2007
@@ -1,0 +1,122 @@
+#ifndef __DRIVERS_FS_NP_NPFS_H
+#define __DRIVERS_FS_NP_NPFS_H
+
+#include <ntifs.h>
+#include <ndk/iotypes.h>
+
+typedef struct _NPFS_DEVICE_EXTENSION
+{
+	LIST_ENTRY PipeListHead;
+	LIST_ENTRY ThreadListHead;
+	KMUTEX PipeListLock;
+	ULONG EmptyWaiterCount;
+	ULONG MinQuota;
+	ULONG DefaultQuota;
+	ULONG MaxQuota;
+} NPFS_DEVICE_EXTENSION, *PNPFS_DEVICE_EXTENSION;
+
+typedef struct _NPFS_FCB
+{
+	FSRTL_COMMON_FCB_HEADER RFCB;
+	UNICODE_STRING PipeName;
+	LIST_ENTRY PipeListEntry;
+	KMUTEX CcbListLock;
+	LIST_ENTRY ServerCcbListHead;
+	LIST_ENTRY ClientCcbListHead;
+	LIST_ENTRY WaiterListHead;
+	LIST_ENTRY EmptyBufferListHead;
+	ULONG PipeType;
+	ULONG ReadMode;
+	ULONG WriteMode;
+	ULONG CompletionMode;
+	ULONG PipeConfiguration;
+	ULONG MaximumInstances;
+	ULONG CurrentInstances;
+	ULONG InboundQuota;
+	ULONG OutboundQuota;
+	LARGE_INTEGER TimeOut;
+} NPFS_FCB, *PNPFS_FCB;
+
+typedef struct _NPFS_CCB
+{
+	LIST_ENTRY CcbListEntry;
+	struct _NPFS_CCB* OtherSide;
+	struct ETHREAD *Thread;
+	PNPFS_FCB Fcb;
+	KEVENT ConnectEvent;
+	KEVENT ReadEvent;
+	KEVENT WriteEvent;
+	ULONG PipeEnd;
+	ULONG PipeState;
+	ULONG ReadDataAvailable;
+	ULONG WriteQuotaAvailable;
+
+	LIST_ENTRY ReadRequestListHead;
+
+	PVOID Data;
+	PVOID ReadPtr;
+	PVOID WritePtr;
+	ULONG MaxDataLength;
+
+	FAST_MUTEX DataListLock;	/* Data queue lock */
+} NPFS_CCB, *PNPFS_CCB;
+
+typedef struct _NPFS_CONTEXT
+{
+	LIST_ENTRY ListEntry;
+	PKEVENT WaitEvent;
+} NPFS_CONTEXT, *PNPFS_CONTEXT;
+
+typedef struct _NPFS_THREAD_CONTEXT
+{
+	ULONG Count;
+	KEVENT Event;
+	PNPFS_DEVICE_EXTENSION DeviceExt;
+	LIST_ENTRY ListEntry;
+	PVOID WaitObjectArray[MAXIMUM_WAIT_OBJECTS];
+	KWAIT_BLOCK WaitBlockArray[MAXIMUM_WAIT_OBJECTS];
+	PIRP WaitIrpArray[MAXIMUM_WAIT_OBJECTS];
+} NPFS_THREAD_CONTEXT, *PNPFS_THREAD_CONTEXT;
+
+typedef struct _NPFS_WAITER_ENTRY
+{
+	LIST_ENTRY Entry;
+	PNPFS_CCB Ccb;
+} NPFS_WAITER_ENTRY, *PNPFS_WAITER_ENTRY;
+
+
+extern NPAGED_LOOKASIDE_LIST NpfsPipeDataLookasideList;
+
+
+#define KeLockMutex(x) KeWaitForSingleObject(x, \
+	UserRequest, \
+	KernelMode, \
+	FALSE, \
+	NULL);
+
+#define KeUnlockMutex(x) KeReleaseMutex(x, FALSE);
+
+#define PAGE_ROUND_UP(x) ( (((ULONG_PTR)x)%PAGE_SIZE) ? ((((ULONG_PTR)x)&(~(PAGE_SIZE-1)))+PAGE_SIZE) : ((ULONG_PTR)x) )
+
+NTSTATUS STDCALL NpfsCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp);
+NTSTATUS STDCALL NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject, PIRP Irp);
+NTSTATUS STDCALL NpfsCleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp);
+NTSTATUS STDCALL NpfsClose(PDEVICE_OBJECT DeviceObject, PIRP Irp);
+
+NTSTATUS STDCALL NpfsRead(PDEVICE_OBJECT DeviceObject, PIRP Irp);
+NTSTATUS STDCALL NpfsWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp);
+
+NTSTATUS STDCALL NpfsFlushBuffers(PDEVICE_OBJECT DeviceObject, PIRP Irp);
+
+NTSTATUS STDCALL NpfsFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
+
+NTSTATUS STDCALL NpfsQueryInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp);
+NTSTATUS STDCALL NpfsSetInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp);
+
+NTSTATUS STDCALL NpfsQueryVolumeInformation (PDEVICE_OBJECT DeviceObject, PIRP Irp);
+
+NTSTATUS STDCALL
+DriverEntry(PDRIVER_OBJECT DriverObject,
+			PUNICODE_STRING RegistryPath);
+
+#endif /* __DRIVERS_FS_NP_NPFS_H */

Propchange: trunk/reactos/drivers/filesystems/npfs_new/npfs.h
------------------------------------------------------------------------------
    svn:eol-style = native

Added: trunk/reactos/drivers/filesystems/npfs_new/npfs.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/npfs_new/npfs.rbuild?rev=26631&view=auto
==============================================================================
--- trunk/reactos/drivers/filesystems/npfs_new/npfs.rbuild (added)
+++ trunk/reactos/drivers/filesystems/npfs_new/npfs.rbuild Fri May  4 14:15:00 2007
@@ -1,0 +1,15 @@
+<module name="npfs" type="kernelmodedriver" installbase="system32/drivers" installname="npfs.sys">
+	<include base="npfs">.</include>
+	<define name="__USE_W32API" />
+	<define name="__NO_CTYPE_INLINES" />
+	<library>ntoskrnl</library>
+	<library>hal</library>
+	<file>create.c</file>
+	<file>finfo.c</file>
+	<file>fsctrl.c</file>
+	<file>npfs.c</file>
+	<file>rw.c</file>
+	<file>volume.c</file>
+	<file>npfs.rc</file>
+	<pch>npfs.h</pch>
+</module>

Propchange: trunk/reactos/drivers/filesystems/npfs_new/npfs.rbuild
------------------------------------------------------------------------------
    svn:eol-style = native

Added: trunk/reactos/drivers/filesystems/npfs_new/npfs.rc
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/npfs_new/npfs.rc?rev=26631&view=auto
==============================================================================
--- trunk/reactos/drivers/filesystems/npfs_new/npfs.rc (added)
+++ trunk/reactos/drivers/filesystems/npfs_new/npfs.rc Fri May  4 14:15:00 2007
@@ -1,0 +1,5 @@
+#define REACTOS_VERSION_DLL
+#define REACTOS_STR_FILE_DESCRIPTION	"Named Pipe IFS Driver\0"
+#define REACTOS_STR_INTERNAL_NAME	"npfs\0"
+#define REACTOS_STR_ORIGINAL_FILENAME	"npfs.sys\0"
+#include <reactos/version.rc>

Added: trunk/reactos/drivers/filesystems/npfs_new/rw.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/npfs_new/rw.c?rev=26631&view=auto
==============================================================================
--- trunk/reactos/drivers/filesystems/npfs_new/rw.c (added)
+++ trunk/reactos/drivers/filesystems/npfs_new/rw.c Fri May  4 14:15:00 2007
@@ -1,0 +1,779 @@
+/*
+ * PROJECT:         ReactOS Drivers
+ * LICENSE:         GPL - See COPYING in the top level directory
+ * FILE:            drivers/filesystems/npfs/rw.c
+ * PURPOSE:         Named pipe filesystem
+ * PROGRAMMERS:     
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include "npfs.h"
+
+//#define NDEBUG
+#include <debug.h>
+
+/* FUNCTIONS *****************************************************************/
+
+#ifndef NDEBUG
+VOID HexDump(PUCHAR Buffer, ULONG Length)
+{
+	CHAR Line[65];
+	UCHAR ch;
+	const char Hex[] = "0123456789ABCDEF";
+	int i, j;
+
+	DbgPrint("---------------\n");
+
+	for (i = 0; i < Length; i+= 16)
+	{
+		memset(Line, ' ', 64);
+		Line[64] = 0;
+
+		for (j = 0; j < 16 && j + i < Length; j++)
+		{
+			ch = Buffer[i + j];
+			Line[3*j + 0] = Hex[ch >> 4];
+			Line[3*j + 1] = Hex[ch & 0x0f];
+			Line[48 + j] = isprint(ch) ? ch : '.';
+		}
+		DbgPrint("%s\n", Line);
+	}
+	DbgPrint("---------------\n");
+}
+#endif
+
+static VOID STDCALL
+NpfsReadWriteCancelRoutine(IN PDEVICE_OBJECT DeviceObject,
+						   IN PIRP Irp)
+{
+	PNPFS_CONTEXT Context;
+	PNPFS_DEVICE_EXTENSION DeviceExt;
+	PIO_STACK_LOCATION IoStack;
+	PNPFS_CCB Ccb;
+	BOOLEAN Complete = FALSE;
+
+	DPRINT("NpfsReadWriteCancelRoutine(DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
+
+	IoReleaseCancelSpinLock(Irp->CancelIrql);
+
+	Context = (PNPFS_CONTEXT)&Irp->Tail.Overlay.DriverContext;
+	DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+	IoStack = IoGetCurrentIrpStackLocation(Irp);
+	Ccb = IoStack->FileObject->FsContext2;
+
+	KeLockMutex(&DeviceExt->PipeListLock);
+	ExAcquireFastMutex(&Ccb->DataListLock);
+	switch(IoStack->MajorFunction)
+	{
+	case IRP_MJ_READ:
+		if (Ccb->ReadRequestListHead.Flink != &Context->ListEntry)
+		{
+			/* we are not the first in the list, remove an complete us */
+			RemoveEntryList(&Context->ListEntry);
+			Complete = TRUE;
+		}
+		else
+		{
+			KeSetEvent(&Ccb->ReadEvent, IO_NO_INCREMENT, FALSE);
+		}
+		break;
+	default:
+		KEBUGCHECK(0);
+	}
+	ExReleaseFastMutex(&Ccb->DataListLock);
+	KeUnlockMutex(&DeviceExt->PipeListLock);
+	if (Complete)
+	{
+		Irp->IoStatus.Status = STATUS_CANCELLED;
+		Irp->IoStatus.Information = 0;
+		IoCompleteRequest(Irp, IO_NO_INCREMENT);
+	}
+}
+
+static VOID STDCALL
+NpfsWaiterThread(PVOID InitContext)
+{
+	PNPFS_THREAD_CONTEXT ThreadContext = (PNPFS_THREAD_CONTEXT) InitContext;
+	ULONG CurrentCount;
+	ULONG Count = 0;
+	PIRP Irp = NULL;
+	PIRP NextIrp;
+	NTSTATUS Status;
+	BOOLEAN Terminate = FALSE;
+	BOOLEAN Cancel = FALSE;
+	PIO_STACK_LOCATION IoStack = NULL;
+	PNPFS_CONTEXT Context;
+	PNPFS_CONTEXT NextContext;
+	PNPFS_CCB Ccb;
+
+	KeLockMutex(&ThreadContext->DeviceExt->PipeListLock);
+
+	while (1)
+	{
+		CurrentCount = ThreadContext->Count;
+		KeUnlockMutex(&ThreadContext->DeviceExt->PipeListLock);
+		if (Irp)
+		{
+			if (Cancel)
+			{
+				Irp->IoStatus.Status = STATUS_CANCELLED;
+				Irp->IoStatus.Information = 0;
+				IoCompleteRequest(Irp, IO_NO_INCREMENT);
+			}
+			else
+			{
+				switch (IoStack->MajorFunction)
+				{
+				case IRP_MJ_READ:
+					NpfsRead(IoStack->DeviceObject, Irp);
+					break;
+				default:
+					KEBUGCHECK(0);
+				}
+			}
+		}
+		if (Terminate)
+		{
+			break;
+		}
+		Status = KeWaitForMultipleObjects(CurrentCount,
+			ThreadContext->WaitObjectArray,
+			WaitAny,
+			Executive,
+			KernelMode,
+			FALSE,
+			NULL,
+			ThreadContext->WaitBlockArray);
+		if (!NT_SUCCESS(Status))
+		{
+			KEBUGCHECK(0);
+		}
+		KeLockMutex(&ThreadContext->DeviceExt->PipeListLock);
+		Count = Status - STATUS_SUCCESS;
+		ASSERT (Count < CurrentCount);
+		if (Count > 0)
+		{
+			Irp = ThreadContext->WaitIrpArray[Count];
+			ThreadContext->Count--;
+			ThreadContext->DeviceExt->EmptyWaiterCount++;
+			ThreadContext->WaitObjectArray[Count] = ThreadContext->WaitObjectArray[ThreadContext->Count];
+			ThreadContext->WaitIrpArray[Count] = ThreadContext->WaitIrpArray[ThreadContext->Count];
+
+			Cancel = (NULL == IoSetCancelRoutine(Irp, NULL));
+			Context = (PNPFS_CONTEXT)&Irp->Tail.Overlay.DriverContext;
+			IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+			if (Cancel)
+			{
+				Ccb = IoStack->FileObject->FsContext2;
+				ExAcquireFastMutex(&Ccb->DataListLock);
+				RemoveEntryList(&Context->ListEntry);
+				switch (IoStack->MajorFunction)
+				{
+				case IRP_MJ_READ:
+					if (!IsListEmpty(&Ccb->ReadRequestListHead))
+					{
+						/* put the next request on the wait list */
+						NextContext = CONTAINING_RECORD(Ccb->ReadRequestListHead.Flink, NPFS_CONTEXT, ListEntry);
+						ThreadContext->WaitObjectArray[ThreadContext->Count] = NextContext->WaitEvent;
+						NextIrp = CONTAINING_RECORD(NextContext, IRP, Tail.Overlay.DriverContext);
+						ThreadContext->WaitIrpArray[ThreadContext->Count] = NextIrp;
+						ThreadContext->Count++;
+						ThreadContext->DeviceExt->EmptyWaiterCount--;
+					}
+					break;
+				default:
+					KEBUGCHECK(0);
+				}
+				ExReleaseFastMutex(&Ccb->DataListLock);
+			}
+		}
+		else
+		{
+			/* someone has add a new wait request */
+			Irp = NULL;
+		}
+		if (ThreadContext->Count == 1 && ThreadContext->DeviceExt->EmptyWaiterCount >= MAXIMUM_WAIT_OBJECTS)
+		{
+			/* it exist an other thread with empty wait slots, we can remove our thread from the list */
+			RemoveEntryList(&ThreadContext->ListEntry);
+			ThreadContext->DeviceExt->EmptyWaiterCount -= MAXIMUM_WAIT_OBJECTS - 1;
+			Terminate = TRUE;
+		}
+	}
+	ExFreePool(ThreadContext);
+}
+
+static NTSTATUS
+NpfsAddWaitingReadWriteRequest(IN PDEVICE_OBJECT DeviceObject,
+							   IN PIRP Irp)
+{
+	PLIST_ENTRY ListEntry;
+	PNPFS_THREAD_CONTEXT ThreadContext = NULL;
+	NTSTATUS Status;
+	HANDLE hThread;
+	KIRQL oldIrql;
+
+	PNPFS_CONTEXT Context = (PNPFS_CONTEXT)&Irp->Tail.Overlay.DriverContext;
+	PNPFS_DEVICE_EXTENSION DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+	DPRINT("NpfsAddWaitingReadWriteRequest(DeviceObject %p, Irp %p)\n", DeviceObject, Irp);
+
+	KeLockMutex(&DeviceExt->PipeListLock);
+
+	ListEntry = DeviceExt->ThreadListHead.Flink;
+	while (ListEntry != &DeviceExt->ThreadListHead)
+	{
+		ThreadContext = CONTAINING_RECORD(ListEntry, NPFS_THREAD_CONTEXT, ListEntry);
+		if (ThreadContext->Count < MAXIMUM_WAIT_OBJECTS)
+		{
+			break;
+		}
+		ListEntry = ListEntry->Flink;
+	}
+	if (ListEntry == &DeviceExt->ThreadListHead)
+	{
+		ThreadContext = ExAllocatePool(NonPagedPool, sizeof(NPFS_THREAD_CONTEXT));
+		if (ThreadContext == NULL)
+		{
+			KeUnlockMutex(&DeviceExt->PipeListLock);
+			return STATUS_NO_MEMORY;
+		}
+		ThreadContext->DeviceExt = DeviceExt;
+		KeInitializeEvent(&ThreadContext->Event, SynchronizationEvent, FALSE);
+		ThreadContext->Count = 1;
+		ThreadContext->WaitObjectArray[0] = &ThreadContext->Event;
+
+
+		DPRINT("Creating a new system thread for waiting read/write requests\n");
+
+		Status = PsCreateSystemThread(&hThread,
+			THREAD_ALL_ACCESS,
+			NULL,
+			NULL,
+			NULL,
+			NpfsWaiterThread,
+			(PVOID)ThreadContext);
+		if (!NT_SUCCESS(Status))
+		{
+			ExFreePool(ThreadContext);
+			KeUnlockMutex(&DeviceExt->PipeListLock);
+			return Status;
+		}
+		InsertHeadList(&DeviceExt->ThreadListHead, &ThreadContext->ListEntry);
+		DeviceExt->EmptyWaiterCount += MAXIMUM_WAIT_OBJECTS - 1;
+	}
+	IoMarkIrpPending(Irp);
+
+	IoAcquireCancelSpinLock(&oldIrql);
+	if (Irp->Cancel)
+	{
+		IoReleaseCancelSpinLock(oldIrql);
+		Status = STATUS_CANCELLED;
+	}
+	else
+	{
+		(void)IoSetCancelRoutine(Irp, NpfsReadWriteCancelRoutine);
+		IoReleaseCancelSpinLock(oldIrql);
+		ThreadContext->WaitObjectArray[ThreadContext->Count] = Context->WaitEvent;
+		ThreadContext->WaitIrpArray[ThreadContext->Count] = Irp;
+		ThreadContext->Count++;
+		DeviceExt->EmptyWaiterCount--;
+		KeSetEvent(&ThreadContext->Event, IO_NO_INCREMENT, FALSE);
+		Status = STATUS_SUCCESS;
+	}
+	KeUnlockMutex(&DeviceExt->PipeListLock);
+	return Status;
+}
+
+NTSTATUS STDCALL
+NpfsRead(IN PDEVICE_OBJECT DeviceObject,
+		 IN PIRP Irp)
+{
+	PFILE_OBJECT FileObject;
+	NTSTATUS Status;
+	NTSTATUS OriginalStatus = STATUS_SUCCESS;
+	PNPFS_CCB Ccb;
+	PNPFS_CONTEXT Context;
+	KEVENT Event;
+	ULONG Length;
+	ULONG Information = 0;
+	ULONG CopyLength;
+	ULONG TempLength;
+	BOOLEAN IsOriginalRequest = TRUE;
+	PVOID Buffer;
+
+	DPRINT("NpfsRead(DeviceObject %p, Irp %p)\n", DeviceObject, Irp);
+
+	if (Irp->MdlAddress == NULL)
+	{
+		DPRINT("Irp->MdlAddress == NULL\n");
+		Status = STATUS_UNSUCCESSFUL;
+		Irp->IoStatus.Information = 0;
+		goto done;
+	}
+
+	FileObject = IoGetCurrentIrpStackLocation(Irp)->FileObject;
+	Ccb = FileObject->FsContext2;
+	Context = (PNPFS_CONTEXT)&Irp->Tail.Overlay.DriverContext;
+
+	if (Ccb->OtherSide == NULL)
+	{
+		DPRINT("Pipe is NOT connected!\n");
+		if (Ccb->PipeState == FILE_PIPE_LISTENING_STATE)
+			Status = STATUS_PIPE_LISTENING;
+		else if (Ccb->PipeState == FILE_PIPE_DISCONNECTED_STATE)
+			Status = STATUS_PIPE_DISCONNECTED;
+		else
+			Status = STATUS_UNSUCCESSFUL;
+		Irp->IoStatus.Information = 0;
+		goto done;
+	}
+
+	if (Ccb->Data == NULL)
+	{
+		DPRINT1("Pipe is NOT readable!\n");
+		Status = STATUS_UNSUCCESSFUL;
+		Irp->IoStatus.Information = 0;
+		goto done;
+	}
+
+	ExAcquireFastMutex(&Ccb->DataListLock);
+
+	if (IoIsOperationSynchronous(Irp))
+	{
+		InsertTailList(&Ccb->ReadRequestListHead, &Context->ListEntry);
+		if (Ccb->ReadRequestListHead.Flink != &Context->ListEntry)
+		{
+			KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
+			Context->WaitEvent = &Event;
+			ExReleaseFastMutex(&Ccb->DataListLock);
+			Status = KeWaitForSingleObject(&Event,
+				Executive,
+				KernelMode,
+				FALSE,
+				NULL);
+			if (!NT_SUCCESS(Status))
+			{
+				KEBUGCHECK(0);
+			}
+			ExAcquireFastMutex(&Ccb->DataListLock);
+		}
+		Irp->IoStatus.Information = 0;
+	}
+	else
+	{
+		KIRQL oldIrql;
+		if (IsListEmpty(&Ccb->ReadRequestListHead) ||
+			Ccb->ReadRequestListHead.Flink != &Context->ListEntry)
+		{
+			/* this is a new request */
+			Irp->IoStatus.Information = 0;
+			Context->WaitEvent = &Ccb->ReadEvent;
+			InsertTailList(&Ccb->ReadRequestListHead, &Context->ListEntry);
+			if (Ccb->ReadRequestListHead.Flink != &Context->ListEntry)
+			{
+				/* there was already a request on the list */
+				IoAcquireCancelSpinLock(&oldIrql);
+				if (Irp->Cancel)
+				{
+					IoReleaseCancelSpinLock(oldIrql);
+					RemoveEntryList(&Context->ListEntry);
+					ExReleaseFastMutex(&Ccb->DataListLock);
+					Status = STATUS_CANCELLED;
+					goto done;
+				}
+				(void)IoSetCancelRoutine(Irp, NpfsReadWriteCancelRoutine);
+				IoReleaseCancelSpinLock(oldIrql);
+				ExReleaseFastMutex(&Ccb->DataListLock);
+				IoMarkIrpPending(Irp);
+				Status = STATUS_PENDING;
+				goto done;
+			}
+		}
+	}
+
+	while (1)
+	{
+		Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
+		Information = Irp->IoStatus.Information;
+		Length = IoGetCurrentIrpStackLocation(Irp)->Parameters.Read.Length;
+		ASSERT (Information <= Length);
+		Buffer = (PVOID)((ULONG_PTR)Buffer + Information);
+		Length -= Information;
+		Status = STATUS_SUCCESS;
+
+		while (1)
+		{
+			if (Ccb->ReadDataAvailable == 0)
+			{
+				if (Ccb->PipeState == FILE_PIPE_CONNECTED_STATE)
+				{
+					ASSERT(Ccb->OtherSide != NULL);
+					KeSetEvent(&Ccb->OtherSide->WriteEvent, IO_NO_INCREMENT, FALSE);
+				}
+				if (Information > 0 &&
+					(Ccb->Fcb->ReadMode != FILE_PIPE_BYTE_STREAM_MODE ||
+					Ccb->PipeState != FILE_PIPE_CONNECTED_STATE))
+				{
+					break;
+				}
+				if (Ccb->PipeState != FILE_PIPE_CONNECTED_STATE)
+				{
+					DPRINT("PipeState: %x\n", Ccb->PipeState);
+					Status = STATUS_PIPE_BROKEN;
+					break;
+				}
+				ExReleaseFastMutex(&Ccb->DataListLock);
+				if (IoIsOperationSynchronous(Irp))
+				{
+					/* Wait for ReadEvent to become signaled */
+
+					DPRINT("Waiting for readable data (%wZ)\n", &Ccb->Fcb->PipeName);
+					Status = KeWaitForSingleObject(&Ccb->ReadEvent,
+						UserRequest,
+						KernelMode,
+						FALSE,
+						NULL);
+					DPRINT("Finished waiting (%wZ)! Status: %x\n", &Ccb->Fcb->PipeName, Status);
+					ExAcquireFastMutex(&Ccb->DataListLock);
+				}
+				else
+				{
+					Context = (PNPFS_CONTEXT)&Irp->Tail.Overlay.DriverContext;
+
+					Context->WaitEvent = &Ccb->ReadEvent;
+					Status = NpfsAddWaitingReadWriteRequest(DeviceObject, Irp);
+
+					if (NT_SUCCESS(Status))
+					{
+						Status = STATUS_PENDING;
+					}
+					ExAcquireFastMutex(&Ccb->DataListLock);
+					break;
+				}
+			}
+			ASSERT(IoGetCurrentIrpStackLocation(Irp)->FileObject != NULL);
+			if (Ccb->Fcb->ReadMode == FILE_PIPE_BYTE_STREAM_MODE)
+			{
+				DPRINT("Byte stream mode\n");
+				/* Byte stream mode */
+				while (Length > 0 && Ccb->ReadDataAvailable > 0)
+				{
+					CopyLength = min(Ccb->ReadDataAvailable, Length);
+					if ((ULONG_PTR)Ccb->ReadPtr + CopyLength <= (ULONG_PTR)Ccb->Data + Ccb->MaxDataLength)
+					{
+						memcpy(Buffer, Ccb->ReadPtr, CopyLength);
+						Ccb->ReadPtr = (PVOID)((ULONG_PTR)Ccb->ReadPtr + CopyLength);
+						if (Ccb->ReadPtr == (PVOID)((ULONG_PTR)Ccb->Data + Ccb->MaxDataLength))
+						{
+							Ccb->ReadPtr = Ccb->Data;
+						}
+					}
+					else
+					{
+						TempLength = (ULONG)((ULONG_PTR)Ccb->Data + Ccb->MaxDataLength - (ULONG_PTR)Ccb->ReadPtr);
+						memcpy(Buffer, Ccb->ReadPtr, TempLength);
+						memcpy((PVOID)((ULONG_PTR)Buffer + TempLength), Ccb->Data, CopyLength - TempLength);
+						Ccb->ReadPtr = (PVOID)((ULONG_PTR)Ccb->Data + CopyLength - TempLength);
+					}
+
+					Buffer = (PVOID)((ULONG_PTR)Buffer + CopyLength);
+					Length -= CopyLength;
+					Information += CopyLength;
+
+					Ccb->ReadDataAvailable -= CopyLength;
+					Ccb->WriteQuotaAvailable += CopyLength;
+				}
+
+				if (Length == 0)
+				{
+					if (Ccb->PipeState == FILE_PIPE_CONNECTED_STATE)
+					{
+						KeSetEvent(&Ccb->OtherSide->WriteEvent, IO_NO_INCREMENT, FALSE);
+					}
+					KeResetEvent(&Ccb->ReadEvent);
+					break;
+				}
+			}
+			else
+			{
+				DPRINT("Message mode\n");
+
+				/* Message mode */
+				if (Ccb->ReadDataAvailable)
+				{
+					/* Truncate the message if the receive buffer is too small */
+					CopyLength = min(Ccb->ReadDataAvailable, Length);
+					memcpy(Buffer, Ccb->Data, CopyLength);
+
+#ifndef NDEBUG
+					DPRINT("Length %d Buffer %x\n",CopyLength,Buffer);
+					HexDump((PUCHAR)Buffer, CopyLength);
+#endif
+
+					Information = CopyLength;
+
+					if (Ccb->ReadDataAvailable > Length)
+					{
+						memmove(Ccb->Data, (PVOID)((ULONG_PTR)Ccb->Data + Length),
+							Ccb->ReadDataAvailable - Length);
+						Ccb->ReadDataAvailable -= Length;
+						Status = STATUS_MORE_ENTRIES;
+					}
+					else
+					{
+						KeResetEvent(&Ccb->ReadEvent);
+						if (Ccb->PipeState == FILE_PIPE_CONNECTED_STATE)
+						{
+							KeSetEvent(&Ccb->OtherSide->WriteEvent, IO_NO_INCREMENT, FALSE);
+						}
+						Ccb->ReadDataAvailable = 0;
+						Ccb->WriteQuotaAvailable = Ccb->MaxDataLength;
+					}
+				}
+
+				if (Information > 0)
+				{
+					break;
+				}
+			}
+		}
+		Irp->IoStatus.Information = Information;
+		Irp->IoStatus.Status = Status;
+
+		ASSERT(IoGetCurrentIrpStackLocation(Irp)->FileObject != NULL);
+
+		if (IoIsOperationSynchronous(Irp))
+		{
+			RemoveEntryList(&Context->ListEntry);
+			if (!IsListEmpty(&Ccb->ReadRequestListHead))
+			{
+				Context = CONTAINING_RECORD(Ccb->ReadRequestListHead.Flink, NPFS_CONTEXT, ListEntry);
+				KeSetEvent(Context->WaitEvent, IO_NO_INCREMENT, FALSE);
+			}
+			ExReleaseFastMutex(&Ccb->DataListLock);
+			IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+			DPRINT("NpfsRead done (Status %lx)\n", Status);
+			return Status;
+		}
+		else
+		{
+			if (IsOriginalRequest)
+			{
+				IsOriginalRequest = FALSE;
+				OriginalStatus = Status;
+			}
+			if (Status == STATUS_PENDING)
+			{
+				ExReleaseFastMutex(&Ccb->DataListLock);
+				DPRINT("NpfsRead done (Status %lx)\n", OriginalStatus);
+				return OriginalStatus;
+			}
+			RemoveEntryList(&Context->ListEntry);
+			IoCompleteRequest(Irp, IO_NO_INCREMENT);
+			if (IsListEmpty(&Ccb->ReadRequestListHead))
+			{
+				ExReleaseFastMutex(&Ccb->DataListLock);
+				DPRINT("NpfsRead done (Status %lx)\n", OriginalStatus);
+				return OriginalStatus;
+			}
+			Context = CONTAINING_RECORD(Ccb->ReadRequestListHead.Flink, NPFS_CONTEXT, ListEntry);
+			Irp = CONTAINING_RECORD(Context, IRP, Tail.Overlay.DriverContext);
+		}
+	}
+
+done:
+	Irp->IoStatus.Status = Status;
+
+	if (Status != STATUS_PENDING)
+	{
+		IoCompleteRequest(Irp, IO_NO_INCREMENT);
+	}
+	DPRINT("NpfsRead done (Status %lx)\n", Status);
+
+	return Status;
+}
+
+NTSTATUS STDCALL
+NpfsWrite(PDEVICE_OBJECT DeviceObject,
+		  PIRP Irp)
+{
+	PIO_STACK_LOCATION IoStack;
+	PFILE_OBJECT FileObject;
+	PNPFS_FCB Fcb = NULL;
+	PNPFS_CCB Ccb = NULL;
+	PNPFS_CCB ReaderCcb;
+	PUCHAR Buffer;
+	NTSTATUS Status = STATUS_SUCCESS;
+	ULONG Length;
+	ULONG Offset;
+	ULONG Information;
+	ULONG CopyLength;
+	ULONG TempLength;
+
+	DPRINT("NpfsWrite()\n");
+
+	IoStack = IoGetCurrentIrpStackLocation(Irp);
+	FileObject = IoStack->FileObject;
+	DPRINT("FileObject %p\n", FileObject);
+	DPRINT("Pipe name %wZ\n", &FileObject->FileName);
+
+	Ccb = FileObject->FsContext2;
+	ReaderCcb = Ccb->OtherSide;
+	Fcb = Ccb->Fcb;
+
+	Length = IoStack->Parameters.Write.Length;
+	Offset = IoStack->Parameters.Write.ByteOffset.u.LowPart;
+	Information = 0;
+
+	if (Irp->MdlAddress == NULL)
+	{
+		DPRINT("Irp->MdlAddress == NULL\n");
+		Status = STATUS_UNSUCCESSFUL;
+		Length = 0;
+		goto done;
+	}
+
+	if (ReaderCcb == NULL)
+	{
+		DPRINT("Pipe is NOT connected!\n");
+		if (Ccb->PipeState == FILE_PIPE_LISTENING_STATE)
+			Status = STATUS_PIPE_LISTENING;
+		else if (Ccb->PipeState == FILE_PIPE_DISCONNECTED_STATE)
+			Status = STATUS_PIPE_DISCONNECTED;
+		else
+			Status = STATUS_UNSUCCESSFUL;
+		Length = 0;
+		goto done;
+	}
+
+	if (ReaderCcb->Data == NULL)
+	{
+		DPRINT("Pipe is NOT writable!\n");
+		Status = STATUS_UNSUCCESSFUL;
+		Length = 0;
+		goto done;
+	}
+
+	Status = STATUS_SUCCESS;
+	Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress);
+
+	ExAcquireFastMutex(&ReaderCcb->DataListLock);
+#ifndef NDEBUG
+	DPRINT("Length %d Buffer %x Offset %x\n",Length,Buffer,Offset);
+	HexDump(Buffer, Length);
+#endif
+
+	while(1)
+	{
+		if (ReaderCcb->WriteQuotaAvailable == 0)
+		{
+			KeSetEvent(&ReaderCcb->ReadEvent, IO_NO_INCREMENT, FALSE);
+			if (Ccb->PipeState != FILE_PIPE_CONNECTED_STATE)
+			{
+				Status = STATUS_PIPE_BROKEN;
+				ExReleaseFastMutex(&ReaderCcb->DataListLock);
+				goto done;
+			}
+			ExReleaseFastMutex(&ReaderCcb->DataListLock);
+
+			DPRINT("Waiting for buffer space (%S)\n", Fcb->PipeName.Buffer);
+			Status = KeWaitForSingleObject(&Ccb->WriteEvent,
+				UserRequest,
+				KernelMode,
+				FALSE,
+				NULL);
+			DPRINT("Finished waiting (%S)! Status: %x\n", Fcb->PipeName.Buffer, Status);
+
+			/*
+			* It's possible that the event was signaled because the
+			* other side of pipe was closed.
+			*/
+			if (Ccb->PipeState != FILE_PIPE_CONNECTED_STATE)
+			{
+				DPRINT("PipeState: %x\n", Ccb->PipeState);
+				Status = STATUS_PIPE_BROKEN;
+				// ExReleaseFastMutex(&ReaderCcb->DataListLock);
+				goto done;
+			}
+
+			ExAcquireFastMutex(&ReaderCcb->DataListLock);
+		}
+
+		if (Fcb->WriteMode == FILE_PIPE_BYTE_STREAM_MODE)
+		{
+			DPRINT("Byte stream mode\n");
+			while (Length > 0 && ReaderCcb->WriteQuotaAvailable > 0)
+			{
+				CopyLength = min(Length, ReaderCcb->WriteQuotaAvailable);
+				if ((ULONG_PTR)ReaderCcb->WritePtr + CopyLength <= (ULONG_PTR)ReaderCcb->Data + ReaderCcb->MaxDataLength)
+				{
+					memcpy(ReaderCcb->WritePtr, Buffer, CopyLength);
+					ReaderCcb->WritePtr = (PVOID)((ULONG_PTR)ReaderCcb->WritePtr + CopyLength);
+					if ((ULONG_PTR)ReaderCcb->WritePtr == (ULONG_PTR)ReaderCcb->Data + ReaderCcb->MaxDataLength)
+					{
+						ReaderCcb->WritePtr = ReaderCcb->Data;
+					}
+				}
+				else
+				{
+					TempLength = (ULONG)((ULONG_PTR)ReaderCcb->Data + ReaderCcb->MaxDataLength - (ULONG_PTR)ReaderCcb->WritePtr);
+					memcpy(ReaderCcb->WritePtr, Buffer, TempLength);
+					memcpy(ReaderCcb->Data, Buffer + TempLength, CopyLength - TempLength);
+					ReaderCcb->WritePtr = (PVOID)((ULONG_PTR)ReaderCcb->Data + CopyLength - TempLength);
+				}
+
+				Buffer += CopyLength;
+				Length -= CopyLength;
+				Information += CopyLength;
+
+				ReaderCcb->ReadDataAvailable += CopyLength;
+				ReaderCcb->WriteQuotaAvailable -= CopyLength;
+			}
+
+			if (Length == 0)
+			{
+				KeSetEvent(&ReaderCcb->ReadEvent, IO_NO_INCREMENT, FALSE);
+				KeResetEvent(&Ccb->WriteEvent);
+				break;
+			}
+		}
+		else
+		{
+			DPRINT("Message mode\n");
+			if (Length > 0)
+			{
+				CopyLength = min(Length, ReaderCcb->WriteQuotaAvailable);
+				memcpy(ReaderCcb->Data, Buffer, CopyLength);
+
+				Information = CopyLength;
+				ReaderCcb->ReadDataAvailable = CopyLength;
+				ReaderCcb->WriteQuotaAvailable = 0;
+			}
+
+			if (Information > 0)
+			{
+				KeSetEvent(&ReaderCcb->ReadEvent, IO_NO_INCREMENT, FALSE);
+				KeResetEvent(&Ccb->WriteEvent);
+				break;
+			}
+		}
+	}
+
+	ExReleaseFastMutex(&ReaderCcb->DataListLock);
+
+done:
+	Irp->IoStatus.Status = Status;
+	Irp->IoStatus.Information = Information;
+
+	IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+	DPRINT("NpfsWrite done (Status %lx)\n", Status);
+
+	return Status;
+}
+
+/* EOF */

Propchange: trunk/reactos/drivers/filesystems/npfs_new/rw.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: trunk/reactos/drivers/filesystems/npfs_new/volume.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/npfs_new/volume.c?rev=26631&view=auto
==============================================================================
--- trunk/reactos/drivers/filesystems/npfs_new/volume.c (added)
+++ trunk/reactos/drivers/filesystems/npfs_new/volume.c Fri May  4 14:15:00 2007
@@ -1,0 +1,19 @@
+/*
+ * PROJECT:         ReactOS Drivers
+ * LICENSE:         GPL - See COPYING in the top level directory
+ * FILE:            drivers/filesystems/npfs/volume.c
+ * PURPOSE:         Named pipe filesystem
+ * PROGRAMMERS:     
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include "npfs.h"
+
+//#define NDEBUG
+#include <debug.h>
+
+/* FUNCTIONS ****************************************************************/
+
+
+/* EOF */

Propchange: trunk/reactos/drivers/filesystems/npfs_new/volume.c
------------------------------------------------------------------------------
    svn:eol-style = native




More information about the Ros-diffs mailing list