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
12 /* INCLUDES *******************************************************************/
16 #include <ndk/obfuncs.h>
17 #include <pseh/pseh2.h>
18 //#define UNIMPLEMENTED
19 //#define DPRINT1 DbgPrint
23 #define TRACE(...) /* DPRINT1("%s: ", __FUNCTION__); DbgPrint(__VA_ARGS__) */
25 /* Allow Microsoft Extensions */
27 #pragma warning(disable:4201)
28 #pragma warning(disable:4214)
29 #pragma warning(disable:4100)
32 #define MIN_INDEXED_LENGTH 5
33 #define MAX_INDEXED_LENGTH 9
35 /* TYPEDEFS & DEFINES *********************************************************/
38 // Pool Tags for NPFS (from pooltag.txt)
40 // Npf* -npfs.sys - Npfs Allocations
41 // NpFc - npfs.sys - CCB, client control block
42 // NpFf - npfs.sys - FCB, file control block
43 // NpFC - npfs.sys - ROOT_DCB CCB
44 // NpFD - npfs.sys - DCB, directory block
45 // NpFg - npfs.sys - Global storage
46 // NpFi - npfs.sys - NPFS client info buffer.
47 // NpFn - npfs.sys - Name block
48 // NpFq - npfs.sys - Query template buffer used for directory query
49 // NpFr - npfs.sys - DATA_ENTRY records(read / write buffers)
50 // NpFs - npfs.sys - Client security context
51 // NpFw - npfs.sys - Write block
52 // NpFW - npfs.sys - Write block
53 #define NPFS_CCB_TAG 'cFpN'
54 #define NPFS_ROOT_DCB_CCB_TAG 'CFpN'
55 #define NPFS_DCB_TAG 'DFpN'
56 #define NPFS_FCB_TAG 'fFpN'
57 #define NPFS_GLOBAL_TAG 'gFpN'
58 #define NPFS_CLIENT_INFO_TAG 'iFpN'
59 #define NPFS_NAME_BLOCK_TAG 'nFpN'
60 #define NPFS_QUERY_TEMPLATE_TAG 'qFpN'
61 #define NPFS_DATA_ENTRY_TAG 'rFpN'
62 #define NPFS_CLIENT_SEC_CTX_TAG 'sFpN'
63 #define NPFS_WAIT_BLOCK_TAG 'tFpN'
64 #define NPFS_WRITE_BLOCK_TAG 'wFpN'
67 // NPFS bugchecking support
69 // We define the NpBugCheck macro which triggers a NPFS_FILE_SYSTEM bugcheck
70 // containing the source file ID number and the line where it was emitted, as
71 // described in the MSDN article "Bug Check 0x25: NPFS_FILE_SYSTEM".
73 // The bugcheck emits 4 ULONGs; the first one is made, in its high word, by
74 // the current source file ID and in its low word, by the line number; the
75 // three other ones are user-defined.
77 // In order to avoid redefinition of the same file ID in different source files,
78 // we gather all of them here, so that you will have to add (or remove) a new
79 // one as soon as you add (or remove) a source file from the NPFS driver code.
81 // To use the NpBugCheck macro in a source file, define at its beginning
82 // the constant NPFS_BUGCHECK_FILE_ID with one of the following file IDs,
83 // then use the bugcheck macro wherever you want.
85 #define NPFS_BUGCHECK_CLEANUP 0x0001
86 #define NPFS_BUGCHECK_CLOSE 0x0002
87 #define NPFS_BUGCHECK_CREATE 0x0003
88 #define NPFS_BUGCHECK_DATASUP 0x0004
89 #define NPFS_BUGCHECK_FILEINFO 0x0005
90 #define NPFS_BUGCHECK_FILEOBSUP 0x0006
91 #define NPFS_BUGCHECK_FLUSHBUF 0x0007
92 #define NPFS_BUGCHECK_FSCTRL 0x0008
93 #define NPFS_BUGCHECK_MAIN 0x0009
94 #define NPFS_BUGCHECK_PREFXSUP 0x000a
95 #define NPFS_BUGCHECK_READ 0x000b
96 #define NPFS_BUGCHECK_READSUP 0x000c
97 #define NPFS_BUGCHECK_SECURSUP 0x000d
98 #define NPFS_BUGCHECK_SEINFO 0x000e
99 #define NPFS_BUGCHECK_STATESUP 0x000f
100 #define NPFS_BUGCHECK_STRUCSUP 0x0010
101 #define NPFS_BUGCHECK_VOLINFO 0x0011
102 #define NPFS_BUGCHECK_WAITSUP 0x0012
103 #define NPFS_BUGCHECK_WRITE 0x0013
104 #define NPFS_BUGCHECK_WRITESUP 0x0014
106 #define NpBugCheck(p1, p2, p3) \
107 KeBugCheckEx(NPFS_FILE_SYSTEM, \
108 (NPFS_BUGCHECK_FILE_ID << 16) | __LINE__, \
111 /* Node Type Codes for NPFS */
112 #define NPFS_NTC_VCB 1
113 #define NPFS_NTC_ROOT_DCB 2
114 #define NPFS_NTC_FCB 4
115 #define NPFS_NTC_CCB 6
116 #define NPFS_NTC_NONPAGED_CCB 7
117 #define NPFS_NTC_ROOT_DCB_CCB 8
118 typedef USHORT NODE_TYPE_CODE
, *PNODE_TYPE_CODE
;
120 /* Data Queue States */
121 typedef enum _NP_DATA_QUEUE_STATE
126 } NP_DATA_QUEUE_STATE
;
128 /* Data Queue Entry Types */
129 typedef enum _NP_DATA_QUEUE_ENTRY_TYPE
133 } NP_DATA_QUEUE_ENTRY_TYPE
;
135 /* An Input or Output Data Queue. Each CCB has two of these. */
136 typedef struct _NP_DATA_QUEUE
141 ULONG EntriesInQueue
;
145 } NP_DATA_QUEUE
, *PNP_DATA_QUEUE
;
147 /* The Entries that go into the Queue */
148 typedef struct _NP_DATA_QUEUE_ENTRY
150 LIST_ENTRY QueueEntry
;
154 PSECURITY_CLIENT_CONTEXT ClientSecurityContext
;
156 } NP_DATA_QUEUE_ENTRY
, *PNP_DATA_QUEUE_ENTRY
;
158 /* A Wait Queue. Only the VCB has one of these. */
159 typedef struct _NP_WAIT_QUEUE
163 } NP_WAIT_QUEUE
, *PNP_WAIT_QUEUE
;
165 /* The Entries in the Queue above, one for each Waiter. */
166 typedef struct _NP_WAIT_QUEUE_ENTRY
171 PNP_WAIT_QUEUE WaitQueue
;
172 UNICODE_STRING AliasName
;
173 PFILE_OBJECT FileObject
;
174 } NP_WAIT_QUEUE_ENTRY
, *PNP_WAIT_QUEUE_ENTRY
;
176 /* The event buffer in the NonPaged CCB */
177 typedef struct _NP_EVENT_BUFFER
180 } NP_EVENT_BUFFER
, *PNP_EVENT_BUFFER
;
182 /* The CCB for the Root DCB */
183 typedef struct _NP_ROOT_DCB_CCB
185 NODE_TYPE_CODE NodeType
;
188 } NP_ROOT_DCB_CCB
, *PNP_ROOT_DCB_FCB
;
190 /* The header that both FCB and DCB share */
191 typedef struct _NP_CB_HEADER
193 NODE_TYPE_CODE NodeType
;
196 ULONG CurrentInstances
;
197 ULONG ServerOpenCount
;
198 PSECURITY_DESCRIPTOR SecurityDescriptor
;
199 } NP_CB_HEADER
, *PNP_CB_HEADER
;
201 /* The footer that both FCB and DCB share */
202 typedef struct _NP_CB_FOOTER
204 UNICODE_STRING FullName
;
205 UNICODE_STRING ShortName
;
206 UNICODE_PREFIX_TABLE_ENTRY PrefixTableEntry
;
209 /* A Directory Control Block (DCB) */
210 typedef struct _NP_DCB
215 /* DCB-specific data */
216 LIST_ENTRY NotifyList
;
217 LIST_ENTRY NotifyList2
;
227 /* A File Control BLock (FCB) */
228 typedef struct _NP_FCB
233 /* FCB-specific fields */
234 ULONG MaximumInstances
;
235 USHORT NamedPipeConfiguration
;
236 USHORT NamedPipeType
;
237 LARGE_INTEGER Timeout
;
247 C_ASSERT(FIELD_OFFSET(NP_FCB
, PrefixTableEntry
) == FIELD_OFFSET(NP_DCB
, PrefixTableEntry
));
249 /* The nonpaged portion of the CCB */
250 typedef struct _NP_NONPAGED_CCB
252 NODE_TYPE_CODE NodeType
;
253 PNP_EVENT_BUFFER EventBuffer
[2];
255 } NP_NONPAGED_CCB
, *PNP_NONPAGED_CCB
;
257 /* A Client Control Block (CCB) */
258 typedef struct _NP_CCB
260 NODE_TYPE_CODE NodeType
;
261 UCHAR NamedPipeState
;
263 UCHAR CompletionMode
[2];
264 SECURITY_QUALITY_OF_SERVICE ClientQos
;
267 PFILE_OBJECT FileObject
[2];
270 PNP_NONPAGED_CCB NonPagedCcb
;
271 NP_DATA_QUEUE DataQueue
[2];
272 PSECURITY_CLIENT_CONTEXT ClientContext
;
276 /* A Volume Control Block (VCB) */
277 typedef struct _NP_VCB
279 NODE_TYPE_CODE NodeType
;
280 ULONG ReferenceCount
;
282 UNICODE_PREFIX_TABLE PrefixTable
;
284 RTL_GENERIC_TABLE EventTable
;
285 NP_WAIT_QUEUE WaitQueue
;
288 extern PNP_VCB NpVcb
;
290 /* Defines an alias */
291 typedef struct _NPFS_ALIAS
293 struct _NPFS_ALIAS
*Next
;
294 PUNICODE_STRING TargetName
;
296 } NPFS_ALIAS
, *PNPFS_ALIAS
;
298 /* Private structure used to enumerate the alias values */
299 typedef struct _NPFS_QUERY_VALUE_CONTEXT
303 ULONG NumberOfAliases
;
304 ULONG NumberOfEntries
;
305 PNPFS_ALIAS CurrentAlias
;
306 PUNICODE_STRING CurrentTargetName
;
307 PWCHAR CurrentStringPointer
;
308 } NPFS_QUERY_VALUE_CONTEXT
, *PNPFS_QUERY_VALUE_CONTEXT
;
310 extern PNPFS_ALIAS NpAliasList
;
311 extern PNPFS_ALIAS NpAliasListByLength
[MAX_INDEXED_LENGTH
+ 1 - MIN_INDEXED_LENGTH
];
313 /* This structure is actually a user-mode structure and should go into a share header */
314 typedef struct _NP_CLIENT_PROCESS
320 } NP_CLIENT_PROCESS
, *PNP_CLIENT_PROCESS
;
322 /* FUNCTIONS ******************************************************************/
324 /* Functions to lock/unlock the global VCB lock */
328 NpAcquireSharedVcb(VOID
)
330 /* Acquire the lock in shared mode */
331 ExAcquireResourceSharedLite(&NpVcb
->Lock
, TRUE
);
336 NpAcquireExclusiveVcb(VOID
)
338 /* Acquire the lock in exclusive mode */
339 ExAcquireResourceExclusiveLite(&NpVcb
->Lock
, TRUE
);
346 /* Release the lock */
347 ExReleaseResourceLite(&NpVcb
->Lock
);
351 // Function to process deferred IRPs outside the VCB lock but still within the
356 NpCompleteDeferredIrps(IN PLIST_ENTRY DeferredList
)
358 PLIST_ENTRY ThisEntry
, NextEntry
;
362 ThisEntry
= DeferredList
->Flink
;
363 while (ThisEntry
!= DeferredList
)
365 /* Remember the next entry, but don't switch to it yet */
366 NextEntry
= ThisEntry
->Flink
;
368 /* Complete the IRP for this entry */
369 Irp
= CONTAINING_RECORD(ThisEntry
, IRP
, Tail
.Overlay
.ListEntry
);
370 IoCompleteRequest(Irp
, IO_NAMED_PIPE_INCREMENT
);
372 /* And now switch to the next one */
373 ThisEntry
= NextEntry
;
380 _In_ PCUNICODE_STRING String1
,
381 _In_ PCUNICODE_STRING String2
);
385 NpDeleteEventTableEntry(IN PRTL_GENERIC_TABLE Table
,
390 NpInitializeWaitQueue(IN PNP_WAIT_QUEUE WaitQueue
);
394 NpUninitializeDataQueue(IN PNP_DATA_QUEUE DataQueue
);
398 NpGetNextRealDataQueueEntry(IN PNP_DATA_QUEUE DataQueue
,
399 IN PLIST_ENTRY List
);
403 NpRemoveDataQueueEntry(IN PNP_DATA_QUEUE DataQueue
,
405 IN PLIST_ENTRY List
);
409 NpAddDataQueueEntry(IN ULONG NamedPipeEnd
,
411 IN PNP_DATA_QUEUE DataQueue
,
417 IN ULONG ByteOffset
);
421 NpCompleteStalledWrites(IN PNP_DATA_QUEUE DataQueue
,
422 IN PLIST_ENTRY List
);
426 NpInitializeDataQueue(IN PNP_DATA_QUEUE DataQueue
,
431 NpCreateCcb(IN PNP_FCB Fcb
,
432 IN PFILE_OBJECT FileObject
,
435 IN UCHAR CompletionMode
,
438 OUT PNP_CCB
*NewCcb
);
442 NpCreateFcb(IN PNP_DCB Dcb
,
443 IN PUNICODE_STRING PipeName
,
444 IN ULONG MaximumInstances
,
445 IN LARGE_INTEGER Timeout
,
446 IN USHORT NamedPipeConfiguration
,
447 IN USHORT NamedPipeType
,
448 OUT PNP_FCB
*NewFcb
);
452 NpCreateRootDcb(VOID
);
456 NpCreateRootDcbCcb(IN PNP_ROOT_DCB_FCB
*NewRootCcb
);
460 NpInitializeVcb(VOID
);
464 NpDeleteCcb(IN PNP_CCB Ccb
,
465 IN PLIST_ENTRY ListEntry
);
469 NpDeleteFcb(IN PNP_FCB Fcb
,
470 IN PLIST_ENTRY ListEntry
);
474 NpFsdCreateNamedPipe(IN PDEVICE_OBJECT DeviceObject
,
479 NpFsdCreate(IN PDEVICE_OBJECT DeviceObject
,
484 NpFsdClose(IN PDEVICE_OBJECT DeviceObject
,
489 NpFsdCleanup(IN PDEVICE_OBJECT DeviceObject
,
494 NpFsdFileSystemControl(IN PDEVICE_OBJECT DeviceObject
,
499 NpSetConnectedPipeState(IN PNP_CCB Ccb
,
500 IN PFILE_OBJECT FileObject
,
501 IN PLIST_ENTRY List
);
505 NpSetListeningPipeState(IN PNP_CCB Ccb
,
507 IN PLIST_ENTRY List
);
511 NpSetDisconnectedPipeState(IN PNP_CCB Ccb
,
512 IN PLIST_ENTRY List
);
516 NpSetClosingPipeState(IN PNP_CCB Ccb
,
518 IN ULONG NamedPipeEnd
,
519 IN PLIST_ENTRY List
);
523 NpFreeClientSecurityContext(IN PSECURITY_CLIENT_CONTEXT ClientContext
);
527 NpImpersonateClientContext(IN PNP_CCB Ccb
);
531 NpCopyClientContext(IN PNP_CCB Ccb
,
532 IN PNP_DATA_QUEUE_ENTRY DataQueueEntry
);
536 NpUninitializeSecurity(IN PNP_CCB Ccb
);
540 NpInitializeSecurity(IN PNP_CCB Ccb
,
541 IN PSECURITY_QUALITY_OF_SERVICE SecurityQos
,
546 NpGetClientSecurityContext(IN ULONG NamedPipeEnd
,
549 IN PSECURITY_CLIENT_CONTEXT
*Context
);
553 NpSetFileObject(IN PFILE_OBJECT FileObject
,
554 IN PVOID PrimaryContext
,
556 IN ULONG NamedPipeEnd
);
560 NpDecodeFileObject(IN PFILE_OBJECT FileObject
,
561 OUT PVOID
*PrimaryContext OPTIONAL
,
563 OUT PULONG NamedPipeEnd OPTIONAL
);
567 NpFindPrefix(IN PUNICODE_STRING Name
,
568 IN ULONG CaseInsensitiveIndex
,
569 IN PUNICODE_STRING Prefix
);
573 NpFindRelativePrefix(IN PNP_DCB Dcb
,
574 IN PUNICODE_STRING Name
,
575 IN ULONG CaseInsensitiveIndex
,
576 IN PUNICODE_STRING Prefix
,
577 OUT PNP_FCB
*FoundFcb
);
581 NpCheckForNotify(IN PNP_DCB Dcb
,
582 IN BOOLEAN SecondList
,
583 IN PLIST_ENTRY List
);
587 NpAddWaiter(IN PNP_WAIT_QUEUE WaitQueue
,
588 IN LARGE_INTEGER WaitTime
,
590 IN PUNICODE_STRING AliasName
);
594 NpCancelWaiter(IN PNP_WAIT_QUEUE WaitQueue
,
595 IN PUNICODE_STRING PipeName
,
597 IN PLIST_ENTRY ListEntry
);
602 NpReadDataQueue(IN PNP_DATA_QUEUE DataQueue
,
604 IN BOOLEAN ReadOverflowOperation
,
609 IN PLIST_ENTRY List
);
614 NpWriteDataQueue(IN PNP_DATA_QUEUE WriteQueue
,
617 IN ULONG OutBufferSize
,
619 OUT PULONG BytesWritten
,
621 IN ULONG NamedPipeEnd
,
623 IN PLIST_ENTRY List
);
627 NpFsdRead(IN PDEVICE_OBJECT DeviceObject
,
630 _Function_class_(FAST_IO_READ
)
635 _In_ PFILE_OBJECT FileObject
,
636 _In_ PLARGE_INTEGER FileOffset
,
641 _Out_ PIO_STATUS_BLOCK IoStatus
,
642 _In_ PDEVICE_OBJECT DeviceObject
);
644 _Function_class_(FAST_IO_WRITE
)
649 _In_ PFILE_OBJECT FileObject
,
650 _In_ PLARGE_INTEGER FileOffset
,
655 _Out_ PIO_STATUS_BLOCK IoStatus
,
656 _In_ PDEVICE_OBJECT DeviceObject
);
661 NpFsdWrite(IN PDEVICE_OBJECT DeviceObject
,
666 NpFsdFlushBuffers(IN PDEVICE_OBJECT DeviceObject
,
671 NpFsdSetInformation(IN PDEVICE_OBJECT DeviceObject
,
676 NpFsdQueryInformation(IN PDEVICE_OBJECT DeviceObject
,
682 NpFsdQuerySecurityInfo(IN PDEVICE_OBJECT DeviceObject
,
687 NpFsdSetSecurityInfo(IN PDEVICE_OBJECT DeviceObject
,
692 NpFsdQueryVolumeInformation(IN PDEVICE_OBJECT DeviceObject
,
695 #endif /* _NPFS_PCH_ */