2 * PROJECT: ReactOS Named Pipe FileSystem
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: drivers/filesystems/npfs/npfs.h
5 * PURPOSE: Named Pipe FileSystem Header
6 * PROGRAMMERS: ReactOS Portable Systems Group
9 /* INCLUDES *******************************************************************/
16 #include <pseh/pseh2.h>
17 //#define UNIMPLEMENTED
18 //#define DPRINT1 DbgPrint
22 #define TRACE(...) /* DPRINT1("%s: ", __FUNCTION__); DbgPrint(__VA_ARGS__) */
25 // Allow Microsoft Extensions
28 #pragma warning(disable:4201)
29 #pragma warning(disable:4214)
30 #pragma warning(disable:4100)
33 #define MIN_INDEXED_LENGTH 5
34 #define MAX_INDEXED_LENGTH 9
37 /* TYPEDEFS & DEFINES *********************************************************/
40 // Pool Tags for NPFS (from pooltag.txt)
42 // Npf* -npfs.sys - Npfs Allocations
43 // NpFc - npfs.sys - CCB, client control block
44 // NpFf - npfs.sys - FCB, file control block
45 // NpFC - npfs.sys - ROOT_DCB CCB
46 // NpFD - npfs.sys - DCB, directory block
47 // NpFg - npfs.sys - Global storage
48 // NpFi - npfs.sys - NPFS client info buffer.
49 // NpFn - npfs.sys - Name block
50 // NpFq - npfs.sys - Query template buffer used for directory query
51 // NpFr - npfs.sys - DATA_ENTRY records(read / write buffers)
52 // NpFs - npfs.sys - Client security context
53 // NpFw - npfs.sys - Write block
54 // NpFW - npfs.sys - Write block
55 #define NPFS_CCB_TAG 'NpFc'
56 #define NPFS_ROOT_DCB_CCB_TAG 'NpFC'
57 #define NPFS_DCB_TAG 'NpFD'
58 #define NPFS_FCB_TAG 'NpFf'
59 #define NPFS_GLOBAL_TAG 'NpFg'
60 #define NPFS_CLIENT_INFO_TAG 'NpFi'
61 #define NPFS_NAME_BLOCK_TAG 'NpFn'
62 #define NPFS_QUERY_TEMPLATE_TAG 'NpFq'
63 #define NPFS_DATA_ENTRY_TAG 'NpFr'
64 #define NPFS_CLIENT_SEC_CTX_TAG 'NpFs'
65 #define NPFS_WAIT_BLOCK_TAG 'NpFt'
66 #define NPFS_WRITE_BLOCK_TAG 'NpFw'
69 // NPFS bugchecking support
71 // We define the NpBugCheck macro which triggers a NPFS_FILE_SYSTEM bugcheck
72 // containing the source file ID number and the line where it was emitted, as
73 // described in the MSDN article "Bug Check 0x25: NPFS_FILE_SYSTEM".
75 // The bugcheck emits 4 ULONGs; the first one is made, in its high word, by
76 // the current source file ID and in its low word, by the line number; the
77 // three other ones are user-defined.
79 // In order to avoid redefinition of the same file ID in different source files,
80 // we gather all of them here, so that you will have to add (or remove) a new
81 // one as soon as you add (or remove) a source file from the NPFS driver code.
83 // To use the NpBugCheck macro in a source file, define at its beginning
84 // the constant NPFS_BUGCHECK_FILE_ID with one of the following file IDs,
85 // then use the bugcheck macro wherever you want.
87 #define NPFS_BUGCHECK_CLEANUP 0x0001
88 #define NPFS_BUGCHECK_CLOSE 0x0002
89 #define NPFS_BUGCHECK_CREATE 0x0003
90 #define NPFS_BUGCHECK_DATASUP 0x0004
91 #define NPFS_BUGCHECK_FILEINFO 0x0005
92 #define NPFS_BUGCHECK_FILEOBSUP 0x0006
93 #define NPFS_BUGCHECK_FLUSHBUF 0x0007
94 #define NPFS_BUGCHECK_FSCTRL 0x0008
95 #define NPFS_BUGCHECK_MAIN 0x0009
96 #define NPFS_BUGCHECK_PREFXSUP 0x000a
97 #define NPFS_BUGCHECK_READ 0x000b
98 #define NPFS_BUGCHECK_READSUP 0x000c
99 #define NPFS_BUGCHECK_SECURSUP 0x000d
100 #define NPFS_BUGCHECK_SEINFO 0x000e
101 #define NPFS_BUGCHECK_STATESUP 0x000f
102 #define NPFS_BUGCHECK_STRUCSUP 0x0010
103 #define NPFS_BUGCHECK_VOLINFO 0x0011
104 #define NPFS_BUGCHECK_WAITSUP 0x0012
105 #define NPFS_BUGCHECK_WRITE 0x0013
106 #define NPFS_BUGCHECK_WRITESUP 0x0014
108 #define NpBugCheck(p1, p2, p3) \
109 KeBugCheckEx(NPFS_FILE_SYSTEM, \
110 (NPFS_BUGCHECK_FILE_ID << 16) | __LINE__, \
114 // Node Type Codes for NPFS
116 #define NPFS_NTC_VCB 1
117 #define NPFS_NTC_ROOT_DCB 2
118 #define NPFS_NTC_FCB 4
119 #define NPFS_NTC_CCB 6
120 #define NPFS_NTC_NONPAGED_CCB 7
121 #define NPFS_NTC_ROOT_DCB_CCB 8
122 typedef USHORT NODE_TYPE_CODE
, *PNODE_TYPE_CODE
;
127 typedef enum _NP_DATA_QUEUE_STATE
132 } NP_DATA_QUEUE_STATE
;
135 // Data Queue Entry Types
137 typedef enum _NP_DATA_QUEUE_ENTRY_TYPE
141 } NP_DATA_QUEUE_ENTRY_TYPE
;
144 // An Input or Output Data Queue. Each CCB has two of these.
146 typedef struct _NP_DATA_QUEUE
151 ULONG EntriesInQueue
;
155 } NP_DATA_QUEUE
, *PNP_DATA_QUEUE
;
158 // The Entries that go into the Queue
160 typedef struct _NP_DATA_QUEUE_ENTRY
162 LIST_ENTRY QueueEntry
;
166 PSECURITY_CLIENT_CONTEXT ClientSecurityContext
;
168 } NP_DATA_QUEUE_ENTRY
, *PNP_DATA_QUEUE_ENTRY
;
171 // A Wait Queue. Only the VCB has one of these.
173 typedef struct _NP_WAIT_QUEUE
177 } NP_WAIT_QUEUE
, *PNP_WAIT_QUEUE
;
180 // The Entries in the Queue above, one for each Waiter.
182 typedef struct _NP_WAIT_QUEUE_ENTRY
187 PNP_WAIT_QUEUE WaitQueue
;
188 UNICODE_STRING AliasName
;
189 PFILE_OBJECT FileObject
;
190 } NP_WAIT_QUEUE_ENTRY
, *PNP_WAIT_QUEUE_ENTRY
;
193 // The event buffer in the NonPaged CCB
195 typedef struct _NP_EVENT_BUFFER
198 } NP_EVENT_BUFFER
, *PNP_EVENT_BUFFER
;
201 // The CCB for the Root DCB
203 typedef struct _NP_ROOT_DCB_CCB
205 NODE_TYPE_CODE NodeType
;
208 } NP_ROOT_DCB_CCB
, *PNP_ROOT_DCB_FCB
;
211 // The header that both FCB and DCB share
213 typedef struct _NP_CB_HEADER
215 NODE_TYPE_CODE NodeType
;
218 ULONG CurrentInstances
;
219 ULONG ServerOpenCount
;
220 PSECURITY_DESCRIPTOR SecurityDescriptor
;
221 } NP_CB_HEADER
, *PNP_CB_HEADER
;
224 // The footer that both FCB and DCB share
226 typedef struct _NP_CB_FOOTER
228 UNICODE_STRING FullName
;
229 UNICODE_STRING ShortName
;
230 UNICODE_PREFIX_TABLE_ENTRY PrefixTableEntry
;
234 // A Directory Control Block (DCB)
236 typedef struct _NP_DCB
246 LIST_ENTRY NotifyList
;
247 LIST_ENTRY NotifyList2
;
260 // A File Control BLock (FCB)
262 typedef struct _NP_FCB
270 // FCB-specific fields
272 ULONG MaximumInstances
;
273 USHORT NamedPipeConfiguration
;
274 USHORT NamedPipeType
;
275 LARGE_INTEGER Timeout
;
287 C_ASSERT(FIELD_OFFSET(NP_FCB
, PrefixTableEntry
) == FIELD_OFFSET(NP_DCB
, PrefixTableEntry
));
290 // The nonpaged portion of the CCB
292 typedef struct _NP_NONPAGED_CCB
294 NODE_TYPE_CODE NodeType
;
295 PNP_EVENT_BUFFER EventBuffer
[2];
297 } NP_NONPAGED_CCB
, *PNP_NONPAGED_CCB
;
300 // A Client Control Block (CCB)
302 typedef struct _NP_CCB
304 NODE_TYPE_CODE NodeType
;
305 UCHAR NamedPipeState
;
307 UCHAR CompletionMode
[2];
308 SECURITY_QUALITY_OF_SERVICE ClientQos
;
311 PFILE_OBJECT FileObject
[2];
314 PNP_NONPAGED_CCB NonPagedCcb
;
315 NP_DATA_QUEUE DataQueue
[2];
316 PSECURITY_CLIENT_CONTEXT ClientContext
;
321 // A Volume Control Block (VCB)
323 typedef struct _NP_VCB
325 NODE_TYPE_CODE NodeType
;
326 ULONG ReferenceCount
;
328 UNICODE_PREFIX_TABLE PrefixTable
;
330 RTL_GENERIC_TABLE EventTable
;
331 NP_WAIT_QUEUE WaitQueue
;
334 extern PNP_VCB NpVcb
;
339 typedef struct _NPFS_ALIAS
341 struct _NPFS_ALIAS
*Next
;
342 PUNICODE_STRING TargetName
;
344 } NPFS_ALIAS
, *PNPFS_ALIAS
;
347 // Private structure used to enumerate the alias values
349 typedef struct _NPFS_QUERY_VALUE_CONTEXT
353 ULONG NumberOfAliases
;
354 ULONG NumberOfEntries
;
355 PNPFS_ALIAS CurrentAlias
;
356 PUNICODE_STRING CurrentTargetName
;
357 PWCHAR CurrentStringPointer
;
358 } NPFS_QUERY_VALUE_CONTEXT
, *PNPFS_QUERY_VALUE_CONTEXT
;
360 extern PNPFS_ALIAS NpAliasList
;
361 extern PNPFS_ALIAS NpAliasListByLength
[MAX_INDEXED_LENGTH
+ 1 - MIN_INDEXED_LENGTH
];
364 // This structure is actually a user-mode structure and should go into a share header
366 typedef struct _NP_CLIENT_PROCESS
372 } NP_CLIENT_PROCESS
, *PNP_CLIENT_PROCESS
;
375 /* FUNCTIONS ******************************************************************/
378 // Functions to lock/unlock the global VCB lock
382 NpAcquireSharedVcb(VOID
)
384 /* Acquire the lock in shared mode */
385 ExAcquireResourceSharedLite(&NpVcb
->Lock
, TRUE
);
390 NpAcquireExclusiveVcb(VOID
)
392 /* Acquire the lock in exclusive mode */
393 ExAcquireResourceExclusiveLite(&NpVcb
->Lock
, TRUE
);
400 /* Release the lock */
401 ExReleaseResourceLite(&NpVcb
->Lock
);
407 // Function to process deferred IRPs outside the VCB lock but still within the
412 NpCompleteDeferredIrps(IN PLIST_ENTRY DeferredList
)
414 PLIST_ENTRY ThisEntry
, NextEntry
;
418 ThisEntry
= DeferredList
->Flink
;
419 while (ThisEntry
!= DeferredList
)
421 /* Remember the next entry, but don't switch to it yet */
422 NextEntry
= ThisEntry
->Flink
;
424 /* Complete the IRP for this entry */
425 Irp
= CONTAINING_RECORD(ThisEntry
, IRP
, Tail
.Overlay
.ListEntry
);
426 IoCompleteRequest(Irp
, IO_NAMED_PIPE_INCREMENT
);
428 /* And now switch to the next one */
429 ThisEntry
= NextEntry
;
436 _In_ PCUNICODE_STRING String1
,
437 _In_ PCUNICODE_STRING String2
);
441 NpDeleteEventTableEntry(IN PRTL_GENERIC_TABLE Table
,
446 NpInitializeWaitQueue(IN PNP_WAIT_QUEUE WaitQueue
);
451 NpUninitializeDataQueue(IN PNP_DATA_QUEUE DataQueue
);
455 NpGetNextRealDataQueueEntry(IN PNP_DATA_QUEUE DataQueue
,
456 IN PLIST_ENTRY List
);
460 NpRemoveDataQueueEntry(IN PNP_DATA_QUEUE DataQueue
,
462 IN PLIST_ENTRY List
);
466 NpAddDataQueueEntry(IN ULONG NamedPipeEnd
,
468 IN PNP_DATA_QUEUE DataQueue
,
474 IN ULONG ByteOffset
);
478 NpCompleteStalledWrites(IN PNP_DATA_QUEUE DataQueue
,
479 IN PLIST_ENTRY List
);
483 NpInitializeDataQueue(IN PNP_DATA_QUEUE DataQueue
,
488 NpCreateCcb(IN PNP_FCB Fcb
,
489 IN PFILE_OBJECT FileObject
,
492 IN UCHAR CompletionMode
,
495 OUT PNP_CCB
*NewCcb
);
499 NpCreateFcb(IN PNP_DCB Dcb
,
500 IN PUNICODE_STRING PipeName
,
501 IN ULONG MaximumInstances
,
502 IN LARGE_INTEGER Timeout
,
503 IN USHORT NamedPipeConfiguration
,
504 IN USHORT NamedPipeType
,
505 OUT PNP_FCB
*NewFcb
);
509 NpCreateRootDcb(VOID
);
513 NpCreateRootDcbCcb(IN PNP_ROOT_DCB_FCB
*NewRootCcb
);
517 NpInitializeVcb(VOID
);
521 NpDeleteCcb(IN PNP_CCB Ccb
,
522 IN PLIST_ENTRY ListEntry
);
526 NpDeleteFcb(IN PNP_FCB Fcb
,
527 IN PLIST_ENTRY ListEntry
);
531 NpFsdCreateNamedPipe(IN PDEVICE_OBJECT DeviceObject
,
536 NpFsdCreate(IN PDEVICE_OBJECT DeviceObject
,
541 NpFsdClose(IN PDEVICE_OBJECT DeviceObject
,
547 NpFsdCleanup(IN PDEVICE_OBJECT DeviceObject
,
552 NpFsdFileSystemControl(IN PDEVICE_OBJECT DeviceObject
,
557 NpSetConnectedPipeState(IN PNP_CCB Ccb
,
558 IN PFILE_OBJECT FileObject
,
559 IN PLIST_ENTRY List
);
563 NpSetListeningPipeState(IN PNP_CCB Ccb
,
565 IN PLIST_ENTRY List
);
570 NpSetDisconnectedPipeState(IN PNP_CCB Ccb
,
571 IN PLIST_ENTRY List
);
575 NpSetClosingPipeState(IN PNP_CCB Ccb
,
577 IN ULONG NamedPipeEnd
,
578 IN PLIST_ENTRY List
);
582 NpFreeClientSecurityContext(IN PSECURITY_CLIENT_CONTEXT ClientContext
);
586 NpImpersonateClientContext(IN PNP_CCB Ccb
);
590 NpCopyClientContext(IN PNP_CCB Ccb
,
591 IN PNP_DATA_QUEUE_ENTRY DataQueueEntry
);
595 NpUninitializeSecurity(IN PNP_CCB Ccb
);
599 NpInitializeSecurity(IN PNP_CCB Ccb
,
600 IN PSECURITY_QUALITY_OF_SERVICE SecurityQos
,
605 NpGetClientSecurityContext(IN ULONG NamedPipeEnd
,
608 IN PSECURITY_CLIENT_CONTEXT
*Context
);
612 NpSetFileObject(IN PFILE_OBJECT FileObject
,
613 IN PVOID PrimaryContext
,
615 IN ULONG NamedPipeEnd
);
619 NpDecodeFileObject(IN PFILE_OBJECT FileObject
,
620 OUT PVOID
*PrimaryContext OPTIONAL
,
622 OUT PULONG NamedPipeEnd OPTIONAL
);
626 NpFindPrefix(IN PUNICODE_STRING Name
,
627 IN ULONG CaseInsensitiveIndex
,
628 IN PUNICODE_STRING Prefix
);
632 NpFindRelativePrefix(IN PNP_DCB Dcb
,
633 IN PUNICODE_STRING Name
,
634 IN ULONG CaseInsensitiveIndex
,
635 IN PUNICODE_STRING Prefix
,
636 OUT PNP_FCB
*FoundFcb
);
640 NpCheckForNotify(IN PNP_DCB Dcb
,
641 IN BOOLEAN SecondList
,
642 IN PLIST_ENTRY List
);
646 NpAddWaiter(IN PNP_WAIT_QUEUE WaitQueue
,
647 IN LARGE_INTEGER WaitTime
,
649 IN PUNICODE_STRING AliasName
);
653 NpCancelWaiter(IN PNP_WAIT_QUEUE WaitQueue
,
654 IN PUNICODE_STRING PipeName
,
656 IN PLIST_ENTRY ListEntry
);
661 NpReadDataQueue(IN PNP_DATA_QUEUE DataQueue
,
663 IN BOOLEAN ReadOverflowOperation
,
668 IN PLIST_ENTRY List
);
673 NpWriteDataQueue(IN PNP_DATA_QUEUE WriteQueue
,
676 IN ULONG OutBufferSize
,
678 OUT PULONG BytesWritten
,
680 IN ULONG NamedPipeEnd
,
682 IN PLIST_ENTRY List
);
686 NpFsdRead(IN PDEVICE_OBJECT DeviceObject
,
689 _Function_class_(FAST_IO_READ
)
694 _In_ PFILE_OBJECT FileObject
,
695 _In_ PLARGE_INTEGER FileOffset
,
700 _Out_ PIO_STATUS_BLOCK IoStatus
,
701 _In_ PDEVICE_OBJECT DeviceObject
);
703 _Function_class_(FAST_IO_WRITE
)
708 _In_ PFILE_OBJECT FileObject
,
709 _In_ PLARGE_INTEGER FileOffset
,
714 _Out_ PIO_STATUS_BLOCK IoStatus
,
715 _In_ PDEVICE_OBJECT DeviceObject
);
720 NpFsdWrite(IN PDEVICE_OBJECT DeviceObject
,
725 NpFsdFlushBuffers(IN PDEVICE_OBJECT DeviceObject
,
730 NpFsdSetInformation(IN PDEVICE_OBJECT DeviceObject
,
735 NpFsdQueryInformation(IN PDEVICE_OBJECT DeviceObject
,
741 NpFsdQuerySecurityInfo(IN PDEVICE_OBJECT DeviceObject
,
746 NpFsdSetSecurityInfo(IN PDEVICE_OBJECT DeviceObject
,
751 NpFsdQueryVolumeInformation(IN PDEVICE_OBJECT DeviceObject
,