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>
18 #define DPRINT1 DbgPrint
21 // Allow Microsoft Extensions
24 #pragma warning(disable:4201)
25 #pragma warning(disable:4214)
26 #pragma warning(disable:4100)
30 /* TYPEDEFS & DEFINES *********************************************************/
33 // Pool Tags for NPFS (from pooltag.txt)
35 // Npf* -npfs.sys - Npfs Allocations
36 // NpFc - npfs.sys - CCB, client control block
37 // NpFf - npfs.sys - FCB, file control block
38 // NpFC - npfs.sys - ROOT_DCB CCB
39 // NpFD - npfs.sys - DCB, directory block
40 // NpFg - npfs.sys - Global storage
41 // NpFi - npfs.sys - NPFS client info buffer.
42 // NpFn - npfs.sys - Name block
43 // NpFq - npfs.sys - Query template buffer used for directory query
44 // NpFr - npfs.sys - DATA_ENTRY records(read / write buffers)
45 // NpFs - npfs.sys - Client security context
46 // NpFw - npfs.sys - Write block
47 // NpFW - npfs.sys - Write block
48 #define NPFS_CCB_TAG 'NpFc'
49 #define NPFS_ROOT_DCB_CCB_TAG 'NpFC'
50 #define NPFS_DCB_TAG 'NpFD'
51 #define NPFS_FCB_TAG 'NpFf'
52 #define NPFS_GLOBAL_TAG 'NpFg'
53 #define NPFS_CLIENT_INFO_TAG 'NpFi'
54 #define NPFS_NAME_BLOCK_TAG 'NpFn'
55 #define NPFS_QUERY_TEMPLATE_TAG 'NpFq'
56 #define NPFS_DATA_ENTRY_TAG 'NpFr'
57 #define NPFS_CLIENT_SEC_CTX_TAG 'NpFs'
58 #define NPFS_WAIT_BLOCK_TAG 'NpFt'
59 #define NPFS_WRITE_BLOCK_TAG 'NpFw'
62 // NPFS bugchecking support
64 // We define the NpBugCheck macro which triggers a NPFS_FILE_SYSTEM bugcheck
65 // containing the source file ID number and the line where it was emitted, as
66 // described in the MSDN article "Bug Check 0x25: NPFS_FILE_SYSTEM".
68 // The bugcheck emits 4 ULONGs; the first one is made, in its high word, by
69 // the current source file ID and in its low word, by the line number; the
70 // three other ones are user-defined.
72 // In order to avoid redefinition of the same file ID in different source files,
73 // we gather all of them here, so that you will have to add (or remove) a new
74 // one as soon as you add (or remove) a source file from the NPFS driver code.
76 // To use the NpBugCheck macro in a source file, define at its beginning
77 // the constant NPFS_BUGCHECK_FILE_ID with one of the following file IDs,
78 // then use the bugcheck macro wherever you want.
80 #define NPFS_BUGCHECK_CLEANUP 0x0001
81 #define NPFS_BUGCHECK_CLOSE 0x0002
82 #define NPFS_BUGCHECK_CREATE 0x0003
83 #define NPFS_BUGCHECK_DATASUP 0x0004
84 #define NPFS_BUGCHECK_FILEINFO 0x0005
85 #define NPFS_BUGCHECK_FILEOBSUP 0x0006
86 #define NPFS_BUGCHECK_FLUSHBUF 0x0007
87 #define NPFS_BUGCHECK_FSCTRL 0x0008
88 #define NPFS_BUGCHECK_MAIN 0x0009
89 #define NPFS_BUGCHECK_PREFXSUP 0x000a
90 #define NPFS_BUGCHECK_READ 0x000b
91 #define NPFS_BUGCHECK_READSUP 0x000c
92 #define NPFS_BUGCHECK_SECURSUP 0x000d
93 #define NPFS_BUGCHECK_SEINFO 0x000e
94 #define NPFS_BUGCHECK_STATESUP 0x000f
95 #define NPFS_BUGCHECK_STRUCSUP 0x0010
96 #define NPFS_BUGCHECK_VOLINFO 0x0011
97 #define NPFS_BUGCHECK_WAITSUP 0x0012
98 #define NPFS_BUGCHECK_WRITE 0x0013
99 #define NPFS_BUGCHECK_WRITESUP 0x0014
101 #define NpBugCheck(p1, p2, p3) \
102 KeBugCheckEx(NPFS_FILE_SYSTEM, \
103 (NPFS_BUGCHECK_FILE_ID << 16) | __LINE__, \
107 // Node Type Codes for NPFS
109 #define NPFS_NTC_VCB 1
110 #define NPFS_NTC_ROOT_DCB 2
111 #define NPFS_NTC_FCB 4
112 #define NPFS_NTC_CCB 6
113 #define NPFS_NTC_NONPAGED_CCB 7
114 #define NPFS_NTC_ROOT_DCB_CCB 8
115 typedef USHORT NODE_TYPE_CODE
, *PNODE_TYPE_CODE
;
120 typedef enum _NP_DATA_QUEUE_STATE
125 } NP_DATA_QUEUE_STATE
;
128 // Data Queue Entry Types
130 typedef enum _NP_DATA_QUEUE_ENTRY_TYPE
134 } NP_DATA_QUEUE_ENTRY_TYPE
;
137 // An Input or Output Data Queue. Each CCB has two of these.
139 typedef struct _NP_DATA_QUEUE
144 ULONG EntriesInQueue
;
148 } NP_DATA_QUEUE
, *PNP_DATA_QUEUE
;
151 // The Entries that go into the Queue
153 typedef struct _NP_DATA_QUEUE_ENTRY
155 LIST_ENTRY QueueEntry
;
159 PSECURITY_CLIENT_CONTEXT ClientSecurityContext
;
161 } NP_DATA_QUEUE_ENTRY
, *PNP_DATA_QUEUE_ENTRY
;
164 // A Wait Queue. Only the VCB has one of these.
166 typedef struct _NP_WAIT_QUEUE
170 } NP_WAIT_QUEUE
, *PNP_WAIT_QUEUE
;
173 // The Entries in the Queue above, one for each Waiter.
175 typedef struct _NP_WAIT_QUEUE_ENTRY
180 PNP_WAIT_QUEUE WaitQueue
;
181 UNICODE_STRING AliasName
;
182 PFILE_OBJECT FileObject
;
183 } NP_WAIT_QUEUE_ENTRY
, *PNP_WAIT_QUEUE_ENTRY
;
186 // The event buffer in the NonPaged CCB
188 typedef struct _NP_EVENT_BUFFER
191 } NP_EVENT_BUFFER
, *PNP_EVENT_BUFFER
;
194 // The CCB for the Root DCB
196 typedef struct _NP_ROOT_DCB_CCB
198 NODE_TYPE_CODE NodeType
;
201 } NP_ROOT_DCB_CCB
, *PNP_ROOT_DCB_FCB
;
204 // The header that both FCB and DCB share
206 typedef struct _NP_CB_HEADER
208 NODE_TYPE_CODE NodeType
;
211 ULONG CurrentInstances
;
212 ULONG ServerOpenCount
;
213 PSECURITY_DESCRIPTOR SecurityDescriptor
;
214 } NP_CB_HEADER
, *PNP_CB_HEADER
;
217 // The footer that both FCB and DCB share
219 typedef struct _NP_CB_FOOTER
221 UNICODE_STRING FullName
;
222 UNICODE_STRING ShortName
;
223 UNICODE_PREFIX_TABLE_ENTRY PrefixTableEntry
;
227 // A Directory Control Block (DCB)
229 typedef struct _NP_DCB
239 LIST_ENTRY NotifyList
;
240 LIST_ENTRY NotifyList2
;
253 // A File Control BLock (FCB)
255 typedef struct _NP_FCB
263 // FCB-specific fields
265 ULONG MaximumInstances
;
266 USHORT NamedPipeConfiguration
;
267 USHORT NamedPipeType
;
268 LARGE_INTEGER Timeout
;
280 C_ASSERT(FIELD_OFFSET(NP_FCB
, PrefixTableEntry
) == FIELD_OFFSET(NP_DCB
, PrefixTableEntry
));
283 // The nonpaged portion of the CCB
285 typedef struct _NP_NONPAGED_CCB
287 NODE_TYPE_CODE NodeType
;
288 PNP_EVENT_BUFFER EventBuffer
[2];
290 } NP_NONPAGED_CCB
, *PNP_NONPAGED_CCB
;
293 // A Client Control Block (CCB)
295 typedef struct _NP_CCB
297 NODE_TYPE_CODE NodeType
;
298 UCHAR NamedPipeState
;
300 UCHAR CompletionMode
[2];
301 SECURITY_QUALITY_OF_SERVICE ClientQos
;
304 PFILE_OBJECT FileObject
[2];
307 PNP_NONPAGED_CCB NonPagedCcb
;
308 NP_DATA_QUEUE DataQueue
[2];
309 PSECURITY_CLIENT_CONTEXT ClientContext
;
314 // A Volume Control Block (VCB)
316 typedef struct _NP_VCB
318 NODE_TYPE_CODE NodeType
;
319 ULONG ReferenceCount
;
321 UNICODE_PREFIX_TABLE PrefixTable
;
323 RTL_GENERIC_TABLE EventTable
;
324 NP_WAIT_QUEUE WaitQueue
;
327 extern PNP_VCB NpVcb
;
330 /* FUNCTIONS ******************************************************************/
333 // Functions to lock/unlock the global VCB lock
337 NpAcquireSharedVcb(VOID
)
339 /* Acquire the lock in shared mode */
340 ExAcquireResourceSharedLite(&NpVcb
->Lock
, TRUE
);
345 NpAcquireExclusiveVcb(VOID
)
347 /* Acquire the lock in exclusive mode */
348 ExAcquireResourceExclusiveLite(&NpVcb
->Lock
, TRUE
);
355 /* Release the lock */
356 ExReleaseResourceLite(&NpVcb
->Lock
);
362 // Function to process deferred IRPs outside the VCB lock but still within the
367 NpCompleteDeferredIrps(IN PLIST_ENTRY DeferredList
)
369 PLIST_ENTRY ThisEntry
, NextEntry
;
373 ThisEntry
= DeferredList
->Flink
;
374 while (ThisEntry
!= DeferredList
)
376 /* Remember the next entry, but don't switch to it yet */
377 NextEntry
= ThisEntry
->Flink
;
379 /* Complete the IRP for this entry */
380 Irp
= CONTAINING_RECORD(ThisEntry
, IRP
, Tail
.Overlay
.ListEntry
);
381 IoCompleteRequest(Irp
, IO_NAMED_PIPE_INCREMENT
);
383 /* And now switch to the next one */
384 ThisEntry
= NextEntry
;
390 NpDeleteEventTableEntry(IN PRTL_GENERIC_TABLE Table
,
395 NpInitializeWaitQueue(IN PNP_WAIT_QUEUE WaitQueue
);
400 NpUninitializeDataQueue(IN PNP_DATA_QUEUE DataQueue
);
404 NpGetNextRealDataQueueEntry(IN PNP_DATA_QUEUE DataQueue
,
405 IN PLIST_ENTRY List
);
409 NpRemoveDataQueueEntry(IN PNP_DATA_QUEUE DataQueue
,
411 IN PLIST_ENTRY List
);
415 NpAddDataQueueEntry(IN ULONG NamedPipeEnd
,
417 IN PNP_DATA_QUEUE DataQueue
,
423 IN ULONG ByteOffset
);
427 NpCompleteStalledWrites(IN PNP_DATA_QUEUE DataQueue
,
428 IN PLIST_ENTRY List
);
432 NpInitializeDataQueue(IN PNP_DATA_QUEUE DataQueue
,
437 NpCreateCcb(IN PNP_FCB Fcb
,
438 IN PFILE_OBJECT FileObject
,
441 IN UCHAR CompletionMode
,
444 OUT PNP_CCB
*NewCcb
);
448 NpCreateFcb(IN PNP_DCB Dcb
,
449 IN PUNICODE_STRING PipeName
,
450 IN ULONG MaximumInstances
,
451 IN LARGE_INTEGER Timeout
,
452 IN USHORT NamedPipeConfiguration
,
453 IN USHORT NamedPipeType
,
454 OUT PNP_FCB
*NewFcb
);
458 NpCreateRootDcb(VOID
);
462 NpCreateRootDcbCcb(IN PNP_ROOT_DCB_FCB
*NewRootCcb
);
466 NpInitializeVcb(VOID
);
470 NpDeleteCcb(IN PNP_CCB Ccb
,
471 IN PLIST_ENTRY ListEntry
);
475 NpDeleteFcb(IN PNP_FCB Fcb
,
476 IN PLIST_ENTRY ListEntry
);
480 NpFsdCreateNamedPipe(IN PDEVICE_OBJECT DeviceObject
,
485 NpFsdCreate(IN PDEVICE_OBJECT DeviceObject
,
490 NpFsdClose(IN PDEVICE_OBJECT DeviceObject
,
496 NpFsdCleanup(IN PDEVICE_OBJECT DeviceObject
,
501 NpFsdFileSystemControl(IN PDEVICE_OBJECT DeviceObject
,
506 NpSetConnectedPipeState(IN PNP_CCB Ccb
,
507 IN PFILE_OBJECT FileObject
,
508 IN PLIST_ENTRY List
);
512 NpSetListeningPipeState(IN PNP_CCB Ccb
,
514 IN PLIST_ENTRY List
);
519 NpSetDisconnectedPipeState(IN PNP_CCB Ccb
,
520 IN PLIST_ENTRY List
);
524 NpSetClosingPipeState(IN PNP_CCB Ccb
,
526 IN ULONG NamedPipeEnd
,
527 IN PLIST_ENTRY List
);
531 NpFreeClientSecurityContext(IN PSECURITY_CLIENT_CONTEXT ClientContext
);
535 NpImpersonateClientContext(IN PNP_CCB Ccb
);
539 NpCopyClientContext(IN PNP_CCB Ccb
,
540 IN PNP_DATA_QUEUE_ENTRY DataQueueEntry
);
544 NpUninitializeSecurity(IN PNP_CCB Ccb
);
548 NpInitializeSecurity(IN PNP_CCB Ccb
,
549 IN PSECURITY_QUALITY_OF_SERVICE SecurityQos
,
554 NpGetClientSecurityContext(IN ULONG NamedPipeEnd
,
557 IN PSECURITY_CLIENT_CONTEXT
*Context
);
561 NpSetFileObject(IN PFILE_OBJECT FileObject
,
562 IN PVOID PrimaryContext
,
564 IN ULONG NamedPipeEnd
);
568 NpDecodeFileObject(IN PFILE_OBJECT FileObject
,
569 OUT PVOID
*PrimaryContext OPTIONAL
,
571 OUT PULONG NamedPipeEnd OPTIONAL
);
575 NpFindPrefix(IN PUNICODE_STRING Name
,
576 IN ULONG CaseInsensitiveIndex
,
577 IN PUNICODE_STRING Prefix
);
581 NpFindRelativePrefix(IN PNP_DCB Dcb
,
582 IN PUNICODE_STRING Name
,
583 IN ULONG CaseInsensitiveIndex
,
584 IN PUNICODE_STRING Prefix
,
585 OUT PNP_FCB
*FoundFcb
);
589 NpCheckForNotify(IN PNP_DCB Dcb
,
590 IN BOOLEAN SecondList
,
591 IN PLIST_ENTRY List
);
595 NpAddWaiter(IN PNP_WAIT_QUEUE WaitQueue
,
596 IN LARGE_INTEGER WaitTime
,
598 IN PUNICODE_STRING AliasName
);
602 NpCancelWaiter(IN PNP_WAIT_QUEUE WaitQueue
,
603 IN PUNICODE_STRING PipeName
,
605 IN PLIST_ENTRY ListEntry
);
610 NpReadDataQueue(IN PNP_DATA_QUEUE DataQueue
,
612 IN BOOLEAN ReadOverflowOperation
,
617 IN PLIST_ENTRY List
);
622 NpWriteDataQueue(IN PNP_DATA_QUEUE WriteQueue
,
625 IN ULONG OutBufferSize
,
627 OUT PULONG BytesWritten
,
629 IN ULONG NamedPipeEnd
,
631 IN PLIST_ENTRY List
);
635 NpFsdRead(IN PDEVICE_OBJECT DeviceObject
,
641 NpFsdWrite(IN PDEVICE_OBJECT DeviceObject
,
646 NpFsdFlushBuffers(IN PDEVICE_OBJECT DeviceObject
,
651 NpFsdSetInformation(IN PDEVICE_OBJECT DeviceObject
,
656 NpFsdQueryInformation(IN PDEVICE_OBJECT DeviceObject
,
662 NpFsdQuerySecurityInfo(IN PDEVICE_OBJECT DeviceObject
,
667 NpFsdSetSecurityInfo(IN PDEVICE_OBJECT DeviceObject
,
672 NpFsdQueryVolumeInformation(IN PDEVICE_OBJECT DeviceObject
,