/* * 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 #include #include #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 */