77c7fceb19d085de208683bc4344872bc3b9de17
[reactos.git] / reactos / drivers / filesystems / npfs / npfs.h
1 /*
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
7 */
8
9 /* INCLUDES *******************************************************************/
10
11 //
12 // System Headers
13 //
14 #include <ntifs.h>
15 #include <ntndk.h>
16 #include <pseh/pseh2.h>
17 #define UNIMPLEMENTED
18 #define DPRINT1 DbgPrint
19
20 //
21 // Allow Microsoft Extensions
22 //
23 #ifdef _MSC_VER
24 #pragma warning(disable:4201)
25 #pragma warning(disable:4214)
26 #pragma warning(disable:4100)
27 #endif
28
29
30 /* TYPEDEFS & DEFINES *********************************************************/
31
32 //
33 // Pool Tags for NPFS (from pooltag.txt)
34 //
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'
60
61 //
62 // NPFS bugchecking support
63 //
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".
67 //
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.
71 //
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.
75 //
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.
79 //
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
100
101 #define NpBugCheck(p1, p2, p3) \
102 KeBugCheckEx(NPFS_FILE_SYSTEM, \
103 (NPFS_BUGCHECK_FILE_ID << 16) | __LINE__, \
104 (p1), (p2), (p3))
105
106 //
107 // Node Type Codes for NPFS
108 //
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;
116
117 //
118 // Data Queue States
119 //
120 typedef enum _NP_DATA_QUEUE_STATE
121 {
122 ReadEntries = 0,
123 WriteEntries = 1,
124 Empty = 2
125 } NP_DATA_QUEUE_STATE;
126
127 //
128 // Data Queue Entry Types
129 //
130 typedef enum _NP_DATA_QUEUE_ENTRY_TYPE
131 {
132 Buffered = 0,
133 Unbuffered
134 } NP_DATA_QUEUE_ENTRY_TYPE;
135
136 //
137 // An Input or Output Data Queue. Each CCB has two of these.
138 //
139 typedef struct _NP_DATA_QUEUE
140 {
141 LIST_ENTRY Queue;
142 ULONG QueueState;
143 ULONG BytesInQueue;
144 ULONG EntriesInQueue;
145 ULONG QuotaUsed;
146 ULONG ByteOffset;
147 ULONG Quota;
148 } NP_DATA_QUEUE, *PNP_DATA_QUEUE;
149
150 //
151 // The Entries that go into the Queue
152 //
153 typedef struct _NP_DATA_QUEUE_ENTRY
154 {
155 LIST_ENTRY QueueEntry;
156 ULONG DataEntryType;
157 PIRP Irp;
158 ULONG QuotaInEntry;
159 PSECURITY_CLIENT_CONTEXT ClientSecurityContext;
160 ULONG DataSize;
161 } NP_DATA_QUEUE_ENTRY, *PNP_DATA_QUEUE_ENTRY;
162
163 //
164 // A Wait Queue. Only the VCB has one of these.
165 //
166 typedef struct _NP_WAIT_QUEUE
167 {
168 LIST_ENTRY WaitList;
169 KSPIN_LOCK WaitLock;
170 } NP_WAIT_QUEUE, *PNP_WAIT_QUEUE;
171
172 //
173 // The Entries in the Queue above, one for each Waiter.
174 //
175 typedef struct _NP_WAIT_QUEUE_ENTRY
176 {
177 PIRP Irp;
178 KDPC Dpc;
179 KTIMER Timer;
180 PNP_WAIT_QUEUE WaitQueue;
181 UNICODE_STRING AliasName;
182 PFILE_OBJECT FileObject;
183 } NP_WAIT_QUEUE_ENTRY, *PNP_WAIT_QUEUE_ENTRY;
184
185 //
186 // The event buffer in the NonPaged CCB
187 //
188 typedef struct _NP_EVENT_BUFFER
189 {
190 PKEVENT Event;
191 } NP_EVENT_BUFFER, *PNP_EVENT_BUFFER;
192
193 //
194 // The CCB for the Root DCB
195 //
196 typedef struct _NP_ROOT_DCB_CCB
197 {
198 NODE_TYPE_CODE NodeType;
199 PVOID Unknown;
200 ULONG Unknown2;
201 } NP_ROOT_DCB_CCB, *PNP_ROOT_DCB_FCB;
202
203 //
204 // The header that both FCB and DCB share
205 //
206 typedef struct _NP_CB_HEADER
207 {
208 NODE_TYPE_CODE NodeType;
209 LIST_ENTRY DcbEntry;
210 PVOID ParentDcb;
211 ULONG CurrentInstances;
212 ULONG ServerOpenCount;
213 PSECURITY_DESCRIPTOR SecurityDescriptor;
214 } NP_CB_HEADER, *PNP_CB_HEADER;
215
216 //
217 // The footer that both FCB and DCB share
218 //
219 typedef struct _NP_CB_FOOTER
220 {
221 UNICODE_STRING FullName;
222 UNICODE_STRING ShortName;
223 UNICODE_PREFIX_TABLE_ENTRY PrefixTableEntry;
224 } NP_CB_FOOTER;
225
226 //
227 // A Directory Control Block (DCB)
228 //
229 typedef struct _NP_DCB
230 {
231 //
232 // Common Header
233 //
234 NP_CB_HEADER;
235
236 //
237 // DCB-specific data
238 //
239 LIST_ENTRY NotifyList;
240 LIST_ENTRY NotifyList2;
241 LIST_ENTRY FcbList;
242 #ifndef _WIN64
243 ULONG Pad;
244 #endif
245
246 //
247 // Common Footer
248 //
249 NP_CB_FOOTER;
250 } NP_DCB, *PNP_DCB;
251
252 //
253 // A File Control BLock (FCB)
254 //
255 typedef struct _NP_FCB
256 {
257 //
258 // Common Header
259 //
260 NP_CB_HEADER;
261
262 //
263 // FCB-specific fields
264 //
265 ULONG MaximumInstances;
266 USHORT NamedPipeConfiguration;
267 USHORT NamedPipeType;
268 LARGE_INTEGER Timeout;
269 LIST_ENTRY CcbList;
270 #ifdef _WIN64
271 PVOID Pad[2];
272 #endif
273
274 //
275 // Common Footer
276 //
277 NP_CB_FOOTER;
278 } NP_FCB, *PNP_FCB;
279
280 C_ASSERT(FIELD_OFFSET(NP_FCB, PrefixTableEntry) == FIELD_OFFSET(NP_DCB, PrefixTableEntry));
281
282 //
283 // The nonpaged portion of the CCB
284 //
285 typedef struct _NP_NONPAGED_CCB
286 {
287 NODE_TYPE_CODE NodeType;
288 PNP_EVENT_BUFFER EventBuffer[2];
289 ERESOURCE Lock;
290 } NP_NONPAGED_CCB, *PNP_NONPAGED_CCB;
291
292 //
293 // A Client Control Block (CCB)
294 //
295 typedef struct _NP_CCB
296 {
297 NODE_TYPE_CODE NodeType;
298 UCHAR NamedPipeState;
299 UCHAR ReadMode[2];
300 UCHAR CompletionMode[2];
301 SECURITY_QUALITY_OF_SERVICE ClientQos;
302 LIST_ENTRY CcbEntry;
303 PNP_FCB Fcb;
304 PFILE_OBJECT FileObject[2];
305 PEPROCESS Process;
306 PVOID ClientSession;
307 PNP_NONPAGED_CCB NonPagedCcb;
308 NP_DATA_QUEUE DataQueue[2];
309 PSECURITY_CLIENT_CONTEXT ClientContext;
310 LIST_ENTRY IrpList;
311 } NP_CCB, *PNP_CCB;
312
313 //
314 // A Volume Control Block (VCB)
315 //
316 typedef struct _NP_VCB
317 {
318 NODE_TYPE_CODE NodeType;
319 ULONG ReferenceCount;
320 PNP_DCB RootDcb;
321 UNICODE_PREFIX_TABLE PrefixTable;
322 ERESOURCE Lock;
323 RTL_GENERIC_TABLE EventTable;
324 NP_WAIT_QUEUE WaitQueue;
325 } NP_VCB, *PNP_VCB;
326
327 extern PNP_VCB NpVcb;
328
329
330 /* FUNCTIONS ******************************************************************/
331
332 //
333 // Functions to lock/unlock the global VCB lock
334 //
335 FORCEINLINE
336 VOID
337 NpAcquireSharedVcb(VOID)
338 {
339 /* Acquire the lock in shared mode */
340 ExAcquireResourceSharedLite(&NpVcb->Lock, TRUE);
341 }
342
343 FORCEINLINE
344 VOID
345 NpAcquireExclusiveVcb(VOID)
346 {
347 /* Acquire the lock in exclusive mode */
348 ExAcquireResourceExclusiveLite(&NpVcb->Lock, TRUE);
349 }
350
351 FORCEINLINE
352 VOID
353 NpReleaseVcb(VOID)
354 {
355 /* Release the lock */
356 ExReleaseResourceLite(&NpVcb->Lock);
357 }
358
359
360
361 //
362 // Function to process deferred IRPs outside the VCB lock but still within the
363 // critical region
364 //
365 VOID
366 FORCEINLINE
367 NpCompleteDeferredIrps(IN PLIST_ENTRY DeferredList)
368 {
369 PLIST_ENTRY ThisEntry, NextEntry;
370 PIRP Irp;
371
372 /* Loop the list */
373 ThisEntry = DeferredList->Flink;
374 while (ThisEntry != DeferredList)
375 {
376 /* Remember the next entry, but don't switch to it yet */
377 NextEntry = ThisEntry->Flink;
378
379 /* Complete the IRP for this entry */
380 Irp = CONTAINING_RECORD(ThisEntry, IRP, Tail.Overlay.ListEntry);
381 IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
382
383 /* And now switch to the next one */
384 ThisEntry = NextEntry;
385 }
386 }
387
388 BOOLEAN
389 NTAPI
390 NpDeleteEventTableEntry(IN PRTL_GENERIC_TABLE Table,
391 IN PVOID Buffer);
392
393 VOID
394 NTAPI
395 NpInitializeWaitQueue(IN PNP_WAIT_QUEUE WaitQueue);
396
397
398 NTSTATUS
399 NTAPI
400 NpUninitializeDataQueue(IN PNP_DATA_QUEUE DataQueue);
401
402 PLIST_ENTRY
403 NTAPI
404 NpGetNextRealDataQueueEntry(IN PNP_DATA_QUEUE DataQueue,
405 IN PLIST_ENTRY List);
406
407 PIRP
408 NTAPI
409 NpRemoveDataQueueEntry(IN PNP_DATA_QUEUE DataQueue,
410 IN BOOLEAN Flag,
411 IN PLIST_ENTRY List);
412
413 NTSTATUS
414 NTAPI
415 NpAddDataQueueEntry(IN ULONG NamedPipeEnd,
416 IN PNP_CCB Ccb,
417 IN PNP_DATA_QUEUE DataQueue,
418 IN ULONG Who,
419 IN ULONG Type,
420 IN ULONG DataSize,
421 IN PIRP Irp,
422 IN PVOID Buffer,
423 IN ULONG ByteOffset);
424
425 VOID
426 NTAPI
427 NpCompleteStalledWrites(IN PNP_DATA_QUEUE DataQueue,
428 IN PLIST_ENTRY List);
429
430 NTSTATUS
431 NTAPI
432 NpInitializeDataQueue(IN PNP_DATA_QUEUE DataQueue,
433 IN ULONG Quota);
434
435 NTSTATUS
436 NTAPI
437 NpCreateCcb(IN PNP_FCB Fcb,
438 IN PFILE_OBJECT FileObject,
439 IN UCHAR State,
440 IN UCHAR ReadMode,
441 IN UCHAR CompletionMode,
442 IN ULONG InQuota,
443 IN ULONG OutQuota,
444 OUT PNP_CCB *NewCcb);
445
446 NTSTATUS
447 NTAPI
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);
455
456 NTSTATUS
457 NTAPI
458 NpCreateRootDcb(VOID);
459
460 NTSTATUS
461 NTAPI
462 NpCreateRootDcbCcb(IN PNP_ROOT_DCB_FCB *NewRootCcb);
463
464 VOID
465 NTAPI
466 NpInitializeVcb(VOID);
467
468 VOID
469 NTAPI
470 NpDeleteCcb(IN PNP_CCB Ccb,
471 IN PLIST_ENTRY ListEntry);
472
473 VOID
474 NTAPI
475 NpDeleteFcb(IN PNP_FCB Fcb,
476 IN PLIST_ENTRY ListEntry);
477
478 NTSTATUS
479 NTAPI
480 NpFsdCreateNamedPipe(IN PDEVICE_OBJECT DeviceObject,
481 IN PIRP Irp);
482
483 NTSTATUS
484 NTAPI
485 NpFsdCreate(IN PDEVICE_OBJECT DeviceObject,
486 IN PIRP Irp);
487
488 NTSTATUS
489 NTAPI
490 NpFsdClose(IN PDEVICE_OBJECT DeviceObject,
491 IN PIRP Irp);
492
493
494 NTSTATUS
495 NTAPI
496 NpFsdCleanup(IN PDEVICE_OBJECT DeviceObject,
497 IN PIRP Irp);
498
499 NTSTATUS
500 NTAPI
501 NpFsdFileSystemControl(IN PDEVICE_OBJECT DeviceObject,
502 IN PIRP Irp);
503
504 NTSTATUS
505 NTAPI
506 NpSetConnectedPipeState(IN PNP_CCB Ccb,
507 IN PFILE_OBJECT FileObject,
508 IN PLIST_ENTRY List);
509
510 NTSTATUS
511 NTAPI
512 NpSetListeningPipeState(IN PNP_CCB Ccb,
513 IN PIRP Irp,
514 IN PLIST_ENTRY List);
515
516
517 NTSTATUS
518 NTAPI
519 NpSetDisconnectedPipeState(IN PNP_CCB Ccb,
520 IN PLIST_ENTRY List);
521
522 NTSTATUS
523 NTAPI
524 NpSetClosingPipeState(IN PNP_CCB Ccb,
525 IN PIRP Irp,
526 IN ULONG NamedPipeEnd,
527 IN PLIST_ENTRY List);
528
529 VOID
530 NTAPI
531 NpFreeClientSecurityContext(IN PSECURITY_CLIENT_CONTEXT ClientContext);
532
533 NTSTATUS
534 NTAPI
535 NpImpersonateClientContext(IN PNP_CCB Ccb);
536
537 VOID
538 NTAPI
539 NpCopyClientContext(IN PNP_CCB Ccb,
540 IN PNP_DATA_QUEUE_ENTRY DataQueueEntry);
541
542 VOID
543 NTAPI
544 NpUninitializeSecurity(IN PNP_CCB Ccb);
545
546 NTSTATUS
547 NTAPI
548 NpInitializeSecurity(IN PNP_CCB Ccb,
549 IN PSECURITY_QUALITY_OF_SERVICE SecurityQos,
550 IN PETHREAD Thread);
551
552 NTSTATUS
553 NTAPI
554 NpGetClientSecurityContext(IN ULONG NamedPipeEnd,
555 IN PNP_CCB Ccb,
556 IN PETHREAD Thread,
557 IN PSECURITY_CLIENT_CONTEXT *Context);
558
559 VOID
560 NTAPI
561 NpSetFileObject(IN PFILE_OBJECT FileObject,
562 IN PVOID PrimaryContext,
563 IN PVOID Ccb,
564 IN ULONG NamedPipeEnd);
565
566 NODE_TYPE_CODE
567 NTAPI
568 NpDecodeFileObject(IN PFILE_OBJECT FileObject,
569 OUT PVOID *PrimaryContext OPTIONAL,
570 OUT PNP_CCB *Ccb,
571 OUT PULONG NamedPipeEnd OPTIONAL);
572
573 PNP_FCB
574 NTAPI
575 NpFindPrefix(IN PUNICODE_STRING Name,
576 IN ULONG CaseInsensitiveIndex,
577 IN PUNICODE_STRING Prefix);
578
579 NTSTATUS
580 NTAPI
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);
586
587 VOID
588 NTAPI
589 NpCheckForNotify(IN PNP_DCB Dcb,
590 IN BOOLEAN SecondList,
591 IN PLIST_ENTRY List);
592
593 NTSTATUS
594 NTAPI
595 NpAddWaiter(IN PNP_WAIT_QUEUE WaitQueue,
596 IN LARGE_INTEGER WaitTime,
597 IN PIRP Irp,
598 IN PUNICODE_STRING AliasName);
599
600 NTSTATUS
601 NTAPI
602 NpCancelWaiter(IN PNP_WAIT_QUEUE WaitQueue,
603 IN PUNICODE_STRING PipeName,
604 IN NTSTATUS Status,
605 IN PLIST_ENTRY ListEntry);
606
607
608 IO_STATUS_BLOCK
609 NTAPI
610 NpReadDataQueue(IN PNP_DATA_QUEUE DataQueue,
611 IN BOOLEAN Peek,
612 IN BOOLEAN ReadOverflowOperation,
613 IN PVOID Buffer,
614 IN ULONG BufferSize,
615 IN ULONG Mode,
616 IN PNP_CCB Ccb,
617 IN PLIST_ENTRY List);
618
619
620 NTSTATUS
621 NTAPI
622 NpWriteDataQueue(IN PNP_DATA_QUEUE WriteQueue,
623 IN ULONG Mode,
624 IN PVOID OutBuffer,
625 IN ULONG OutBufferSize,
626 IN ULONG PipeType,
627 OUT PULONG BytesWritten,
628 IN PNP_CCB Ccb,
629 IN ULONG NamedPipeEnd,
630 IN PETHREAD Thread,
631 IN PLIST_ENTRY List);
632
633 NTSTATUS
634 NTAPI
635 NpFsdRead(IN PDEVICE_OBJECT DeviceObject,
636 IN PIRP Irp);
637
638
639 NTSTATUS
640 NTAPI
641 NpFsdWrite(IN PDEVICE_OBJECT DeviceObject,
642 IN PIRP Irp);
643
644 NTSTATUS
645 NTAPI
646 NpFsdFlushBuffers(IN PDEVICE_OBJECT DeviceObject,
647 IN PIRP Irp);
648
649 NTSTATUS
650 NTAPI
651 NpFsdSetInformation(IN PDEVICE_OBJECT DeviceObject,
652 IN PIRP Irp);
653
654 NTSTATUS
655 NTAPI
656 NpFsdQueryInformation(IN PDEVICE_OBJECT DeviceObject,
657 IN PIRP Irp);
658
659
660 NTSTATUS
661 NTAPI
662 NpFsdQuerySecurityInfo(IN PDEVICE_OBJECT DeviceObject,
663 IN PIRP Irp);
664
665 NTSTATUS
666 NTAPI
667 NpFsdSetSecurityInfo(IN PDEVICE_OBJECT DeviceObject,
668 IN PIRP Irp);
669
670 NTSTATUS
671 NTAPI
672 NpFsdQueryVolumeInformation(IN PDEVICE_OBJECT DeviceObject,
673 IN PIRP Irp);
674
675 /* EOF */