[NPFS/NPFS_NEW]

* Make npfs_new the one and only npfs. One of the few foo_new modules that actually made it and I hope it won't be the last ;)
CORE-7451

svn path=/trunk/; revision=60611
This commit is contained in:
Amine Khaldi 2013-10-11 15:19:46 +00:00
parent 9f4686524d
commit 429a1c4b23
27 changed files with 1938 additions and 4004 deletions

View file

@ -6,5 +6,5 @@ add_subdirectory(fastfat)
add_subdirectory(fs_rec) add_subdirectory(fs_rec)
add_subdirectory(msfs) add_subdirectory(msfs)
add_subdirectory(mup) add_subdirectory(mup)
add_subdirectory(npfs_new) add_subdirectory(npfs)
add_subdirectory(ntfs) add_subdirectory(ntfs)

View file

@ -1,19 +1,29 @@
list(APPEND SOURCE list(APPEND SOURCE
cleanup.c
close.c
create.c create.c
dirctl.c datasup.c
finfo.c fileinfo.c
fileobsup.c
flushbuf.c
fsctrl.c fsctrl.c
npfs.c main.c
rw.c prefxsup.c
volume.c read.c
npfs.rc) readsup.c
secursup.c
seinfo.c
statesup.c
strucsup.c
volinfo.c
waitsup.c
write.c
writesup.c)
add_library(npfs SHARED ${SOURCE}) add_library(npfs SHARED ${SOURCE})
target_link_libraries(npfs ${PSEH_LIB})
set_module_type(npfs kernelmodedriver) set_module_type(npfs kernelmodedriver)
target_link_libraries(npfs ${PSEH_LIB})
add_importlibs(npfs ntoskrnl hal) add_importlibs(npfs ntoskrnl hal)
add_pch(npfs npfs.h) add_pch(npfs npfs.h)
add_cd_file(TARGET npfs DESTINATION reactos/system32/drivers FOR all) add_cd_file(TARGET npfs DESTINATION reactos/system32/drivers FOR all)

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,208 +1,675 @@
#ifndef __DRIVERS_FS_NP_NPFS_H /*
#define __DRIVERS_FS_NP_NPFS_H * PROJECT: ReactOS Named Pipe FileSystem
* LICENSE: BSD - See COPYING.ARM in the top level directory
* FILE: drivers/filesystems/npfs/npfs.h
* PURPOSE: Named Pipe FileSystem Header
* PROGRAMMERS: ReactOS Portable Systems Group
*/
/* INCLUDES *******************************************************************/
//
// System Headers
//
#include <ntifs.h> #include <ntifs.h>
#include <ndk/iotypes.h> #include <ntndk.h>
#include <pseh/pseh2.h> #include <pseh/pseh2.h>
#define UNIMPLEMENTED
#define DPRINT1 DbgPrint
#define TAG_NPFS_CCB 'cFpN' //
#define TAG_NPFS_CCB_DATA 'iFpN' /* correct? */ // Allow Microsoft Extensions
#define TAG_NPFS_FCB 'FFpN' //
#define TAG_NPFS_NAMEBLOCK 'nFpN' #ifdef _MSC_VER
#define TAG_NPFS_THREAD_CONTEXT 'tFpN' #pragma warning(disable:4201)
#pragma warning(disable:4214)
#pragma warning(disable:4100)
#endif
#define ROUND_DOWN(n, align) \
(((ULONG)n) & ~((align) - 1l))
#define ROUND_UP(n, align) \ /* TYPEDEFS & DEFINES *********************************************************/
ROUND_DOWN(((ULONG)n) + (align) - 1, (align))
typedef enum _FCB_TYPE //
// Pool Tags for NPFS (from pooltag.txt)
//
// Npf* -npfs.sys - Npfs Allocations
// NpFc - npfs.sys - CCB, client control block
// NpFf - npfs.sys - FCB, file control block
// NpFC - npfs.sys - ROOT_DCB CCB
// NpFD - npfs.sys - DCB, directory block
// NpFg - npfs.sys - Global storage
// NpFi - npfs.sys - NPFS client info buffer.
// NpFn - npfs.sys - Name block
// NpFq - npfs.sys - Query template buffer used for directory query
// NpFr - npfs.sys - DATA_ENTRY records(read / write buffers)
// NpFs - npfs.sys - Client security context
// NpFw - npfs.sys - Write block
// NpFW - npfs.sys - Write block
#define NPFS_CCB_TAG 'NpFc'
#define NPFS_ROOT_DCB_CCB_TAG 'NpFC'
#define NPFS_DCB_TAG 'NpFD'
#define NPFS_FCB_TAG 'NpFf'
#define NPFS_GLOBAL_TAG 'NpFg'
#define NPFS_CLIENT_INFO_TAG 'NpFi'
#define NPFS_NAME_BLOCK_TAG 'NpFn'
#define NPFS_QUERY_TEMPLATE_TAG 'NpFq'
#define NPFS_DATA_ENTRY_TAG 'NpFr'
#define NPFS_CLIENT_SEC_CTX_TAG 'NpFs'
#define NPFS_WAIT_BLOCK_TAG 'NpFt'
#define NPFS_WRITE_BLOCK_TAG 'NpFw'
//
// NPFS bugchecking support
//
// We define the NpBugCheck macro which triggers a NPFS_FILE_SYSTEM bugcheck
// containing the source file ID number and the line where it was emitted, as
// described in the MSDN article "Bug Check 0x25: NPFS_FILE_SYSTEM".
//
// The bugcheck emits 4 ULONGs; the first one is made, in its high word, by
// the current source file ID and in its low word, by the line number; the
// three other ones are user-defined.
//
// In order to avoid redefinition of the same file ID in different source files,
// we gather all of them here, so that you will have to add (or remove) a new
// one as soon as you add (or remove) a source file from the NPFS driver code.
//
// To use the NpBugCheck macro in a source file, define at its beginning
// the constant NPFS_BUGCHECK_FILE_ID with one of the following file IDs,
// then use the bugcheck macro wherever you want.
//
#define NPFS_BUGCHECK_CLEANUP 0x0001
#define NPFS_BUGCHECK_CLOSE 0x0002
#define NPFS_BUGCHECK_CREATE 0x0003
#define NPFS_BUGCHECK_DATASUP 0x0004
#define NPFS_BUGCHECK_FILEINFO 0x0005
#define NPFS_BUGCHECK_FILEOBSUP 0x0006
#define NPFS_BUGCHECK_FLUSHBUF 0x0007
#define NPFS_BUGCHECK_FSCTRL 0x0008
#define NPFS_BUGCHECK_MAIN 0x0009
#define NPFS_BUGCHECK_PREFXSUP 0x000a
#define NPFS_BUGCHECK_READ 0x000b
#define NPFS_BUGCHECK_READSUP 0x000c
#define NPFS_BUGCHECK_SECURSUP 0x000d
#define NPFS_BUGCHECK_SEINFO 0x000e
#define NPFS_BUGCHECK_STATESUP 0x000f
#define NPFS_BUGCHECK_STRUCSUP 0x0010
#define NPFS_BUGCHECK_VOLINFO 0x0011
#define NPFS_BUGCHECK_WAITSUP 0x0012
#define NPFS_BUGCHECK_WRITE 0x0013
#define NPFS_BUGCHECK_WRITESUP 0x0014
#define NpBugCheck(p1, p2, p3) \
KeBugCheckEx(NPFS_FILE_SYSTEM, \
(NPFS_BUGCHECK_FILE_ID << 16) | __LINE__, \
(p1), (p2), (p3))
//
// Node Type Codes for NPFS
//
#define NPFS_NTC_VCB 1
#define NPFS_NTC_ROOT_DCB 2
#define NPFS_NTC_FCB 4
#define NPFS_NTC_CCB 6
#define NPFS_NTC_NONPAGED_CCB 7
#define NPFS_NTC_ROOT_DCB_CCB 8
typedef USHORT NODE_TYPE_CODE, *PNODE_TYPE_CODE;
//
// Data Queue States
//
typedef enum _NP_DATA_QUEUE_STATE
{ {
FCB_INVALID, ReadEntries = 0,
FCB_DEVICE, WriteEntries = 1,
FCB_DIRECTORY, Empty = 2
FCB_PIPE } NP_DATA_QUEUE_STATE;
} FCB_TYPE;
typedef enum _CCB_TYPE //
// Data Queue Entry Types
//
typedef enum _NP_DATA_QUEUE_ENTRY_TYPE
{ {
CCB_INVALID, Buffered = 0,
CCB_DEVICE, Unbuffered
CCB_DIRECTORY, } NP_DATA_QUEUE_ENTRY_TYPE;
CCB_PIPE
} CCB_TYPE;
/* Volume Control Block (VCB) aka Device Extension */ //
typedef struct _NPFS_VCB // An Input or Output Data Queue. Each CCB has two of these.
//
typedef struct _NP_DATA_QUEUE
{ {
LIST_ENTRY PipeListHead; LIST_ENTRY Queue;
LIST_ENTRY ThreadListHead; ULONG QueueState;
KMUTEX PipeListLock; ULONG BytesInQueue;
ULONG EmptyWaiterCount; ULONG EntriesInQueue;
ULONG MinQuota; ULONG QuotaUsed;
ULONG DefaultQuota; ULONG ByteOffset;
ULONG MaxQuota; ULONG Quota;
struct _NPFS_FCB *DeviceFcb; } NP_DATA_QUEUE, *PNP_DATA_QUEUE;
struct _NPFS_FCB *RootFcb;
} NPFS_VCB, *PNPFS_VCB;
typedef struct _NPFS_FCB //
// The Entries that go into the Queue
//
typedef struct _NP_DATA_QUEUE_ENTRY
{ {
FCB_TYPE Type; LIST_ENTRY QueueEntry;
PNPFS_VCB Vcb; ULONG DataEntryType;
volatile LONG RefCount; PIRP Irp;
UNICODE_STRING PipeName; ULONG QuotaInEntry;
LIST_ENTRY PipeListEntry; PSECURITY_CLIENT_CONTEXT ClientSecurityContext;
KMUTEX CcbListLock; ULONG DataSize;
LIST_ENTRY ServerCcbListHead; } NP_DATA_QUEUE_ENTRY, *PNP_DATA_QUEUE_ENTRY;
LIST_ENTRY ClientCcbListHead;
LIST_ENTRY WaiterListHead;
LIST_ENTRY EmptyBufferListHead;
ULONG PipeType;
ULONG ClientReadMode;
ULONG ServerReadMode;
ULONG CompletionMode;
ULONG PipeConfiguration;
ULONG MaximumInstances;
ULONG CurrentInstances;
ULONG InboundQuota;
ULONG OutboundQuota;
LARGE_INTEGER TimeOut;
} NPFS_FCB, *PNPFS_FCB;
//
typedef struct _NPFS_CCB_DIRECTORY_DATA // A Wait Queue. Only the VCB has one of these.
//
typedef struct _NP_WAIT_QUEUE
{ {
UNICODE_STRING SearchPattern; LIST_ENTRY WaitList;
ULONG FileIndex; KSPIN_LOCK WaitLock;
} NPFS_CCB_DIRECTORY_DATA, *PNPFS_CCB_DIRECTORY_DATA; } NP_WAIT_QUEUE, *PNP_WAIT_QUEUE;
//
typedef struct _NPFS_CCB // The Entries in the Queue above, one for each Waiter.
//
typedef struct _NP_WAIT_QUEUE_ENTRY
{ {
LIST_ENTRY CcbListEntry; PIRP Irp;
CCB_TYPE Type; KDPC Dpc;
PNPFS_FCB Fcb; KTIMER Timer;
PNP_WAIT_QUEUE WaitQueue;
UNICODE_STRING AliasName;
PFILE_OBJECT FileObject; PFILE_OBJECT FileObject;
} NP_WAIT_QUEUE_ENTRY, *PNP_WAIT_QUEUE_ENTRY;
struct _NPFS_CCB* OtherSide; //
struct ETHREAD *Thread; // The event buffer in the NonPaged CCB
KEVENT ConnectEvent; //
KEVENT ReadEvent; typedef struct _NP_EVENT_BUFFER
KEVENT WriteEvent; {
ULONG PipeEnd; PKEVENT Event;
ULONG PipeState; } NP_EVENT_BUFFER, *PNP_EVENT_BUFFER;
ULONG ReadDataAvailable;
ULONG WriteQuotaAvailable;
volatile LONG RefCount;
LIST_ENTRY ReadRequestListHead; //
// The CCB for the Root DCB
//
typedef struct _NP_ROOT_DCB_CCB
{
NODE_TYPE_CODE NodeType;
PVOID Unknown;
ULONG Unknown2;
} NP_ROOT_DCB_CCB, *PNP_ROOT_DCB_FCB;
PVOID Data; //
PVOID ReadPtr; // The header that both FCB and DCB share
PVOID WritePtr; //
ULONG MaxDataLength; typedef struct _NP_CB_HEADER
{
NODE_TYPE_CODE NodeType;
LIST_ENTRY DcbEntry;
PVOID ParentDcb;
ULONG CurrentInstances;
ULONG ServerOpenCount;
PSECURITY_DESCRIPTOR SecurityDescriptor;
} NP_CB_HEADER, *PNP_CB_HEADER;
FAST_MUTEX DataListLock; /* Data queue lock */ //
// The footer that both FCB and DCB share
//
typedef struct _NP_CB_FOOTER
{
UNICODE_STRING FullName;
UNICODE_STRING ShortName;
UNICODE_PREFIX_TABLE_ENTRY PrefixTableEntry;
} NP_CB_FOOTER;
union //
// A Directory Control Block (DCB)
//
typedef struct _NP_DCB
{
//
// Common Header
//
NP_CB_HEADER;
//
// DCB-specific data
//
LIST_ENTRY NotifyList;
LIST_ENTRY NotifyList2;
LIST_ENTRY FcbList;
#ifndef _WIN64
ULONG Pad;
#endif
//
// Common Footer
//
NP_CB_FOOTER;
} NP_DCB, *PNP_DCB;
//
// A File Control BLock (FCB)
//
typedef struct _NP_FCB
{
//
// Common Header
//
NP_CB_HEADER;
//
// FCB-specific fields
//
ULONG MaximumInstances;
USHORT NamedPipeConfiguration;
USHORT NamedPipeType;
LARGE_INTEGER Timeout;
LIST_ENTRY CcbList;
#ifdef _WIN64
PVOID Pad[2];
#endif
//
// Common Footer
//
NP_CB_FOOTER;
} NP_FCB, *PNP_FCB;
C_ASSERT(FIELD_OFFSET(NP_FCB, PrefixTableEntry) == FIELD_OFFSET(NP_DCB, PrefixTableEntry));
//
// The nonpaged portion of the CCB
//
typedef struct _NP_NONPAGED_CCB
{
NODE_TYPE_CODE NodeType;
PNP_EVENT_BUFFER EventBuffer[2];
ERESOURCE Lock;
} NP_NONPAGED_CCB, *PNP_NONPAGED_CCB;
//
// A Client Control Block (CCB)
//
typedef struct _NP_CCB
{
NODE_TYPE_CODE NodeType;
UCHAR NamedPipeState;
UCHAR ReadMode[2];
UCHAR CompletionMode[2];
SECURITY_QUALITY_OF_SERVICE ClientQos;
LIST_ENTRY CcbEntry;
PNP_FCB Fcb;
PFILE_OBJECT FileObject[2];
PEPROCESS Process;
PVOID ClientSession;
PNP_NONPAGED_CCB NonPagedCcb;
NP_DATA_QUEUE DataQueue[2];
PSECURITY_CLIENT_CONTEXT ClientContext;
LIST_ENTRY IrpList;
} NP_CCB, *PNP_CCB;
//
// A Volume Control Block (VCB)
//
typedef struct _NP_VCB
{
NODE_TYPE_CODE NodeType;
ULONG ReferenceCount;
PNP_DCB RootDcb;
UNICODE_PREFIX_TABLE PrefixTable;
ERESOURCE Lock;
RTL_GENERIC_TABLE EventTable;
NP_WAIT_QUEUE WaitQueue;
} NP_VCB, *PNP_VCB;
extern PNP_VCB NpVcb;
/* FUNCTIONS ******************************************************************/
//
// Functions to lock/unlock the global VCB lock
//
FORCEINLINE
VOID
NpAcquireSharedVcb(VOID)
{
/* Acquire the lock in shared mode */
ExAcquireResourceSharedLite(&NpVcb->Lock, TRUE);
}
FORCEINLINE
VOID
NpAcquireExclusiveVcb(VOID)
{
/* Acquire the lock in exclusive mode */
ExAcquireResourceExclusiveLite(&NpVcb->Lock, TRUE);
}
FORCEINLINE
VOID
NpReleaseVcb(VOID)
{
/* Release the lock */
ExReleaseResourceLite(&NpVcb->Lock);
}
//
// Function to process deferred IRPs outside the VCB lock but still within the
// critical region
//
VOID
FORCEINLINE
NpCompleteDeferredIrps(IN PLIST_ENTRY DeferredList)
{
PLIST_ENTRY ThisEntry, NextEntry;
PIRP Irp;
/* Loop the list */
ThisEntry = DeferredList->Flink;
while (ThisEntry != DeferredList)
{ {
NPFS_CCB_DIRECTORY_DATA Directory; /* Remember the next entry, but don't switch to it yet */
} u; NextEntry = ThisEntry->Flink;
} NPFS_CCB, *PNPFS_CCB; /* Complete the IRP for this entry */
Irp = CONTAINING_RECORD(ThisEntry, IRP, Tail.Overlay.ListEntry);
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
typedef struct _NPFS_CONTEXT /* And now switch to the next one */
{ ThisEntry = NextEntry;
LIST_ENTRY ListEntry; }
PKEVENT WaitEvent; }
} NPFS_CONTEXT, *PNPFS_CONTEXT;
typedef struct _NPFS_THREAD_CONTEXT BOOLEAN
{ NTAPI
ULONG Count; NpDeleteEventTableEntry(IN PRTL_GENERIC_TABLE Table,
KEVENT Event; IN PVOID Buffer);
PNPFS_VCB Vcb;
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) )
DRIVER_DISPATCH NpfsCreate;
NTSTATUS NTAPI NpfsCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp);
DRIVER_DISPATCH NpfsCreateNamedPipe;
NTSTATUS NTAPI NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject, PIRP Irp);
DRIVER_DISPATCH NpfsCleanup;
NTSTATUS NTAPI NpfsCleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp);
DRIVER_DISPATCH NpfsClose;
NTSTATUS NTAPI NpfsClose(PDEVICE_OBJECT DeviceObject, PIRP Irp);
DRIVER_DISPATCH NpfsDirectoryControl;
NTSTATUS NTAPI NpfsDirectoryControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
DRIVER_DISPATCH NpfsRead;
NTSTATUS NTAPI NpfsRead(PDEVICE_OBJECT DeviceObject, PIRP Irp);
DRIVER_DISPATCH NpfsWrite;
NTSTATUS NTAPI NpfsWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp);
DRIVER_DISPATCH NpfsFlushBuffers;
NTSTATUS NTAPI NpfsFlushBuffers(PDEVICE_OBJECT DeviceObject, PIRP Irp);
DRIVER_DISPATCH NpfsFileSystemControl;
NTSTATUS NTAPI NpfsFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
DRIVER_DISPATCH NpfsQueryInformation;
NTSTATUS NTAPI NpfsQueryInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp);
DRIVER_DISPATCH NpfsSetInformation;
NTSTATUS NTAPI NpfsSetInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp);
DRIVER_DISPATCH NpfsQueryVolumeInformation;
NTSTATUS NTAPI NpfsQueryVolumeInformation (PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS NTAPI
DriverEntry(PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath);
VOID VOID
NpfsDereferenceFcb(PNPFS_FCB Fcb); NTAPI
NpInitializeWaitQueue(IN PNP_WAIT_QUEUE WaitQueue);
PNPFS_FCB
NpfsFindPipe(PNPFS_VCB Vcb,
PUNICODE_STRING PipeName);
FCB_TYPE NTSTATUS
NpfsGetFcb(PFILE_OBJECT FileObject, NTAPI
PNPFS_FCB *Fcb); NpUninitializeDataQueue(IN PNP_DATA_QUEUE DataQueue);
CCB_TYPE PLIST_ENTRY
NpfsGetCcb(PFILE_OBJECT FileObject, NTAPI
PNPFS_CCB *Ccb); NpGetNextRealDataQueueEntry(IN PNP_DATA_QUEUE DataQueue,
IN PLIST_ENTRY List);
#endif /* __DRIVERS_FS_NP_NPFS_H */ PIRP
NTAPI
NpRemoveDataQueueEntry(IN PNP_DATA_QUEUE DataQueue,
IN BOOLEAN Flag,
IN PLIST_ENTRY List);
NTSTATUS
NTAPI
NpAddDataQueueEntry(IN ULONG NamedPipeEnd,
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,
IN ULONG Quota);
NTSTATUS
NTAPI
NpCreateCcb(IN PNP_FCB Fcb,
IN PFILE_OBJECT FileObject,
IN UCHAR State,
IN UCHAR ReadMode,
IN UCHAR CompletionMode,
IN ULONG InQuota,
IN ULONG OutQuota,
OUT PNP_CCB *NewCcb);
NTSTATUS
NTAPI
NpCreateFcb(IN PNP_DCB Dcb,
IN PUNICODE_STRING PipeName,
IN ULONG MaximumInstances,
IN LARGE_INTEGER Timeout,
IN USHORT NamedPipeConfiguration,
IN USHORT NamedPipeType,
OUT PNP_FCB *NewFcb);
NTSTATUS
NTAPI
NpCreateRootDcb(VOID);
NTSTATUS
NTAPI
NpCreateRootDcbCcb(IN PNP_ROOT_DCB_FCB *NewRootCcb);
VOID
NTAPI
NpInitializeVcb(VOID);
VOID
NTAPI
NpDeleteCcb(IN PNP_CCB Ccb,
IN PLIST_ENTRY ListEntry);
VOID
NTAPI
NpDeleteFcb(IN PNP_FCB Fcb,
IN PLIST_ENTRY ListEntry);
NTSTATUS
NTAPI
NpFsdCreateNamedPipe(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
NTSTATUS
NTAPI
NpFsdCreate(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
NTSTATUS
NTAPI
NpFsdClose(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
NTSTATUS
NTAPI
NpFsdCleanup(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
NTSTATUS
NTAPI
NpFsdFileSystemControl(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
NTSTATUS
NTAPI
NpSetConnectedPipeState(IN PNP_CCB Ccb,
IN PFILE_OBJECT FileObject,
IN PLIST_ENTRY List);
NTSTATUS
NTAPI
NpSetListeningPipeState(IN PNP_CCB Ccb,
IN PIRP Irp,
IN PLIST_ENTRY List);
NTSTATUS
NTAPI
NpSetDisconnectedPipeState(IN PNP_CCB Ccb,
IN PLIST_ENTRY List);
NTSTATUS
NTAPI
NpSetClosingPipeState(IN PNP_CCB Ccb,
IN PIRP Irp,
IN ULONG NamedPipeEnd,
IN PLIST_ENTRY List);
VOID
NTAPI
NpFreeClientSecurityContext(IN PSECURITY_CLIENT_CONTEXT ClientContext);
NTSTATUS
NTAPI
NpImpersonateClientContext(IN PNP_CCB Ccb);
VOID
NTAPI
NpCopyClientContext(IN PNP_CCB Ccb,
IN PNP_DATA_QUEUE_ENTRY DataQueueEntry);
VOID
NTAPI
NpUninitializeSecurity(IN PNP_CCB Ccb);
NTSTATUS
NTAPI
NpInitializeSecurity(IN PNP_CCB Ccb,
IN PSECURITY_QUALITY_OF_SERVICE SecurityQos,
IN PETHREAD Thread);
NTSTATUS
NTAPI
NpGetClientSecurityContext(IN ULONG NamedPipeEnd,
IN PNP_CCB Ccb,
IN PETHREAD Thread,
IN PSECURITY_CLIENT_CONTEXT *Context);
VOID
NTAPI
NpSetFileObject(IN PFILE_OBJECT FileObject,
IN PVOID PrimaryContext,
IN PVOID Ccb,
IN ULONG NamedPipeEnd);
NODE_TYPE_CODE
NTAPI
NpDecodeFileObject(IN PFILE_OBJECT FileObject,
OUT PVOID *PrimaryContext OPTIONAL,
OUT PNP_CCB *Ccb,
OUT PULONG NamedPipeEnd OPTIONAL);
PNP_FCB
NTAPI
NpFindPrefix(IN PUNICODE_STRING Name,
IN ULONG CaseInsensitiveIndex,
IN PUNICODE_STRING Prefix);
NTSTATUS
NTAPI
NpFindRelativePrefix(IN PNP_DCB Dcb,
IN PUNICODE_STRING Name,
IN ULONG CaseInsensitiveIndex,
IN PUNICODE_STRING Prefix,
OUT PNP_FCB *FoundFcb);
VOID
NTAPI
NpCheckForNotify(IN PNP_DCB Dcb,
IN BOOLEAN SecondList,
IN PLIST_ENTRY List);
NTSTATUS
NTAPI
NpAddWaiter(IN PNP_WAIT_QUEUE WaitQueue,
IN LARGE_INTEGER WaitTime,
IN PIRP Irp,
IN PUNICODE_STRING AliasName);
NTSTATUS
NTAPI
NpCancelWaiter(IN PNP_WAIT_QUEUE WaitQueue,
IN PUNICODE_STRING PipeName,
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
NpWriteDataQueue(IN PNP_DATA_QUEUE WriteQueue,
IN ULONG Mode,
IN PVOID OutBuffer,
IN ULONG OutBufferSize,
IN ULONG PipeType,
OUT PULONG BytesWritten,
IN PNP_CCB Ccb,
IN ULONG NamedPipeEnd,
IN PETHREAD Thread,
IN PLIST_ENTRY List);
NTSTATUS
NTAPI
NpFsdRead(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
NTSTATUS
NTAPI
NpFsdWrite(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
NTSTATUS
NTAPI
NpFsdFlushBuffers(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
NTSTATUS
NTAPI
NpFsdSetInformation(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
NTSTATUS
NTAPI
NpFsdQueryInformation(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
NTSTATUS
NTAPI
NpFsdQuerySecurityInfo(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
NTSTATUS
NTAPI
NpFsdSetSecurityInfo(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
NTSTATUS
NTAPI
NpFsdQueryVolumeInformation(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
/* EOF */

View file

@ -1,29 +0,0 @@
list(APPEND SOURCE
cleanup.c
close.c
create.c
datasup.c
fileinfo.c
fileobsup.c
flushbuf.c
fsctrl.c
main.c
prefxsup.c
read.c
readsup.c
secursup.c
seinfo.c
statesup.c
strucsup.c
volinfo.c
waitsup.c
write.c
writesup.c)
add_library(npfs SHARED ${SOURCE})
set_module_type(npfs kernelmodedriver)
target_link_libraries(npfs ${PSEH_LIB})
add_importlibs(npfs ntoskrnl hal)
add_pch(npfs npfs.h)
add_cd_file(TARGET npfs DESTINATION reactos/system32/drivers FOR all)

View file

@ -1,746 +0,0 @@
/*
* PROJECT: ReactOS Named Pipe FileSystem
* LICENSE: BSD - See COPYING.ARM in the top level directory
* FILE: drivers/filesystems/npfs/create.c
* PURPOSE: Pipes Creation
* PROGRAMMERS: ReactOS Portable Systems Group
*/
/* INCLUDES *******************************************************************/
#include "npfs.h"
// File ID number for NPFS bugchecking support
#define NPFS_BUGCHECK_FILE_ID (NPFS_BUGCHECK_CREATE)
/* FUNCTIONS ******************************************************************/
VOID
NTAPI
NpCheckForNotify(IN PNP_DCB Dcb,
IN BOOLEAN SecondList,
IN PLIST_ENTRY List)
{
PLIST_ENTRY NextEntry, ListHead;
PIRP Irp;
ULONG i;
PAGED_CODE();
ListHead = &Dcb->NotifyList;
for (i = 0; i < 2; i++)
{
ASSERT(IsListEmpty(ListHead));
while (!IsListEmpty(ListHead))
{
NextEntry = RemoveHeadList(ListHead);
Irp = CONTAINING_RECORD(NextEntry, IRP, Tail.Overlay.ListEntry);
if (IoSetCancelRoutine(Irp, NULL))
{
Irp->IoStatus.Status = STATUS_SUCCESS;
InsertTailList(List, NextEntry);
}
else
{
InitializeListHead(NextEntry);
}
}
if (!SecondList) break;
ListHead = &Dcb->NotifyList2;
}
}
IO_STATUS_BLOCK
NTAPI
NpOpenNamedPipeFileSystem(IN PFILE_OBJECT FileObject,
IN ACCESS_MASK DesiredAccess)
{
IO_STATUS_BLOCK Status;
PAGED_CODE();
NpSetFileObject(FileObject, NpVcb, NULL, FALSE);
++NpVcb->ReferenceCount;
Status.Information = FILE_OPENED;
Status.Status = STATUS_SUCCESS;
return Status;
}
IO_STATUS_BLOCK
NTAPI
NpOpenNamedPipeRootDirectory(IN PNP_DCB Dcb,
IN PFILE_OBJECT FileObject,
IN ACCESS_MASK DesiredAccess,
IN PLIST_ENTRY List)
{
IO_STATUS_BLOCK IoStatus;
PNP_ROOT_DCB_FCB Ccb;
PAGED_CODE();
IoStatus.Status = NpCreateRootDcbCcb(&Ccb);
if (NT_SUCCESS(IoStatus.Status))
{
NpSetFileObject(FileObject, Dcb, Ccb, FALSE);
++Dcb->CurrentInstances;
IoStatus.Information = FILE_OPENED;
IoStatus.Status = STATUS_SUCCESS;
}
else
{
IoStatus.Information = 0;
}
return IoStatus;
}
IO_STATUS_BLOCK
NTAPI
NpCreateClientEnd(IN PNP_FCB Fcb,
IN PFILE_OBJECT FileObject,
IN ACCESS_MASK DesiredAccess,
IN PSECURITY_QUALITY_OF_SERVICE SecurityQos,
IN PACCESS_STATE AccessState,
IN KPROCESSOR_MODE PreviousMode,
IN PETHREAD Thread,
IN PLIST_ENTRY List)
{
PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext;
BOOLEAN AccessGranted;
ACCESS_MASK GrantedAccess;
PPRIVILEGE_SET Privileges;
UNICODE_STRING ObjectTypeName;
IO_STATUS_BLOCK IoStatus;
USHORT NamedPipeConfiguration;
PLIST_ENTRY NextEntry, ListHead;
PNP_CCB Ccb = NULL;
IoStatus.Status = STATUS_SUCCESS;
IoStatus.Information = 0;
Privileges = NULL;
NamedPipeConfiguration = Fcb->NamedPipeConfiguration;
SubjectSecurityContext = &AccessState->SubjectSecurityContext;
SeLockSubjectContext(SubjectSecurityContext);
AccessGranted = SeAccessCheck(Fcb->SecurityDescriptor,
SubjectSecurityContext,
TRUE,
DesiredAccess & ~4,
0,
&Privileges,
IoGetFileObjectGenericMapping(),
PreviousMode,
&GrantedAccess,
&IoStatus.Status);
if (Privileges)
{
SeAppendPrivileges(AccessState, Privileges);
SeFreePrivileges(Privileges);
}
if (AccessGranted)
{
AccessState->PreviouslyGrantedAccess |= GrantedAccess;
AccessState->RemainingDesiredAccess &= ~(GrantedAccess | MAXIMUM_ALLOWED);
}
ObjectTypeName.Buffer = L"NamedPipe";
ObjectTypeName.Length = 18;
SeOpenObjectAuditAlarm(&ObjectTypeName,
NULL,
&FileObject->FileName,
Fcb->SecurityDescriptor,
AccessState,
FALSE,
AccessGranted,
PreviousMode,
&AccessState->GenerateOnClose);
SeUnlockSubjectContext(SubjectSecurityContext);
if (!AccessGranted) return IoStatus;
if (((GrantedAccess & FILE_READ_DATA) && (NamedPipeConfiguration == FILE_PIPE_INBOUND)) ||
((GrantedAccess & FILE_WRITE_DATA) && (NamedPipeConfiguration == FILE_PIPE_OUTBOUND)))
{
IoStatus.Status = STATUS_ACCESS_DENIED;
return IoStatus;
}
if (!(GrantedAccess & (FILE_READ_DATA | FILE_WRITE_DATA))) SecurityQos = NULL;
ListHead = &Fcb->CcbList;
NextEntry = ListHead->Flink;
while (NextEntry != ListHead)
{
Ccb = CONTAINING_RECORD(NextEntry, NP_CCB, CcbEntry);
if (Ccb->NamedPipeState == FILE_PIPE_LISTENING_STATE) break;
NextEntry = NextEntry->Flink;
}
if (NextEntry == ListHead)
{
IoStatus.Status = STATUS_PIPE_NOT_AVAILABLE;
return IoStatus;
}
IoStatus.Status = NpInitializeSecurity(Ccb, SecurityQos, Thread);
if (!NT_SUCCESS(IoStatus.Status)) return IoStatus;
IoStatus.Status = NpSetConnectedPipeState(Ccb, FileObject, List);
if (!NT_SUCCESS(IoStatus.Status))
{
NpUninitializeSecurity(Ccb);
return IoStatus;
}
Ccb->ClientSession = NULL;
Ccb->Process = IoThreadToProcess(Thread);
IoStatus.Information = FILE_OPENED;
IoStatus.Status = STATUS_SUCCESS;
return IoStatus;
}
NTSTATUS
NTAPI
NpFsdCreate(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PEXTENDED_IO_STACK_LOCATION IoStack;
UNICODE_STRING FileName;
PFILE_OBJECT FileObject;
PFILE_OBJECT RelatedFileObject;
NODE_TYPE_CODE Type;
PNP_CCB Ccb;
PNP_FCB Fcb;
PNP_DCB Dcb;
ACCESS_MASK DesiredAccess;
LIST_ENTRY DeferredList;
UNICODE_STRING Prefix;
InitializeListHead(&DeferredList);
IoStack = (PEXTENDED_IO_STACK_LOCATION)IoGetCurrentIrpStackLocation(Irp);
FileObject = IoStack->FileObject;
RelatedFileObject = FileObject->RelatedFileObject;
FileName = FileObject->FileName;
DesiredAccess = IoStack->Parameters.CreatePipe.SecurityContext->DesiredAccess;
FsRtlEnterFileSystem();
ExAcquireResourceExclusiveLite(&NpVcb->Lock, TRUE);
if (RelatedFileObject)
{
Type = NpDecodeFileObject(RelatedFileObject, (PVOID*)&Fcb, &Ccb, FALSE);
}
else
{
Type = 0;
Fcb = NULL;
Ccb = NULL;
}
if (FileName.Length)
{
if ((FileName.Length == sizeof(OBJ_NAME_PATH_SEPARATOR)) &&
(FileName.Buffer[0] == OBJ_NAME_PATH_SEPARATOR) &&
!(RelatedFileObject))
{
Irp->IoStatus = NpOpenNamedPipeRootDirectory(NpVcb->RootDcb,
FileObject,
DesiredAccess,
&DeferredList);
goto Quickie;
}
}
else if (!(RelatedFileObject) || (Type == NPFS_NTC_VCB))
{
Irp->IoStatus = NpOpenNamedPipeFileSystem(FileObject,
DesiredAccess);
goto Quickie;
}
else if (Type == NPFS_NTC_ROOT_DCB)
{
Irp->IoStatus = NpOpenNamedPipeRootDirectory(NpVcb->RootDcb,
FileObject,
DesiredAccess,
&DeferredList);
goto Quickie;
}
// Status = NpTranslateAlias(&FileName);; // ignore this for now
// if (!NT_SUCCESS(Status)) goto Quickie;
if (RelatedFileObject)
{
if (Type == NPFS_NTC_ROOT_DCB)
{
Dcb = (PNP_DCB)Ccb;
Irp->IoStatus.Status = NpFindRelativePrefix(Dcb,
&FileName,
1,
&Prefix,
&Fcb);
if (!NT_SUCCESS(Irp->IoStatus.Status))
{
goto Quickie;
}
}
else if ((Type != NPFS_NTC_CCB) || (FileName.Length))
{
Irp->IoStatus.Status = STATUS_OBJECT_NAME_INVALID;
goto Quickie;
}
else
{
Prefix.Length = 0;
}
}
else
{
if ((FileName.Length <= sizeof(OBJ_NAME_PATH_SEPARATOR)) ||
(FileName.Buffer[0] != OBJ_NAME_PATH_SEPARATOR))
{
Irp->IoStatus.Status = STATUS_OBJECT_NAME_INVALID;
goto Quickie;
}
Fcb = NpFindPrefix(&FileName, TRUE, &Prefix);
}
if (Prefix.Length)
{
Irp->IoStatus.Status = Fcb->NodeType != NPFS_NTC_FCB ?
STATUS_OBJECT_NAME_NOT_FOUND :
STATUS_OBJECT_NAME_INVALID;
goto Quickie;
}
if (Fcb->NodeType != NPFS_NTC_FCB)
{
Irp->IoStatus.Status = STATUS_OBJECT_NAME_INVALID;
goto Quickie;
}
if (!Fcb->ServerOpenCount)
{
Irp->IoStatus.Status = STATUS_OBJECT_NAME_NOT_FOUND;
goto Quickie;
}
Irp->IoStatus = NpCreateClientEnd(Fcb,
FileObject,
DesiredAccess,
IoStack->Parameters.CreatePipe.
SecurityContext->SecurityQos,
IoStack->Parameters.CreatePipe.
SecurityContext->AccessState,
IoStack->Flags &
SL_FORCE_ACCESS_CHECK ?
UserMode : Irp->RequestorMode,
Irp->Tail.Overlay.Thread,
&DeferredList);
Quickie:
ExReleaseResourceLite(&NpVcb->Lock);
NpCompleteDeferredIrps(&DeferredList);
FsRtlExitFileSystem();
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Irp->IoStatus.Status;
}
IO_STATUS_BLOCK
NTAPI
NpCreateExistingNamedPipe(IN PNP_FCB Fcb,
IN PFILE_OBJECT FileObject,
IN ACCESS_MASK DesiredAccess,
IN PACCESS_STATE AccessState,
IN KPROCESSOR_MODE PreviousMode,
IN ULONG Disposition,
IN ULONG ShareAccess,
IN PNAMED_PIPE_CREATE_PARAMETERS Parameters,
IN PEPROCESS Process,
OUT PLIST_ENTRY List)
{
PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext;
IO_STATUS_BLOCK IoStatus;
UNICODE_STRING ObjectTypeName;
ACCESS_MASK GrantedAccess;
PNP_CCB Ccb;
PPRIVILEGE_SET Privileges;
USHORT NamedPipeConfiguration, CheckShareAccess;
BOOLEAN AccessGranted;
PAGED_CODE();
Privileges = NULL;
NamedPipeConfiguration = Fcb->NamedPipeConfiguration;
SubjectSecurityContext = &AccessState->SubjectSecurityContext;
SeLockSubjectContext(SubjectSecurityContext);
AccessGranted = SeAccessCheck(Fcb->SecurityDescriptor,
SubjectSecurityContext,
TRUE,
DesiredAccess | 4,
0,
&Privileges,
IoGetFileObjectGenericMapping(),
PreviousMode,
&GrantedAccess,
&IoStatus.Status);
if (Privileges)
{
SeAppendPrivileges(AccessState, Privileges);
SeFreePrivileges(Privileges);
}
if (AccessGranted)
{
AccessState->PreviouslyGrantedAccess |= GrantedAccess;
AccessState->RemainingDesiredAccess &= ~(GrantedAccess | 0x2000000);
}
ObjectTypeName.Buffer = L"NamedPipe";
ObjectTypeName.Length = 18;
SeOpenObjectAuditAlarm(&ObjectTypeName,
NULL,
&FileObject->FileName,
Fcb->SecurityDescriptor,
AccessState,
FALSE,
AccessGranted,
PreviousMode,
&AccessState->GenerateOnClose);
SeUnlockSubjectContext(SubjectSecurityContext);
if (!AccessGranted) return IoStatus;
if (Fcb->CurrentInstances >= Fcb->MaximumInstances)
{
IoStatus.Status = STATUS_INSTANCE_NOT_AVAILABLE;
return IoStatus;
}
if (Disposition == FILE_CREATE)
{
IoStatus.Status = STATUS_ACCESS_DENIED;
return IoStatus;
}
CheckShareAccess = 0;
if (NamedPipeConfiguration == FILE_PIPE_FULL_DUPLEX)
{
CheckShareAccess = FILE_SHARE_READ | FILE_SHARE_WRITE;
}
else if (NamedPipeConfiguration == FILE_PIPE_OUTBOUND)
{
CheckShareAccess = FILE_SHARE_READ;
}
else if (NamedPipeConfiguration == FILE_PIPE_INBOUND)
{
CheckShareAccess = FILE_SHARE_WRITE;
}
if (CheckShareAccess != ShareAccess)
{
IoStatus.Status = STATUS_ACCESS_DENIED;
return IoStatus;
}
IoStatus.Status = NpCreateCcb(Fcb,
FileObject,
FILE_PIPE_LISTENING_STATE,
Parameters->ReadMode & 0xFF,
Parameters->CompletionMode & 0xFF,
Parameters->InboundQuota,
Parameters->OutboundQuota,
&Ccb);
if (!NT_SUCCESS(IoStatus.Status)) return IoStatus;
IoStatus.Status = NpCancelWaiter(&NpVcb->WaitQueue,
&Fcb->FullName,
FALSE,
List);
if (!NT_SUCCESS(IoStatus.Status))
{
--Ccb->Fcb->CurrentInstances;
NpDeleteCcb(Ccb, List);
return IoStatus;
}
NpSetFileObject(FileObject, Ccb, Ccb->NonPagedCcb, TRUE);
Ccb->FileObject[FILE_PIPE_SERVER_END] = FileObject;
NpCheckForNotify(Fcb->ParentDcb, 0, List);
IoStatus.Status = STATUS_SUCCESS;
IoStatus.Information = 1;
return IoStatus;
}
NTSTATUS
NTAPI
NpCreateNewNamedPipe(IN PNP_DCB Dcb,
IN PFILE_OBJECT FileObject,
IN UNICODE_STRING PipeName,
IN ACCESS_MASK DesiredAccess,
IN PACCESS_STATE AccessState,
IN USHORT Disposition,
IN USHORT ShareAccess,
IN PNAMED_PIPE_CREATE_PARAMETERS Parameters,
IN PEPROCESS Process,
IN PLIST_ENTRY List,
IN PIO_STATUS_BLOCK IoStatus)
{
NTSTATUS Status;
USHORT NamedPipeConfiguration;
PSECURITY_SUBJECT_CONTEXT SecurityContext;
PSECURITY_DESCRIPTOR SecurityDescriptor, CachedSecurityDescriptor;
PNP_CCB Ccb;
PNP_FCB Fcb;
PAGED_CODE();
if (!(Parameters->TimeoutSpecified) ||
!(Parameters->MaximumInstances) ||
(Parameters->DefaultTimeout.HighPart >= 0))
{
Status = STATUS_INVALID_PARAMETER;
goto Quickie;
}
if (Disposition == FILE_OPEN)
{
Status = STATUS_OBJECT_NAME_NOT_FOUND;
goto Quickie;
}
if (ShareAccess == (FILE_SHARE_READ | FILE_SHARE_WRITE))
{
NamedPipeConfiguration = FILE_PIPE_FULL_DUPLEX;
}
else if (ShareAccess == FILE_SHARE_READ)
{
NamedPipeConfiguration = FILE_PIPE_OUTBOUND;
}
else if (ShareAccess == FILE_SHARE_WRITE)
{
NamedPipeConfiguration = FILE_PIPE_INBOUND;
}
else
{
Status = STATUS_INVALID_PARAMETER;
goto Quickie;
}
if (!Parameters->NamedPipeType && Parameters->ReadMode == 1)
{
Status = STATUS_INVALID_PARAMETER;
goto Quickie;
}
Status = NpCreateFcb(Dcb,
&PipeName,
Parameters->MaximumInstances,
Parameters->DefaultTimeout,
NamedPipeConfiguration,
Parameters->NamedPipeType & 0xFFFF,
&Fcb);
if (!NT_SUCCESS(Status)) goto Quickie;
Status = NpCreateCcb(Fcb,
FileObject,
FILE_PIPE_LISTENING_STATE,
Parameters->ReadMode & 0xFF,
Parameters->CompletionMode & 0xFF,
Parameters->InboundQuota,
Parameters->OutboundQuota,
&Ccb);
if (!NT_SUCCESS(Status))
{
NpDeleteFcb(Fcb, List);
goto Quickie;
}
SecurityContext = &AccessState->SubjectSecurityContext;
SeLockSubjectContext(&AccessState->SubjectSecurityContext);
Status = SeAssignSecurity(0,
AccessState->SecurityDescriptor,
&SecurityDescriptor,
0,
SecurityContext,
IoGetFileObjectGenericMapping(),
PagedPool);
SeUnlockSubjectContext(SecurityContext);
if (!NT_SUCCESS(Status))
{
NpDeleteCcb(Ccb, List);
NpDeleteFcb(Fcb, List);
goto Quickie;
}
Status = ObLogSecurityDescriptor(SecurityDescriptor,
&CachedSecurityDescriptor,
1);
ExFreePool(SecurityDescriptor);
if (!NT_SUCCESS(Status))
{
NpDeleteCcb(Ccb, List);
NpDeleteFcb(Fcb, List);
goto Quickie;
}
Fcb->SecurityDescriptor = CachedSecurityDescriptor;
NpSetFileObject(FileObject, Ccb, Ccb->NonPagedCcb, TRUE);
Ccb->FileObject[FILE_PIPE_SERVER_END] = FileObject;
NpCheckForNotify(Dcb, TRUE, List);
IoStatus->Status = STATUS_SUCCESS;
IoStatus->Information = FILE_CREATED;
return STATUS_SUCCESS;
Quickie:
IoStatus->Information = 0;
IoStatus->Status = Status;
return Status;
}
NTSTATUS
NTAPI
NpFsdCreateNamedPipe(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PEXTENDED_IO_STACK_LOCATION IoStack;
PFILE_OBJECT FileObject;
PFILE_OBJECT RelatedFileObject;
USHORT Disposition, ShareAccess;
PEPROCESS Process;
LIST_ENTRY DeferredList;
UNICODE_STRING FileName;
PNP_FCB Fcb;
UNICODE_STRING Prefix;
PNAMED_PIPE_CREATE_PARAMETERS Parameters;
IO_STATUS_BLOCK IoStatus;
InitializeListHead(&DeferredList);
Process = IoGetRequestorProcess(Irp);
IoStack = (PEXTENDED_IO_STACK_LOCATION) IoGetCurrentIrpStackLocation(Irp);
FileObject = IoStack->FileObject;
RelatedFileObject = FileObject->RelatedFileObject;
Disposition = (IoStack->Parameters.CreatePipe.Options >> 24) & 0xFF;
ShareAccess = IoStack->Parameters.CreatePipe.ShareAccess & 0xFFFF;
Parameters = IoStack->Parameters.CreatePipe.Parameters;
FileName.Buffer = FileObject->FileName.Buffer;
FileName.Length = FileObject->FileName.Length;
FileName.MaximumLength = FileObject->FileName.MaximumLength;
IoStatus.Status = STATUS_SUCCESS;
IoStatus.Information = 0;
FsRtlEnterFileSystem();
NpAcquireExclusiveVcb();
if (RelatedFileObject)
{
Fcb = (PNP_FCB)((ULONG_PTR)RelatedFileObject->FsContext & ~1);
if (!(Fcb) ||
(Fcb->NodeType != NPFS_NTC_ROOT_DCB) ||
(FileName.Length < sizeof(WCHAR)) ||
(FileName.Buffer[0] == OBJ_NAME_PATH_SEPARATOR))
{
IoStatus.Status = STATUS_OBJECT_NAME_INVALID;
goto Quickie;
}
IoStatus.Status = NpFindRelativePrefix(RelatedFileObject->FsContext,
&FileName,
TRUE,
&Prefix,
&Fcb);
if (!NT_SUCCESS(IoStatus.Status))
{
goto Quickie;
}
}
else
{
if (FileName.Length <= sizeof(OBJ_NAME_PATH_SEPARATOR) ||
FileName.Buffer[0] != OBJ_NAME_PATH_SEPARATOR)
{
IoStatus.Status = STATUS_OBJECT_NAME_INVALID;
goto Quickie;
}
Fcb = NpFindPrefix(&FileName, TRUE, &Prefix);
}
if (Prefix.Length)
{
if (Fcb->NodeType == NPFS_NTC_ROOT_DCB)
{
IoStatus.Status = NpCreateNewNamedPipe((PNP_DCB)Fcb,
FileObject,
FileName,
IoStack->Parameters.CreatePipe.
SecurityContext->DesiredAccess,
IoStack->Parameters.CreatePipe.
SecurityContext->AccessState,
Disposition,
ShareAccess,
Parameters,
Process,
&DeferredList,
&IoStatus);
goto Quickie;
}
else
{
IoStatus.Status = STATUS_OBJECT_NAME_INVALID;
goto Quickie;
}
}
if (Fcb->NodeType != NPFS_NTC_FCB)
{
IoStatus.Status = STATUS_OBJECT_NAME_INVALID;
goto Quickie;
}
IoStatus = NpCreateExistingNamedPipe(Fcb,
FileObject,
IoStack->Parameters.CreatePipe.
SecurityContext->DesiredAccess,
IoStack->Parameters.CreatePipe.
SecurityContext->AccessState,
IoStack->Flags &
SL_FORCE_ACCESS_CHECK ?
UserMode : Irp->RequestorMode,
Disposition,
ShareAccess,
Parameters,
Process,
&DeferredList);
Quickie:
NpReleaseVcb();
NpCompleteDeferredIrps(&DeferredList);
FsRtlExitFileSystem();
Irp->IoStatus = IoStatus;
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
return IoStatus.Status;
}
/* EOF */

View file

@ -1,741 +0,0 @@
/*
* PROJECT: ReactOS Named Pipe FileSystem
* LICENSE: BSD - See COPYING.ARM in the top level directory
* FILE: drivers/filesystems/npfs/fsctrl.c
* PURPOSE: Named Pipe FileSystem I/O Controls
* PROGRAMMERS: ReactOS Portable Systems Group
*/
/* INCLUDES *******************************************************************/
#include "npfs.h"
// File ID number for NPFS bugchecking support
#define NPFS_BUGCHECK_FILE_ID (NPFS_BUGCHECK_FSCTRL)
/* GLOBALS ********************************************************************/
IO_STATUS_BLOCK NpUserIoStatusBlock;
/* FUNCTIONS ******************************************************************/
NTSTATUS
NTAPI
NpInternalTransceive(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PLIST_ENTRY List)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
NTAPI
NpInternalRead(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN BOOLEAN Overflow,
IN PLIST_ENTRY List)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
NTAPI
NpInternalWrite(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PLIST_ENTRY List)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
NTAPI
NpQueryClientProcess(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
NTAPI
NpSetClientProcess(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
NTAPI
NpAssignEvent(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
NTAPI
NpQueryEvent(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
NTAPI
NpImpersonate(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
ULONG NamedPipeEnd;
PNP_CCB Ccb;
NTSTATUS Status;
NODE_TYPE_CODE NodeTypeCode;
PIO_STACK_LOCATION IoStack;
PAGED_CODE();
IoStack = IoGetCurrentIrpStackLocation(Irp);
NodeTypeCode = NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &NamedPipeEnd);
if (NodeTypeCode == NPFS_NTC_CCB)
{
if (NamedPipeEnd == FILE_PIPE_SERVER_END)
{
Status = NpImpersonateClientContext(Ccb);
}
else
{
Status = STATUS_ILLEGAL_FUNCTION;
}
}
return Status;
}
NTSTATUS
NTAPI
NpDisconnect(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PLIST_ENTRY List)
{
ULONG NamedPipeEnd;
PNP_CCB Ccb;
NTSTATUS Status;
NODE_TYPE_CODE NodeTypeCode;
PIO_STACK_LOCATION IoStack;
PAGED_CODE();
IoStack = IoGetCurrentIrpStackLocation(Irp);
NodeTypeCode = NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &NamedPipeEnd);
if (NodeTypeCode == NPFS_NTC_CCB)
{
if (NamedPipeEnd == FILE_PIPE_SERVER_END)
{
ExAcquireResourceExclusiveLite(&Ccb->NonPagedCcb->Lock, TRUE);
Status = NpSetDisconnectedPipeState(Ccb, List);
NpUninitializeSecurity(Ccb);
ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock);
}
else
{
Status = STATUS_ILLEGAL_FUNCTION;
}
}
else
{
Status = STATUS_PIPE_DISCONNECTED;
}
return Status;
}
NTSTATUS
NTAPI
NpListen(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PLIST_ENTRY List)
{
ULONG NamedPipeEnd;
PNP_CCB Ccb;
NTSTATUS Status;
NODE_TYPE_CODE NodeTypeCode;
PIO_STACK_LOCATION IoStack;
PAGED_CODE();
IoStack = IoGetCurrentIrpStackLocation(Irp);
NodeTypeCode = NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &NamedPipeEnd);
if (NodeTypeCode == NPFS_NTC_CCB)
{
if (NamedPipeEnd == FILE_PIPE_SERVER_END)
{
ExAcquireResourceExclusiveLite(&Ccb->NonPagedCcb->Lock, TRUE);
Status = NpSetListeningPipeState(Ccb, Irp, List);
NpUninitializeSecurity(Ccb);
ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock);
}
else
{
Status = STATUS_ILLEGAL_FUNCTION;
}
}
else
{
Status = STATUS_ILLEGAL_FUNCTION;
}
return Status;
}
NTSTATUS
NTAPI
NpPeek(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PLIST_ENTRY List)
{
PIO_STACK_LOCATION IoStack;
NODE_TYPE_CODE Type;
ULONG OutputLength;
ULONG NamedPipeEnd;
PNP_CCB Ccb;
PFILE_PIPE_PEEK_BUFFER PeekBuffer;
PNP_DATA_QUEUE DataQueue;
ULONG_PTR BytesPeeked;
IO_STATUS_BLOCK IoStatus;
NTSTATUS Status;
PNP_DATA_QUEUE_ENTRY DataEntry;
PAGED_CODE();
IoStack = IoGetCurrentIrpStackLocation(Irp);
OutputLength = IoStack->Parameters.FileSystemControl.OutputBufferLength;
Type = NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &NamedPipeEnd);
if (!Type)
{
return STATUS_PIPE_DISCONNECTED;
}
if ((Type != NPFS_NTC_CCB) &&
(OutputLength < FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data)))
{
return STATUS_INVALID_PARAMETER;
}
PeekBuffer = (PFILE_PIPE_PEEK_BUFFER)Irp->AssociatedIrp.SystemBuffer;
if (NamedPipeEnd != FILE_PIPE_CLIENT_END)
{
if (NamedPipeEnd != FILE_PIPE_SERVER_END)
{
NpBugCheck(NamedPipeEnd, 0, 0);
}
DataQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
}
else
{
DataQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
}
if (Ccb->NamedPipeState != FILE_PIPE_CONNECTED_STATE)
{
if (Ccb->NamedPipeState != FILE_PIPE_CLOSING_STATE)
{
return STATUS_INVALID_PIPE_STATE;
}
if (DataQueue->QueueState != WriteEntries)
{
return STATUS_PIPE_BROKEN;
}
}
PeekBuffer->NamedPipeState = 0;
PeekBuffer->ReadDataAvailable = 0;
PeekBuffer->NumberOfMessages = 0;
PeekBuffer->MessageLength = 0;
PeekBuffer->NamedPipeState = Ccb->NamedPipeState;
BytesPeeked = FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data);
if (DataQueue->QueueState == WriteEntries)
{
DataEntry = CONTAINING_RECORD(DataQueue->Queue.Flink,
NP_DATA_QUEUE_ENTRY,
QueueEntry);
ASSERT((DataEntry->DataEntryType == Buffered) || (DataEntry->DataEntryType == Unbuffered));
PeekBuffer->ReadDataAvailable = DataQueue->BytesInQueue - DataQueue->ByteOffset;
if (Ccb->Fcb->NamedPipeType == FILE_PIPE_MESSAGE_TYPE)
{
PeekBuffer->NumberOfMessages = DataQueue->EntriesInQueue;
PeekBuffer->MessageLength = DataEntry->DataSize - DataQueue->ByteOffset;
}
if (OutputLength == FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data))
{
Status = PeekBuffer->ReadDataAvailable ? STATUS_BUFFER_OVERFLOW : STATUS_SUCCESS;
}
else
{
IoStatus = NpReadDataQueue(DataQueue,
TRUE,
FALSE,
PeekBuffer->Data,
OutputLength - FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data),
Ccb->Fcb->NamedPipeType == FILE_PIPE_MESSAGE_TYPE,
Ccb,
List);
Status = IoStatus.Status;
BytesPeeked += IoStatus.Information;
}
}
else
{
Status = STATUS_SUCCESS;
}
Irp->IoStatus.Information = BytesPeeked;
return Status;
}
NTSTATUS
NTAPI
NpCompleteTransceiveIrp(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context)
{
PAGED_CODE();
if (Irp->AssociatedIrp.SystemBuffer)
{
ExFreePool(Irp->AssociatedIrp.SystemBuffer);
}
IoFreeIrp(Irp);
return STATUS_MORE_PROCESSING_REQUIRED;
}
NTSTATUS
NTAPI
NpTransceive(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PLIST_ENTRY List)
{
PIO_STACK_LOCATION IoStack;
PVOID InBuffer, OutBuffer;
ULONG InLength, OutLength, BytesWritten;
NODE_TYPE_CODE NodeTypeCode;
PNP_CCB Ccb;
ULONG NamedPipeEnd;
PNP_NONPAGED_CCB NonPagedCcb;
PNP_DATA_QUEUE ReadQueue, WriteQueue;
PNP_EVENT_BUFFER EventBuffer;
NTSTATUS Status;
PIRP NewIrp;
PAGED_CODE();
IoStack = IoGetCurrentIrpStackLocation(Irp);
InLength = IoStack->Parameters.FileSystemControl.InputBufferLength;
InBuffer = IoStack->Parameters.FileSystemControl.Type3InputBuffer;
OutLength = IoStack->Parameters.FileSystemControl.OutputBufferLength;
OutBuffer = Irp->UserBuffer;
if (Irp->RequestorMode == UserMode)
{
_SEH2_TRY
{
ProbeForRead(InBuffer, InLength, sizeof(CHAR));
ProbeForWrite(OutBuffer, OutLength, sizeof(CHAR));
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
_SEH2_YIELD(return _SEH2_GetExceptionCode());
}
_SEH2_END;
}
NodeTypeCode = NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &NamedPipeEnd);
if (NodeTypeCode != NPFS_NTC_CCB)
{
return STATUS_PIPE_DISCONNECTED;
}
NonPagedCcb = Ccb->NonPagedCcb;
ExAcquireResourceExclusiveLite(&NonPagedCcb->Lock, TRUE);
if (Ccb->NamedPipeState != FILE_PIPE_CONNECTED_STATE)
{
Status = STATUS_INVALID_PIPE_STATE;
goto Quickie;
}
if (NamedPipeEnd != FILE_PIPE_CLIENT_END)
{
if (NamedPipeEnd != FILE_PIPE_SERVER_END)
{
NpBugCheck(NamedPipeEnd, 0, 0);
}
ReadQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
WriteQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
}
else
{
ReadQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
WriteQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
}
EventBuffer = NonPagedCcb->EventBuffer[NamedPipeEnd];
if (Ccb->Fcb->NamedPipeConfiguration != FILE_PIPE_FULL_DUPLEX ||
Ccb->ReadMode[NamedPipeEnd] != FILE_PIPE_MESSAGE_MODE)
{
Status = STATUS_INVALID_PIPE_STATE;
goto Quickie;
}
if (ReadQueue->QueueState != Empty)
{
Status = STATUS_PIPE_BUSY;
goto Quickie;
}
Status = NpWriteDataQueue(WriteQueue,
1,
InBuffer,
InLength,
Ccb->Fcb->NamedPipeType,
&BytesWritten,
Ccb,
NamedPipeEnd,
Irp->Tail.Overlay.Thread,
List);
if (Status == STATUS_MORE_PROCESSING_REQUIRED)
{
ASSERT(WriteQueue->QueueState != ReadEntries);
NewIrp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
if (!NewIrp)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto Quickie;
}
IoSetCompletionRoutine(Irp, NpCompleteTransceiveIrp, NULL, TRUE, TRUE, TRUE);
if (BytesWritten)
{
NewIrp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithQuotaTag(PagedPool | POOL_QUOTA_FAIL_INSTEAD_OF_RAISE,
BytesWritten,
NPFS_WRITE_BLOCK_TAG);
if (!NewIrp->AssociatedIrp.SystemBuffer)
{
IoFreeIrp(NewIrp);
Status = STATUS_INSUFFICIENT_RESOURCES;
goto Quickie;
}
_SEH2_TRY
{
RtlCopyMemory(NewIrp->AssociatedIrp.SystemBuffer,
(PVOID)((ULONG_PTR)InBuffer + InLength - BytesWritten),
BytesWritten);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
_SEH2_YIELD(goto Quickie);
}
_SEH2_END;
}
else
{
NewIrp->AssociatedIrp.SystemBuffer = NULL;
}
IoStack = IoGetNextIrpStackLocation(NewIrp);
IoSetNextIrpStackLocation(NewIrp);
NewIrp->Tail.Overlay.Thread = Irp->Tail.Overlay.Thread;
NewIrp->IoStatus.Information = BytesWritten;
IoStack->Parameters.Read.Length = BytesWritten;
IoStack->MajorFunction = IRP_MJ_WRITE;
if (BytesWritten > 0) NewIrp->Flags = IRP_DEALLOCATE_BUFFER | IRP_BUFFERED_IO;
NewIrp->UserIosb = &NpUserIoStatusBlock;
Status = NpAddDataQueueEntry(NamedPipeEnd,
Ccb,
WriteQueue,
WriteEntries,
Unbuffered,
BytesWritten,
NewIrp,
NULL,
0);
if (Status != STATUS_PENDING)
{
NewIrp->IoStatus.Status = Status;
InsertTailList(List, &NewIrp->Tail.Overlay.ListEntry);
}
}
if (!NT_SUCCESS(Status)) goto Quickie;
if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
ASSERT(ReadQueue->QueueState == Empty);
Status = NpAddDataQueueEntry(NamedPipeEnd,
Ccb,
ReadQueue,
ReadEntries,
Buffered,
OutLength,
Irp,
NULL,
0);
if (NT_SUCCESS(Status))
{
if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
}
Quickie:
ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock);
return Status;
}
NTSTATUS
NTAPI
NpWaitForNamedPipe(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PIO_STACK_LOCATION IoStack;
ULONG InLength, NameLength;
UNICODE_STRING SourceString, Prefix;
ULONG NamedPipeEnd;
PNP_CCB Ccb;
PFILE_PIPE_WAIT_FOR_BUFFER Buffer;
NTSTATUS Status;
NODE_TYPE_CODE NodeTypeCode;
PLIST_ENTRY NextEntry;
PNP_FCB Fcb;
PWCHAR OriginalBuffer;
PAGED_CODE();
IoStack = IoGetCurrentIrpStackLocation(Irp);
InLength = IoStack->Parameters.FileSystemControl.InputBufferLength;
SourceString.Buffer = NULL;
if (NpDecodeFileObject(IoStack->FileObject,
NULL,
&Ccb,
&NamedPipeEnd) != NPFS_NTC_ROOT_DCB)
{
Status = STATUS_ILLEGAL_FUNCTION;
goto Quickie;
}
Buffer = (PFILE_PIPE_WAIT_FOR_BUFFER)Irp->AssociatedIrp.SystemBuffer;
if (InLength < sizeof(*Buffer))
{
Status = STATUS_INVALID_PARAMETER;
goto Quickie;
}
NameLength = Buffer->NameLength;
if ((NameLength > (0xFFFF - sizeof(UNICODE_NULL))) ||
((NameLength + FIELD_OFFSET(FILE_PIPE_WAIT_FOR_BUFFER, Name)) > InLength))
{
Status = STATUS_INVALID_PARAMETER;
goto Quickie;
}
SourceString.Length = (USHORT)NameLength + sizeof(OBJ_NAME_PATH_SEPARATOR);
SourceString.Buffer = ExAllocatePoolWithTag(PagedPool,
SourceString.Length,
NPFS_WRITE_BLOCK_TAG);
if (!SourceString.Buffer)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto Quickie;
}
SourceString.Buffer[0] = OBJ_NAME_PATH_SEPARATOR;
RtlCopyMemory(&SourceString.Buffer[1], Buffer->Name, Buffer->NameLength);
Status = STATUS_SUCCESS;
OriginalBuffer = SourceString.Buffer;
//Status = NpTranslateAlias(&SourceString);
if (!NT_SUCCESS(Status)) goto Quickie;
Fcb = NpFindPrefix(&SourceString, TRUE, &Prefix);
Fcb = (PNP_FCB)((ULONG_PTR)Fcb & ~1);
NodeTypeCode = Fcb ? Fcb->NodeType : 0;
if (NodeTypeCode != NPFS_NTC_FCB)
{
Status = STATUS_OBJECT_NAME_NOT_FOUND;
goto Quickie;
}
for (NextEntry = Fcb->CcbList.Flink;
NextEntry != &Fcb->CcbList;
NextEntry = NextEntry->Flink)
{
Ccb = CONTAINING_RECORD(NextEntry, NP_CCB, CcbEntry);
if (Ccb->NamedPipeState == FILE_PIPE_LISTENING_STATE) break;
}
if (NextEntry != &Fcb->CcbList)
{
Status = STATUS_SUCCESS;
}
else
{
Status = NpAddWaiter(&NpVcb->WaitQueue,
Fcb->Timeout,
Irp,
OriginalBuffer == SourceString.Buffer ?
NULL : &SourceString);
}
Quickie:
if (SourceString.Buffer) ExFreePool(SourceString.Buffer);
return Status;
}
NTSTATUS
NTAPI
NpCommonFileSystemControl(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
ULONG Fsctl;
BOOLEAN Overflow = FALSE;
LIST_ENTRY DeferredList;
NTSTATUS Status;
PAGED_CODE();
InitializeListHead(&DeferredList);
Fsctl = IoGetCurrentIrpStackLocation(Irp)->Parameters.FileSystemControl.FsControlCode;
switch (Fsctl)
{
case FSCTL_PIPE_PEEK:
NpAcquireExclusiveVcb();
Status = NpPeek(DeviceObject, Irp, &DeferredList);
break;
case FSCTL_PIPE_INTERNAL_WRITE:
NpAcquireSharedVcb();
Status = NpInternalWrite(DeviceObject, Irp, &DeferredList);
break;
case FSCTL_PIPE_TRANSCEIVE:
NpAcquireSharedVcb();
Status = NpTransceive(DeviceObject, Irp, &DeferredList);
break;
case FSCTL_PIPE_INTERNAL_TRANSCEIVE:
NpAcquireSharedVcb();
Status = NpInternalTransceive(DeviceObject, Irp, &DeferredList);
break;
case FSCTL_PIPE_INTERNAL_READ_OVFLOW:
Overflow = TRUE;
// on purpose
case FSCTL_PIPE_INTERNAL_READ:
NpAcquireSharedVcb();
Status = NpInternalRead(DeviceObject, Irp, Overflow, &DeferredList);
break;
case FSCTL_PIPE_QUERY_CLIENT_PROCESS:
NpAcquireSharedVcb();
Status = NpQueryClientProcess(DeviceObject, Irp);
break;
case FSCTL_PIPE_ASSIGN_EVENT:
NpAcquireExclusiveVcb();
Status = NpAssignEvent(DeviceObject, Irp);
break;
case FSCTL_PIPE_DISCONNECT:
NpAcquireExclusiveVcb();
Status = NpDisconnect(DeviceObject, Irp, &DeferredList);
break;
case FSCTL_PIPE_LISTEN:
NpAcquireSharedVcb();
Status = NpListen(DeviceObject, Irp, &DeferredList);
break;
case FSCTL_PIPE_QUERY_EVENT:
NpAcquireExclusiveVcb();
Status = NpQueryEvent(DeviceObject, Irp);
break;
case FSCTL_PIPE_WAIT:
NpAcquireExclusiveVcb();
Status = NpWaitForNamedPipe(DeviceObject, Irp);
break;
case FSCTL_PIPE_IMPERSONATE:
NpAcquireExclusiveVcb();
Status = NpImpersonate(DeviceObject, Irp);
break;
case FSCTL_PIPE_SET_CLIENT_PROCESS:
NpAcquireExclusiveVcb();
Status = NpSetClientProcess(DeviceObject, Irp);
break;
default:
return STATUS_NOT_SUPPORTED;
}
NpReleaseVcb();
NpCompleteDeferredIrps(&DeferredList);
return Status;
}
NTSTATUS
NTAPI
NpFsdFileSystemControl(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
NTSTATUS Status;
PAGED_CODE();
FsRtlEnterFileSystem();
Status = NpCommonFileSystemControl(DeviceObject, Irp);
FsRtlExitFileSystem();
if (Status != STATUS_PENDING)
{
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
}
return Status;
}
/* EOF */

View file

@ -1,675 +0,0 @@
/*
* PROJECT: ReactOS Named Pipe FileSystem
* LICENSE: BSD - See COPYING.ARM in the top level directory
* FILE: drivers/filesystems/npfs/npfs.h
* PURPOSE: Named Pipe FileSystem Header
* PROGRAMMERS: ReactOS Portable Systems Group
*/
/* INCLUDES *******************************************************************/
//
// System Headers
//
#include <ntifs.h>
#include <ntndk.h>
#include <pseh/pseh2.h>
#define UNIMPLEMENTED
#define DPRINT1 DbgPrint
//
// Allow Microsoft Extensions
//
#ifdef _MSC_VER
#pragma warning(disable:4201)
#pragma warning(disable:4214)
#pragma warning(disable:4100)
#endif
/* TYPEDEFS & DEFINES *********************************************************/
//
// Pool Tags for NPFS (from pooltag.txt)
//
// Npf* -npfs.sys - Npfs Allocations
// NpFc - npfs.sys - CCB, client control block
// NpFf - npfs.sys - FCB, file control block
// NpFC - npfs.sys - ROOT_DCB CCB
// NpFD - npfs.sys - DCB, directory block
// NpFg - npfs.sys - Global storage
// NpFi - npfs.sys - NPFS client info buffer.
// NpFn - npfs.sys - Name block
// NpFq - npfs.sys - Query template buffer used for directory query
// NpFr - npfs.sys - DATA_ENTRY records(read / write buffers)
// NpFs - npfs.sys - Client security context
// NpFw - npfs.sys - Write block
// NpFW - npfs.sys - Write block
#define NPFS_CCB_TAG 'NpFc'
#define NPFS_ROOT_DCB_CCB_TAG 'NpFC'
#define NPFS_DCB_TAG 'NpFD'
#define NPFS_FCB_TAG 'NpFf'
#define NPFS_GLOBAL_TAG 'NpFg'
#define NPFS_CLIENT_INFO_TAG 'NpFi'
#define NPFS_NAME_BLOCK_TAG 'NpFn'
#define NPFS_QUERY_TEMPLATE_TAG 'NpFq'
#define NPFS_DATA_ENTRY_TAG 'NpFr'
#define NPFS_CLIENT_SEC_CTX_TAG 'NpFs'
#define NPFS_WAIT_BLOCK_TAG 'NpFt'
#define NPFS_WRITE_BLOCK_TAG 'NpFw'
//
// NPFS bugchecking support
//
// We define the NpBugCheck macro which triggers a NPFS_FILE_SYSTEM bugcheck
// containing the source file ID number and the line where it was emitted, as
// described in the MSDN article "Bug Check 0x25: NPFS_FILE_SYSTEM".
//
// The bugcheck emits 4 ULONGs; the first one is made, in its high word, by
// the current source file ID and in its low word, by the line number; the
// three other ones are user-defined.
//
// In order to avoid redefinition of the same file ID in different source files,
// we gather all of them here, so that you will have to add (or remove) a new
// one as soon as you add (or remove) a source file from the NPFS driver code.
//
// To use the NpBugCheck macro in a source file, define at its beginning
// the constant NPFS_BUGCHECK_FILE_ID with one of the following file IDs,
// then use the bugcheck macro wherever you want.
//
#define NPFS_BUGCHECK_CLEANUP 0x0001
#define NPFS_BUGCHECK_CLOSE 0x0002
#define NPFS_BUGCHECK_CREATE 0x0003
#define NPFS_BUGCHECK_DATASUP 0x0004
#define NPFS_BUGCHECK_FILEINFO 0x0005
#define NPFS_BUGCHECK_FILEOBSUP 0x0006
#define NPFS_BUGCHECK_FLUSHBUF 0x0007
#define NPFS_BUGCHECK_FSCTRL 0x0008
#define NPFS_BUGCHECK_MAIN 0x0009
#define NPFS_BUGCHECK_PREFXSUP 0x000a
#define NPFS_BUGCHECK_READ 0x000b
#define NPFS_BUGCHECK_READSUP 0x000c
#define NPFS_BUGCHECK_SECURSUP 0x000d
#define NPFS_BUGCHECK_SEINFO 0x000e
#define NPFS_BUGCHECK_STATESUP 0x000f
#define NPFS_BUGCHECK_STRUCSUP 0x0010
#define NPFS_BUGCHECK_VOLINFO 0x0011
#define NPFS_BUGCHECK_WAITSUP 0x0012
#define NPFS_BUGCHECK_WRITE 0x0013
#define NPFS_BUGCHECK_WRITESUP 0x0014
#define NpBugCheck(p1, p2, p3) \
KeBugCheckEx(NPFS_FILE_SYSTEM, \
(NPFS_BUGCHECK_FILE_ID << 16) | __LINE__, \
(p1), (p2), (p3))
//
// Node Type Codes for NPFS
//
#define NPFS_NTC_VCB 1
#define NPFS_NTC_ROOT_DCB 2
#define NPFS_NTC_FCB 4
#define NPFS_NTC_CCB 6
#define NPFS_NTC_NONPAGED_CCB 7
#define NPFS_NTC_ROOT_DCB_CCB 8
typedef USHORT NODE_TYPE_CODE, *PNODE_TYPE_CODE;
//
// Data Queue States
//
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 Queue;
ULONG QueueState;
ULONG BytesInQueue;
ULONG EntriesInQueue;
ULONG QuotaUsed;
ULONG ByteOffset;
ULONG Quota;
} 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
{
LIST_ENTRY WaitList;
KSPIN_LOCK WaitLock;
} NP_WAIT_QUEUE, *PNP_WAIT_QUEUE;
//
// The Entries in the Queue above, one for each Waiter.
//
typedef struct _NP_WAIT_QUEUE_ENTRY
{
PIRP Irp;
KDPC Dpc;
KTIMER Timer;
PNP_WAIT_QUEUE WaitQueue;
UNICODE_STRING AliasName;
PFILE_OBJECT FileObject;
} NP_WAIT_QUEUE_ENTRY, *PNP_WAIT_QUEUE_ENTRY;
//
// 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
//
typedef struct _NP_ROOT_DCB_CCB
{
NODE_TYPE_CODE NodeType;
PVOID Unknown;
ULONG Unknown2;
} NP_ROOT_DCB_CCB, *PNP_ROOT_DCB_FCB;
//
// The header that both FCB and DCB share
//
typedef struct _NP_CB_HEADER
{
NODE_TYPE_CODE NodeType;
LIST_ENTRY DcbEntry;
PVOID ParentDcb;
ULONG CurrentInstances;
ULONG ServerOpenCount;
PSECURITY_DESCRIPTOR SecurityDescriptor;
} NP_CB_HEADER, *PNP_CB_HEADER;
//
// The footer that both FCB and DCB share
//
typedef struct _NP_CB_FOOTER
{
UNICODE_STRING FullName;
UNICODE_STRING ShortName;
UNICODE_PREFIX_TABLE_ENTRY PrefixTableEntry;
} NP_CB_FOOTER;
//
// A Directory Control Block (DCB)
//
typedef struct _NP_DCB
{
//
// Common Header
//
NP_CB_HEADER;
//
// DCB-specific data
//
LIST_ENTRY NotifyList;
LIST_ENTRY NotifyList2;
LIST_ENTRY FcbList;
#ifndef _WIN64
ULONG Pad;
#endif
//
// Common Footer
//
NP_CB_FOOTER;
} NP_DCB, *PNP_DCB;
//
// A File Control BLock (FCB)
//
typedef struct _NP_FCB
{
//
// Common Header
//
NP_CB_HEADER;
//
// FCB-specific fields
//
ULONG MaximumInstances;
USHORT NamedPipeConfiguration;
USHORT NamedPipeType;
LARGE_INTEGER Timeout;
LIST_ENTRY CcbList;
#ifdef _WIN64
PVOID Pad[2];
#endif
//
// Common Footer
//
NP_CB_FOOTER;
} NP_FCB, *PNP_FCB;
C_ASSERT(FIELD_OFFSET(NP_FCB, PrefixTableEntry) == FIELD_OFFSET(NP_DCB, PrefixTableEntry));
//
// The nonpaged portion of the CCB
//
typedef struct _NP_NONPAGED_CCB
{
NODE_TYPE_CODE NodeType;
PNP_EVENT_BUFFER EventBuffer[2];
ERESOURCE Lock;
} NP_NONPAGED_CCB, *PNP_NONPAGED_CCB;
//
// A Client Control Block (CCB)
//
typedef struct _NP_CCB
{
NODE_TYPE_CODE NodeType;
UCHAR NamedPipeState;
UCHAR ReadMode[2];
UCHAR CompletionMode[2];
SECURITY_QUALITY_OF_SERVICE ClientQos;
LIST_ENTRY CcbEntry;
PNP_FCB Fcb;
PFILE_OBJECT FileObject[2];
PEPROCESS Process;
PVOID ClientSession;
PNP_NONPAGED_CCB NonPagedCcb;
NP_DATA_QUEUE DataQueue[2];
PSECURITY_CLIENT_CONTEXT ClientContext;
LIST_ENTRY IrpList;
} NP_CCB, *PNP_CCB;
//
// A Volume Control Block (VCB)
//
typedef struct _NP_VCB
{
NODE_TYPE_CODE NodeType;
ULONG ReferenceCount;
PNP_DCB RootDcb;
UNICODE_PREFIX_TABLE PrefixTable;
ERESOURCE Lock;
RTL_GENERIC_TABLE EventTable;
NP_WAIT_QUEUE WaitQueue;
} NP_VCB, *PNP_VCB;
extern PNP_VCB NpVcb;
/* FUNCTIONS ******************************************************************/
//
// Functions to lock/unlock the global VCB lock
//
FORCEINLINE
VOID
NpAcquireSharedVcb(VOID)
{
/* Acquire the lock in shared mode */
ExAcquireResourceSharedLite(&NpVcb->Lock, TRUE);
}
FORCEINLINE
VOID
NpAcquireExclusiveVcb(VOID)
{
/* Acquire the lock in exclusive mode */
ExAcquireResourceExclusiveLite(&NpVcb->Lock, TRUE);
}
FORCEINLINE
VOID
NpReleaseVcb(VOID)
{
/* Release the lock */
ExReleaseResourceLite(&NpVcb->Lock);
}
//
// Function to process deferred IRPs outside the VCB lock but still within the
// critical region
//
VOID
FORCEINLINE
NpCompleteDeferredIrps(IN PLIST_ENTRY DeferredList)
{
PLIST_ENTRY ThisEntry, NextEntry;
PIRP Irp;
/* Loop the list */
ThisEntry = DeferredList->Flink;
while (ThisEntry != DeferredList)
{
/* Remember the next entry, but don't switch to it yet */
NextEntry = ThisEntry->Flink;
/* Complete the IRP for this entry */
Irp = CONTAINING_RECORD(ThisEntry, IRP, Tail.Overlay.ListEntry);
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
/* And now switch to the next one */
ThisEntry = NextEntry;
}
}
BOOLEAN
NTAPI
NpDeleteEventTableEntry(IN PRTL_GENERIC_TABLE Table,
IN PVOID Buffer);
VOID
NTAPI
NpInitializeWaitQueue(IN PNP_WAIT_QUEUE WaitQueue);
NTSTATUS
NTAPI
NpUninitializeDataQueue(IN PNP_DATA_QUEUE DataQueue);
PLIST_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 ULONG NamedPipeEnd,
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,
IN ULONG Quota);
NTSTATUS
NTAPI
NpCreateCcb(IN PNP_FCB Fcb,
IN PFILE_OBJECT FileObject,
IN UCHAR State,
IN UCHAR ReadMode,
IN UCHAR CompletionMode,
IN ULONG InQuota,
IN ULONG OutQuota,
OUT PNP_CCB *NewCcb);
NTSTATUS
NTAPI
NpCreateFcb(IN PNP_DCB Dcb,
IN PUNICODE_STRING PipeName,
IN ULONG MaximumInstances,
IN LARGE_INTEGER Timeout,
IN USHORT NamedPipeConfiguration,
IN USHORT NamedPipeType,
OUT PNP_FCB *NewFcb);
NTSTATUS
NTAPI
NpCreateRootDcb(VOID);
NTSTATUS
NTAPI
NpCreateRootDcbCcb(IN PNP_ROOT_DCB_FCB *NewRootCcb);
VOID
NTAPI
NpInitializeVcb(VOID);
VOID
NTAPI
NpDeleteCcb(IN PNP_CCB Ccb,
IN PLIST_ENTRY ListEntry);
VOID
NTAPI
NpDeleteFcb(IN PNP_FCB Fcb,
IN PLIST_ENTRY ListEntry);
NTSTATUS
NTAPI
NpFsdCreateNamedPipe(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
NTSTATUS
NTAPI
NpFsdCreate(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
NTSTATUS
NTAPI
NpFsdClose(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
NTSTATUS
NTAPI
NpFsdCleanup(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
NTSTATUS
NTAPI
NpFsdFileSystemControl(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
NTSTATUS
NTAPI
NpSetConnectedPipeState(IN PNP_CCB Ccb,
IN PFILE_OBJECT FileObject,
IN PLIST_ENTRY List);
NTSTATUS
NTAPI
NpSetListeningPipeState(IN PNP_CCB Ccb,
IN PIRP Irp,
IN PLIST_ENTRY List);
NTSTATUS
NTAPI
NpSetDisconnectedPipeState(IN PNP_CCB Ccb,
IN PLIST_ENTRY List);
NTSTATUS
NTAPI
NpSetClosingPipeState(IN PNP_CCB Ccb,
IN PIRP Irp,
IN ULONG NamedPipeEnd,
IN PLIST_ENTRY List);
VOID
NTAPI
NpFreeClientSecurityContext(IN PSECURITY_CLIENT_CONTEXT ClientContext);
NTSTATUS
NTAPI
NpImpersonateClientContext(IN PNP_CCB Ccb);
VOID
NTAPI
NpCopyClientContext(IN PNP_CCB Ccb,
IN PNP_DATA_QUEUE_ENTRY DataQueueEntry);
VOID
NTAPI
NpUninitializeSecurity(IN PNP_CCB Ccb);
NTSTATUS
NTAPI
NpInitializeSecurity(IN PNP_CCB Ccb,
IN PSECURITY_QUALITY_OF_SERVICE SecurityQos,
IN PETHREAD Thread);
NTSTATUS
NTAPI
NpGetClientSecurityContext(IN ULONG NamedPipeEnd,
IN PNP_CCB Ccb,
IN PETHREAD Thread,
IN PSECURITY_CLIENT_CONTEXT *Context);
VOID
NTAPI
NpSetFileObject(IN PFILE_OBJECT FileObject,
IN PVOID PrimaryContext,
IN PVOID Ccb,
IN ULONG NamedPipeEnd);
NODE_TYPE_CODE
NTAPI
NpDecodeFileObject(IN PFILE_OBJECT FileObject,
OUT PVOID *PrimaryContext OPTIONAL,
OUT PNP_CCB *Ccb,
OUT PULONG NamedPipeEnd OPTIONAL);
PNP_FCB
NTAPI
NpFindPrefix(IN PUNICODE_STRING Name,
IN ULONG CaseInsensitiveIndex,
IN PUNICODE_STRING Prefix);
NTSTATUS
NTAPI
NpFindRelativePrefix(IN PNP_DCB Dcb,
IN PUNICODE_STRING Name,
IN ULONG CaseInsensitiveIndex,
IN PUNICODE_STRING Prefix,
OUT PNP_FCB *FoundFcb);
VOID
NTAPI
NpCheckForNotify(IN PNP_DCB Dcb,
IN BOOLEAN SecondList,
IN PLIST_ENTRY List);
NTSTATUS
NTAPI
NpAddWaiter(IN PNP_WAIT_QUEUE WaitQueue,
IN LARGE_INTEGER WaitTime,
IN PIRP Irp,
IN PUNICODE_STRING AliasName);
NTSTATUS
NTAPI
NpCancelWaiter(IN PNP_WAIT_QUEUE WaitQueue,
IN PUNICODE_STRING PipeName,
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
NpWriteDataQueue(IN PNP_DATA_QUEUE WriteQueue,
IN ULONG Mode,
IN PVOID OutBuffer,
IN ULONG OutBufferSize,
IN ULONG PipeType,
OUT PULONG BytesWritten,
IN PNP_CCB Ccb,
IN ULONG NamedPipeEnd,
IN PETHREAD Thread,
IN PLIST_ENTRY List);
NTSTATUS
NTAPI
NpFsdRead(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
NTSTATUS
NTAPI
NpFsdWrite(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
NTSTATUS
NTAPI
NpFsdFlushBuffers(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
NTSTATUS
NTAPI
NpFsdSetInformation(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
NTSTATUS
NTAPI
NpFsdQueryInformation(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
NTSTATUS
NTAPI
NpFsdQuerySecurityInfo(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
NTSTATUS
NTAPI
NpFsdSetSecurityInfo(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
NTSTATUS
NTAPI
NpFsdQueryVolumeInformation(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
/* EOF */