mirror of
https://github.com/reactos/reactos.git
synced 2024-06-29 01:12:06 +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
|
@ -6,5 +6,5 @@ add_subdirectory(fastfat)
|
|||
add_subdirectory(fs_rec)
|
||||
add_subdirectory(msfs)
|
||||
add_subdirectory(mup)
|
||||
add_subdirectory(npfs_new)
|
||||
add_subdirectory(npfs)
|
||||
add_subdirectory(ntfs)
|
||||
|
|
|
@ -1,19 +1,29 @@
|
|||
|
||||
list(APPEND SOURCE
|
||||
cleanup.c
|
||||
close.c
|
||||
create.c
|
||||
dirctl.c
|
||||
finfo.c
|
||||
datasup.c
|
||||
fileinfo.c
|
||||
fileobsup.c
|
||||
flushbuf.c
|
||||
fsctrl.c
|
||||
npfs.c
|
||||
rw.c
|
||||
volume.c
|
||||
npfs.rc)
|
||||
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})
|
||||
|
||||
target_link_libraries(npfs ${PSEH_LIB})
|
||||
|
||||
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)
|
||||
|
|
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 <ndk/iotypes.h>
|
||||
#include <ntndk.h>
|
||||
#include <pseh/pseh2.h>
|
||||
#define UNIMPLEMENTED
|
||||
#define DPRINT1 DbgPrint
|
||||
|
||||
#define TAG_NPFS_CCB 'cFpN'
|
||||
#define TAG_NPFS_CCB_DATA 'iFpN' /* correct? */
|
||||
#define TAG_NPFS_FCB 'FFpN'
|
||||
#define TAG_NPFS_NAMEBLOCK 'nFpN'
|
||||
#define TAG_NPFS_THREAD_CONTEXT 'tFpN'
|
||||
//
|
||||
// Allow Microsoft Extensions
|
||||
//
|
||||
#ifdef _MSC_VER
|
||||
#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) \
|
||||
ROUND_DOWN(((ULONG)n) + (align) - 1, (align))
|
||||
/* TYPEDEFS & DEFINES *********************************************************/
|
||||
|
||||
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,
|
||||
FCB_DEVICE,
|
||||
FCB_DIRECTORY,
|
||||
FCB_PIPE
|
||||
} FCB_TYPE;
|
||||
ReadEntries = 0,
|
||||
WriteEntries = 1,
|
||||
Empty = 2
|
||||
} NP_DATA_QUEUE_STATE;
|
||||
|
||||
typedef enum _CCB_TYPE
|
||||
//
|
||||
// Data Queue Entry Types
|
||||
//
|
||||
typedef enum _NP_DATA_QUEUE_ENTRY_TYPE
|
||||
{
|
||||
CCB_INVALID,
|
||||
CCB_DEVICE,
|
||||
CCB_DIRECTORY,
|
||||
CCB_PIPE
|
||||
} CCB_TYPE;
|
||||
Buffered = 0,
|
||||
Unbuffered
|
||||
} NP_DATA_QUEUE_ENTRY_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 ThreadListHead;
|
||||
KMUTEX PipeListLock;
|
||||
ULONG EmptyWaiterCount;
|
||||
ULONG MinQuota;
|
||||
ULONG DefaultQuota;
|
||||
ULONG MaxQuota;
|
||||
struct _NPFS_FCB *DeviceFcb;
|
||||
struct _NPFS_FCB *RootFcb;
|
||||
} NPFS_VCB, *PNPFS_VCB;
|
||||
LIST_ENTRY Queue;
|
||||
ULONG QueueState;
|
||||
ULONG BytesInQueue;
|
||||
ULONG EntriesInQueue;
|
||||
ULONG QuotaUsed;
|
||||
ULONG ByteOffset;
|
||||
ULONG Quota;
|
||||
} NP_DATA_QUEUE, *PNP_DATA_QUEUE;
|
||||
|
||||
typedef struct _NPFS_FCB
|
||||
//
|
||||
// The Entries that go into the Queue
|
||||
//
|
||||
typedef struct _NP_DATA_QUEUE_ENTRY
|
||||
{
|
||||
FCB_TYPE Type;
|
||||
PNPFS_VCB Vcb;
|
||||
volatile LONG RefCount;
|
||||
UNICODE_STRING PipeName;
|
||||
LIST_ENTRY PipeListEntry;
|
||||
KMUTEX CcbListLock;
|
||||
LIST_ENTRY ServerCcbListHead;
|
||||
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;
|
||||
LIST_ENTRY QueueEntry;
|
||||
ULONG DataEntryType;
|
||||
PIRP Irp;
|
||||
ULONG QuotaInEntry;
|
||||
PSECURITY_CLIENT_CONTEXT ClientSecurityContext;
|
||||
ULONG DataSize;
|
||||
} NP_DATA_QUEUE_ENTRY, *PNP_DATA_QUEUE_ENTRY;
|
||||
|
||||
|
||||
typedef struct _NPFS_CCB_DIRECTORY_DATA
|
||||
//
|
||||
// A Wait Queue. Only the VCB has one of these.
|
||||
//
|
||||
typedef struct _NP_WAIT_QUEUE
|
||||
{
|
||||
UNICODE_STRING SearchPattern;
|
||||
ULONG FileIndex;
|
||||
} NPFS_CCB_DIRECTORY_DATA, *PNPFS_CCB_DIRECTORY_DATA;
|
||||
LIST_ENTRY WaitList;
|
||||
KSPIN_LOCK WaitLock;
|
||||
} 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;
|
||||
CCB_TYPE Type;
|
||||
PNPFS_FCB Fcb;
|
||||
PIRP Irp;
|
||||
KDPC Dpc;
|
||||
KTIMER Timer;
|
||||
PNP_WAIT_QUEUE WaitQueue;
|
||||
UNICODE_STRING AliasName;
|
||||
PFILE_OBJECT FileObject;
|
||||
} NP_WAIT_QUEUE_ENTRY, *PNP_WAIT_QUEUE_ENTRY;
|
||||
|
||||
struct _NPFS_CCB* OtherSide;
|
||||
struct ETHREAD *Thread;
|
||||
KEVENT ConnectEvent;
|
||||
KEVENT ReadEvent;
|
||||
KEVENT WriteEvent;
|
||||
ULONG PipeEnd;
|
||||
ULONG PipeState;
|
||||
ULONG ReadDataAvailable;
|
||||
ULONG WriteQuotaAvailable;
|
||||
volatile LONG RefCount;
|
||||
//
|
||||
// The event buffer in the NonPaged CCB
|
||||
//
|
||||
typedef struct _NP_EVENT_BUFFER
|
||||
{
|
||||
PKEVENT Event;
|
||||
} NP_EVENT_BUFFER, *PNP_EVENT_BUFFER;
|
||||
|
||||
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;
|
||||
PVOID WritePtr;
|
||||
ULONG MaxDataLength;
|
||||
//
|
||||
// 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;
|
||||
|
||||
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;
|
||||
} u;
|
||||
/* Remember the next entry, but don't switch to it yet */
|
||||
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
|
||||
{
|
||||
LIST_ENTRY ListEntry;
|
||||
PKEVENT WaitEvent;
|
||||
} NPFS_CONTEXT, *PNPFS_CONTEXT;
|
||||
/* And now switch to the next one */
|
||||
ThisEntry = NextEntry;
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct _NPFS_THREAD_CONTEXT
|
||||
{
|
||||
ULONG Count;
|
||||
KEVENT Event;
|
||||
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);
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
NpDeleteEventTableEntry(IN PRTL_GENERIC_TABLE Table,
|
||||
IN PVOID Buffer);
|
||||
|
||||
VOID
|
||||
NpfsDereferenceFcb(PNPFS_FCB Fcb);
|
||||
NTAPI
|
||||
NpInitializeWaitQueue(IN PNP_WAIT_QUEUE WaitQueue);
|
||||
|
||||
PNPFS_FCB
|
||||
NpfsFindPipe(PNPFS_VCB Vcb,
|
||||
PUNICODE_STRING PipeName);
|
||||
|
||||
FCB_TYPE
|
||||
NpfsGetFcb(PFILE_OBJECT FileObject,
|
||||
PNPFS_FCB *Fcb);
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpUninitializeDataQueue(IN PNP_DATA_QUEUE DataQueue);
|
||||
|
||||
CCB_TYPE
|
||||
NpfsGetCcb(PFILE_OBJECT FileObject,
|
||||
PNPFS_CCB *Ccb);
|
||||
PLIST_ENTRY
|
||||
NTAPI
|
||||
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…
Reference in a new issue