mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 14:25:52 +00:00
[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:
parent
9f4686524d
commit
429a1c4b23
27 changed files with 1938 additions and 4004 deletions
|
@ -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)
|
||||||
|
|
|
@ -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
|
@ -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 */
|
||||||
|
|
|
@ -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)
|
|
|
@ -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 */
|
|
|
@ -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 */
|
|
|
@ -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 */
|
|
Loading…
Add table
Add a link
Reference in a new issue