Remove unnecessary executable bits
[reactos.git] / drivers / filesystems / cdfs_new / cdprocs.h
1 /*++
2
3 Copyright (c) 1989-2000 Microsoft Corporation
4
5 Module Name:
6
7 CdProcs.h
8
9 Abstract:
10
11 This module defines all of the globally used procedures in the Cdfs
12 file system.
13
14
15 --*/
16
17 #ifndef _CDPROCS_
18 #define _CDPROCS_
19
20 #ifdef _MSC_VER
21 #pragma warning( disable: 4127 ) // conditional expression is constant
22
23 #pragma warning( push )
24 #pragma warning( disable: 4201 ) // nonstandard extension used : nameless struct/union
25 #pragma warning( disable: 4214 ) // nonstandard extension used : bit field types
26 #endif
27
28 #include <ntifs.h>
29
30 #include <ntddcdrm.h>
31 #include <ntdddisk.h>
32 #include <ntddscsi.h>
33 #ifdef __REACTOS__
34 #include <pseh/pseh2.h>
35 #endif
36
37 #ifndef INLINE
38 #define INLINE __inline
39 #endif
40
41 #include "nodetype.h"
42 #include "cd.h"
43 #include "cdstruc.h"
44 #include "cddata.h"
45
46 #ifdef CDFS_TELEMETRY_DATA
47
48 #include <winmeta.h>
49 #include <TraceLoggingProvider.h>
50 #include <telemetry\MicrosoftTelemetry.h>
51
52 #endif // CDFS_TELEMETRY_DATA
53
54 #ifdef _MSC_VER
55 #pragma warning( pop )
56 #endif
57
58 //**** x86 compiler bug ****
59
60 #if defined(_M_IX86)
61 #undef Int64ShraMod32
62 #define Int64ShraMod32(a, b) ((LONGLONG)(a) >> (b))
63 #endif
64
65 #ifndef Min
66 #define Min(a, b) ((a) < (b) ? (a) : (b))
67 #endif
68
69 #ifndef Max
70 #define Max(a, b) ((a) > (b) ? (a) : (b))
71 #endif
72
73 //
74 // Here are the different pool tags.
75 //
76
77 #define TAG_CCB 'ccdC' // Ccb
78 #define TAG_CDROM_TOC 'ctdC' // TOC
79 #define TAG_DIRENT_NAME 'nddC' // CdName in dirent
80 #define TAG_ENUM_EXPRESSION 'eedC' // Search expression for enumeration
81 #define TAG_FCB_DATA 'dfdC' // Data Fcb
82 #define TAG_FCB_INDEX 'ifdC' // Index Fcb
83 #define TAG_FCB_NONPAGED 'nfdC' // Nonpaged Fcb
84 #define TAG_FCB_TABLE 'tfdC' // Fcb Table entry
85 #define TAG_FILE_NAME 'nFdC' // Filename buffer
86 #define TAG_GEN_SHORT_NAME 'sgdC' // Generated short name
87 #define TAG_IO_BUFFER 'fbdC' // Temporary IO buffer
88 #define TAG_IO_CONTEXT 'oidC' // Io context for async reads
89 #define TAG_IRP_CONTEXT 'cidC' // Irp Context
90 #define TAG_IRP_CONTEXT_LITE 'lidC' // Irp Context lite
91 #define TAG_MCB_ARRAY 'amdC' // Mcb array
92 #define TAG_PATH_ENTRY_NAME 'nPdC' // CdName in path entry
93 #define TAG_PREFIX_ENTRY 'epdC' // Prefix Entry
94 #define TAG_PREFIX_NAME 'npdC' // Prefix Entry name
95 #define TAG_SPANNING_PATH_TABLE 'psdC' // Buffer for spanning path table
96 #define TAG_UPCASE_NAME 'nudC' // Buffer for upcased name
97 #define TAG_VOL_DESC 'dvdC' // Buffer for volume descriptor
98 #define TAG_VPB 'pvdC' // Vpb allocated in filesystem
99
100 //
101 // Tag all of our allocations if tagging is turned on
102 //
103
104 #ifdef POOL_TAGGING
105
106 #undef FsRtlAllocatePool
107 #undef FsRtlAllocatePoolWithQuota
108 #define FsRtlAllocatePool(a,b) FsRtlAllocatePoolWithTag(a,b,'sfdC')
109 #define FsRtlAllocatePoolWithQuota(a,b) FsRtlAllocatePoolWithQuotaTag(a,b,'sfdC')
110
111 #endif // POOL_TAGGING
112
113
114 //
115 // File access check routine, implemented in AcChkSup.c
116 //
117
118 //
119 // BOOLEAN
120 // CdIllegalFcbAccess (
121 // _In_ PIRP_CONTEXT IrpContext,
122 // _In_ TYPE_OF_OPEN TypeOfOpen,
123 // _In_ ACCESS_MASK DesiredAccess
124 // );
125 //
126
127 #define CdIllegalFcbAccess(IC,T,DA) ( \
128 BooleanFlagOn( (DA), \
129 ((T) != UserVolumeOpen ? \
130 (FILE_WRITE_ATTRIBUTES | \
131 FILE_WRITE_DATA | \
132 FILE_WRITE_EA | \
133 FILE_ADD_FILE | \
134 FILE_ADD_SUBDIRECTORY | \
135 FILE_APPEND_DATA) : 0) | \
136 FILE_DELETE_CHILD | \
137 DELETE | \
138 WRITE_DAC ))
139
140 \f
141 //
142 // Allocation support routines, implemented in AllocSup.c
143 //
144 // These routines are for querying allocation on individual streams.
145 //
146
147 _Requires_lock_held_(_Global_critical_region_)
148 VOID
149 CdLookupAllocation (
150 _In_ PIRP_CONTEXT IrpContext,
151 _In_ PFCB Fcb,
152 _In_ LONGLONG FileOffset,
153 _Out_ PLONGLONG DiskOffset,
154 _Out_ PULONG ByteCount
155 );
156
157 VOID
158 CdAddAllocationFromDirent (
159 _In_ PIRP_CONTEXT IrpContext,
160 _Inout_ PFCB Fcb,
161 _In_ ULONG McbEntryOffset,
162 _In_ LONGLONG StartingFileOffset,
163 _In_ PDIRENT Dirent
164 );
165
166 VOID
167 CdAddInitialAllocation (
168 _In_ PIRP_CONTEXT IrpContext,
169 _Inout_ PFCB Fcb,
170 _In_ ULONG StartingBlock,
171 _In_ LONGLONG DataLength
172 );
173
174 VOID
175 CdTruncateAllocation (
176 _In_ PIRP_CONTEXT IrpContext,
177 _Inout_ PFCB Fcb,
178 _In_ LONGLONG StartingFileOffset
179 );
180
181 _At_(Fcb->NodeByteSize, _In_range_(>=, FIELD_OFFSET( FCB, FcbType )))
182 VOID
183 CdInitializeMcb (
184 _In_ PIRP_CONTEXT IrpContext,
185 _Inout_updates_bytes_(Fcb->NodeByteSize) PFCB Fcb
186 );
187
188 _At_(Fcb->NodeByteSize, _In_range_(>=, FIELD_OFFSET( FCB, FcbType )))
189 _When_(Fcb->NodeTypeCode == CDFS_NTC_FCB_PATH_TABLE, _At_(Fcb->NodeByteSize, _In_range_(==, SIZEOF_FCB_INDEX)))
190 _When_(Fcb->NodeTypeCode == CDFS_NTC_FCB_INDEX, _At_(Fcb->NodeByteSize, _In_range_(==, SIZEOF_FCB_INDEX)))
191 _When_(Fcb->NodeTypeCode == CDFS_NTC_FCB_DATA, _At_(Fcb->NodeByteSize, _In_range_(==, SIZEOF_FCB_DATA)))
192 VOID
193 CdUninitializeMcb (
194 _In_ PIRP_CONTEXT IrpContext,
195 _Inout_updates_bytes_(Fcb->NodeByteSize) PFCB Fcb
196 );
197
198 \f
199 //
200 // Buffer control routines for data caching, implemented in CacheSup.c
201 //
202
203 VOID
204 CdCreateInternalStream (
205 _In_ PIRP_CONTEXT IrpContext,
206 _In_ PVCB Vcb,
207 _Inout_ PFCB Fcb,
208 _In_ PUNICODE_STRING Name
209 );
210
211 VOID
212 CdDeleteInternalStream (
213 _In_ PIRP_CONTEXT IrpContext,
214 _Inout_ PFCB Fcb
215 );
216
217 NTSTATUS
218 CdCompleteMdl (
219 _In_ PIRP_CONTEXT IrpContext,
220 _Inout_ PIRP Irp
221 );
222
223 _Requires_lock_held_(_Global_critical_region_)
224 NTSTATUS
225 CdPurgeVolume (
226 _In_ PIRP_CONTEXT IrpContext,
227 _In_ PVCB Vcb,
228 _In_ BOOLEAN DismountUnderway
229 );
230
231 static /* ReactOS Change: GCC "multiple definition" */
232 INLINE /* GCC only accepts __inline as the first modifier */
233 VOID
234 CdVerifyOrCreateDirStreamFile (
235 _In_ PIRP_CONTEXT IrpContext,
236 _In_ PFCB Fcb
237 )
238 {
239 //
240 // Unsafe test to see if call / lock neccessary.
241 //
242
243 if (NULL == Fcb->FileObject) {
244
245 CdCreateInternalStream( IrpContext,
246 Fcb->Vcb,
247 Fcb,
248 &Fcb->FileNamePrefix.ExactCaseName.FileName);
249 }
250 }
251
252
253 //
254 // VOID
255 // CdUnpinData (
256 // _In_ PIRP_CONTEXT IrpContext,
257 // _Inout_ PBCB *Bcb
258 // );
259 //
260
261 #define CdUnpinData(IC,B) \
262 if (*(B) != NULL) { CcUnpinData( *(B) ); *(B) = NULL; }
263
264 \f
265 //
266 // Device I/O routines, implemented in DevIoSup.c
267 //
268 // These routines perform the actual device read and writes. They only affect
269 // the on disk structure and do not alter any other data structures.
270 //
271
272 _Requires_lock_held_(_Global_critical_region_)
273 VOID
274 CdFreeDirCache (
275 _In_ PIRP_CONTEXT IrpContext
276 );
277
278 _Requires_lock_held_(_Global_critical_region_)
279 NTSTATUS
280 CdNonCachedRead (
281 _In_ PIRP_CONTEXT IrpContext,
282 _In_ PFCB Fcb,
283 _In_ LONGLONG StartingOffset,
284 _In_ ULONG ByteCount
285 );
286
287 _Requires_lock_held_(_Global_critical_region_)
288 NTSTATUS
289 CdNonCachedXARead (
290 _In_ PIRP_CONTEXT IrpContext,
291 _In_ PFCB Fcb,
292 _In_ LONGLONG StartingOffset,
293 _In_ ULONG ByteCount
294 );
295
296 _Requires_lock_held_(_Global_critical_region_)
297 NTSTATUS
298 CdVolumeDasdWrite (
299 _In_ PIRP_CONTEXT IrpContext,
300 _In_ PFCB Fcb,
301 _In_ LONGLONG StartingOffset,
302 _In_ ULONG ByteCount
303 );
304
305 BOOLEAN
306 CdReadSectors (
307 _In_ PIRP_CONTEXT IrpContext,
308 _In_ LONGLONG StartingOffset,
309 _In_ ULONG ByteCount,
310 _In_ BOOLEAN ReturnError,
311 _Out_writes_bytes_(ByteCount) PVOID Buffer,
312 _In_ PDEVICE_OBJECT TargetDeviceObject
313 );
314
315 NTSTATUS
316 CdCreateUserMdl (
317 _In_ PIRP_CONTEXT IrpContext,
318 _In_ ULONG BufferLength,
319 _In_ BOOLEAN RaiseOnError,
320 _In_ LOCK_OPERATION Operation
321 );
322
323 NTSTATUS
324 FASTCALL
325 CdPerformDevIoCtrl (
326 _In_ PIRP_CONTEXT IrpContext,
327 _In_ ULONG IoControlCode,
328 _In_ PDEVICE_OBJECT Device,
329 _Out_writes_bytes_opt_(OutputBufferLength) PVOID OutputBuffer,
330 _In_ ULONG OutputBufferLength,
331 _In_ BOOLEAN InternalDeviceIoControl,
332 _In_ BOOLEAN OverrideVerify,
333 _Out_opt_ PIO_STATUS_BLOCK Iosb
334 );
335
336 NTSTATUS
337 CdPerformDevIoCtrlEx (
338 _In_ PIRP_CONTEXT IrpContext,
339 _In_ ULONG IoControlCode,
340 _In_ PDEVICE_OBJECT Device,
341 _In_reads_bytes_opt_(InputBufferLength) PVOID InputBuffer,
342 _In_ ULONG InputBufferLength,
343 _Out_writes_bytes_opt_(OutputBufferLength) PVOID OutputBuffer,
344 _In_ ULONG OutputBufferLength,
345 _In_ BOOLEAN InternalDeviceIoControl,
346 _In_ BOOLEAN OverrideVerify,
347 _Out_opt_ PIO_STATUS_BLOCK Iosb
348 );
349
350 NTSTATUS
351 CdHijackIrpAndFlushDevice (
352 _In_ PIRP_CONTEXT IrpContext,
353 _Inout_ PIRP Irp,
354 _In_ PDEVICE_OBJECT TargetDeviceObject
355 );
356
357
358 //
359 // VOID
360 // CdMapUserBuffer (
361 // _In_ PIRP_CONTEXT IrpContext
362 // _Out_ PVOID UserBuffer
363 // );
364 //
365 // Returns pointer to sys address. Will raise on failure.
366 //
367 //
368 // VOID
369 // CdLockUserBuffer (
370 // _Inout_ PIRP_CONTEXT IrpContext,
371 // _In_ ULONG BufferLength
372 // );
373 //
374
375 #ifndef __REACTOS__
376 #define CdMapUserBuffer(IC, UB) { \
377 *(UB) = (PVOID) ( ((IC)->Irp->MdlAddress == NULL) ? \
378 (IC)->Irp->UserBuffer : \
379 (MmGetSystemAddressForMdlSafe( (IC)->Irp->MdlAddress, NormalPagePriority | MdlMappingNoExecute))); \
380 if (NULL == *(UB)) { \
381 CdRaiseStatus( (IC), STATUS_INSUFFICIENT_RESOURCES); \
382 } \
383 }
384
385 #else
386 #define CdMapUserBuffer(IC, UB) { \
387 *(UB) = (PVOID) ( ((IC)->Irp->MdlAddress == NULL) ? \
388 (IC)->Irp->UserBuffer : \
389 (MmGetSystemAddressForMdlSafe( (IC)->Irp->MdlAddress, NormalPagePriority))); \
390 if (NULL == *(UB)) { \
391 CdRaiseStatus( (IC), STATUS_INSUFFICIENT_RESOURCES); \
392 } \
393 }
394
395 #endif
396
397
398 #define CdLockUserBuffer(IC,BL,OP) { \
399 if ((IC)->Irp->MdlAddress == NULL) { \
400 (VOID) CdCreateUserMdl( (IC), (BL), TRUE, (OP) ); \
401 } \
402 }
403
404 \f
405 //
406 // Dirent support routines, implemented in DirSup.c
407 //
408
409 VOID
410 CdLookupDirent (
411 _In_ PIRP_CONTEXT IrpContext,
412 _In_ PFCB Fcb,
413 _In_ ULONG DirentOffset,
414 _Out_ PDIRENT_ENUM_CONTEXT DirContext
415 );
416
417 BOOLEAN
418 CdLookupNextDirent (
419 _In_ PIRP_CONTEXT IrpContext,
420 _In_ PFCB Fcb,
421 _In_ PDIRENT_ENUM_CONTEXT CurrentDirContext,
422 _Inout_ PDIRENT_ENUM_CONTEXT NextDirContext
423 );
424
425 _At_(Dirent->CdTime, _Post_notnull_)\f
426 VOID
427 CdUpdateDirentFromRawDirent (
428 _In_ PIRP_CONTEXT IrpContext,
429 _In_ PFCB Fcb,
430 _In_ PDIRENT_ENUM_CONTEXT DirContext,
431 _Inout_ PDIRENT Dirent
432 );
433
434 VOID
435 CdUpdateDirentName (
436 _In_ PIRP_CONTEXT IrpContext,
437 _Inout_ PDIRENT Dirent,
438 _In_ ULONG IgnoreCase
439 );
440
441 _Success_(return != FALSE) BOOLEAN
442 CdFindFile (
443 _In_ PIRP_CONTEXT IrpContext,
444 _In_ PFCB Fcb,
445 _In_ PCD_NAME Name,
446 _In_ BOOLEAN IgnoreCase,
447 _Inout_ PFILE_ENUM_CONTEXT FileContext,
448 _Out_ PCD_NAME *MatchingName
449 );
450
451 BOOLEAN
452 CdFindDirectory (
453 _In_ PIRP_CONTEXT IrpContext,
454 _In_ PFCB Fcb,
455 _In_ PCD_NAME Name,
456 _In_ BOOLEAN IgnoreCase,
457 _Inout_ PFILE_ENUM_CONTEXT FileContext
458 );
459
460 _At_(FileContext->ShortName.FileName.MaximumLength, _In_range_(>=, BYTE_COUNT_8_DOT_3))
461 BOOLEAN
462 CdFindFileByShortName (
463 _In_ PIRP_CONTEXT IrpContext,
464 _In_ PFCB Fcb,
465 _In_ PCD_NAME Name,
466 _In_ BOOLEAN IgnoreCase,
467 _In_ ULONG ShortNameDirentOffset,
468 _Inout_ PFILE_ENUM_CONTEXT FileContext
469 );
470
471 BOOLEAN
472 CdLookupNextInitialFileDirent (
473 _In_ PIRP_CONTEXT IrpContext,
474 _In_ PFCB Fcb,
475 _Inout_ PFILE_ENUM_CONTEXT FileContext
476 );
477
478 VOID
479 CdLookupLastFileDirent (
480 _In_ PIRP_CONTEXT IrpContext,
481 _In_ PFCB Fcb,
482 _In_ PFILE_ENUM_CONTEXT FileContext
483 );
484
485 VOID
486 CdCleanupFileContext (
487 _In_ PIRP_CONTEXT IrpContext,
488 _In_ PFILE_ENUM_CONTEXT FileContext
489 );
490
491 //
492 // VOID
493 // CdInitializeFileContext (
494 // _In_ PIRP_CONTEXT IrpContext,
495 // _Out_ PFILE_ENUM_CONTEXT FileContext
496 // );
497 //
498 //
499 // VOID
500 // CdInitializeDirent (
501 // _In_ PIRP_CONTEXT IrpContext,
502 // _Out_ PDIRENT Dirent
503 // );
504 //
505 // VOID
506 // CdInitializeDirContext (
507 // _In_ PIRP_CONTEXT IrpContext,
508 // _Out_ PDIRENT_ENUM_CONTEXT DirContext
509 // );
510 //
511 // VOID
512 // CdCleanupDirent (
513 // _In_ PIRP_CONTEXT IrpContext,
514 // _Inout_ PDIRENT Dirent
515 // );
516 //
517 // VOID
518 // CdCleanupDirContext (
519 // _In_ PIRP_CONTEXT IrpContext,
520 // _Inout_ PDIRENT_ENUM_CONTEXT DirContext
521 // );
522 //
523 // VOID
524 // CdLookupInitialFileDirent (
525 // _In_ PIRP_CONTEXT IrpContext,
526 // _In_ PFCB Fcb,
527 // _Out_ PFILE_ENUM_CONTEXT FileContext,
528 // _In_ ULONG DirentOffset
529 // );
530 //
531
532 #define CdInitializeFileContext(IC,FC) { \
533 RtlZeroMemory( FC, sizeof( FILE_ENUM_CONTEXT )); \
534 (FC)->PriorDirent = &(FC)->Dirents[0]; \
535 (FC)->InitialDirent = &(FC)->Dirents[1]; \
536 (FC)->CurrentDirent = &(FC)->Dirents[2]; \
537 (FC)->ShortName.FileName.MaximumLength = BYTE_COUNT_8_DOT_3; \
538 (FC)->ShortName.FileName.Buffer = (FC)->ShortNameBuffer; \
539 }
540
541 #define CdInitializeDirent(IC,D) \
542 RtlZeroMemory( D, sizeof( DIRENT ))
543
544 #define CdInitializeDirContext(IC,DC) \
545 RtlZeroMemory( DC, sizeof( DIRENT_ENUM_CONTEXT ))
546
547 #define CdCleanupDirent(IC,D) { \
548 if (FlagOn( (D)->Flags, DIRENT_FLAG_ALLOC_BUFFER )) { \
549 CdFreePool( &(D)->CdFileName.FileName.Buffer ); \
550 } \
551 }
552
553 #define CdCleanupDirContext(IC,DC) \
554 CdUnpinData( (IC), &(DC)->Bcb )
555
556 #define CdLookupInitialFileDirent(IC,F,FC,DO) \
557 CdLookupDirent( IC, \
558 F, \
559 DO, \
560 &(FC)->InitialDirent->DirContext ); \
561 CdUpdateDirentFromRawDirent( IC, \
562 F, \
563 &(FC)->InitialDirent->DirContext, \
564 &(FC)->InitialDirent->Dirent )
565
566 \f
567 //
568 // The following routines are used to manipulate the fscontext fields
569 // of the file object, implemented in FilObSup.c
570 //
571
572 //
573 // Type of opens. FilObSup.c depends on this order.
574 //
575
576 typedef enum _TYPE_OF_OPEN {
577
578 UnopenedFileObject = 0,
579 StreamFileOpen,
580 UserVolumeOpen,
581 UserDirectoryOpen,
582 UserFileOpen,
583 BeyondValidType
584
585 } TYPE_OF_OPEN;
586 typedef TYPE_OF_OPEN *PTYPE_OF_OPEN;
587
588 _When_(TypeOfOpen == UnopenedFileObject, _At_(Fcb, _In_opt_))
589 _When_(TypeOfOpen != UnopenedFileObject, _At_(Fcb, _In_))
590 VOID
591 CdSetFileObject (
592 _In_ PIRP_CONTEXT IrpContext,
593 _Inout_ PFILE_OBJECT FileObject,
594 _In_ TYPE_OF_OPEN TypeOfOpen,
595 PFCB Fcb,
596 _In_opt_ PCCB Ccb
597 );
598
599 _When_(return == UnopenedFileObject, _At_(*Fcb, _Post_null_))
600 _When_(return != UnopenedFileObject, _At_(Fcb, _Outptr_))
601 _When_(return == UnopenedFileObject, _At_(*Ccb, _Post_null_))
602 _When_(return != UnopenedFileObject, _At_(Ccb, _Outptr_))
603 TYPE_OF_OPEN
604 CdDecodeFileObject (
605 _In_ PIRP_CONTEXT IrpContext,
606 _In_ PFILE_OBJECT FileObject,
607 PFCB *Fcb,
608 PCCB *Ccb
609 );
610
611 TYPE_OF_OPEN
612 CdFastDecodeFileObject (
613 _In_ PFILE_OBJECT FileObject,
614 _Out_ PFCB *Fcb
615 );
616
617 \f
618 //
619 // Name support routines, implemented in NameSup.c
620 //
621
622 _Post_satisfies_(_Old_(CdName->FileName.Length) >=
623 CdName->FileName.Length + CdName->VersionString.Length)
624 VOID
625 CdConvertNameToCdName (
626 _In_ PIRP_CONTEXT IrpContext,
627 _Inout_ PCD_NAME CdName
628 );
629
630 VOID
631 CdConvertBigToLittleEndian (
632 _In_ PIRP_CONTEXT IrpContext,
633 _In_reads_bytes_(ByteCount) PCHAR BigEndian,
634 _In_ ULONG ByteCount,
635 _Out_writes_bytes_(ByteCount) PCHAR LittleEndian
636 );
637
638 VOID
639 CdUpcaseName (
640 _In_ PIRP_CONTEXT IrpContext,
641 _In_ PCD_NAME Name,
642 _Inout_ PCD_NAME UpcaseName
643 );
644
645 VOID
646 CdDissectName (
647 _In_ PIRP_CONTEXT IrpContext,
648 _Inout_ PUNICODE_STRING RemainingName,
649 _Out_ PUNICODE_STRING FinalName
650 );
651
652 BOOLEAN
653 CdIsLegalName (
654 _In_ PIRP_CONTEXT IrpContext,
655 _In_ PUNICODE_STRING FileName
656 );
657
658 BOOLEAN
659 CdIs8dot3Name (
660 _In_ PIRP_CONTEXT IrpContext,
661 _In_ UNICODE_STRING FileName
662 );
663
664 VOID
665 CdGenerate8dot3Name (
666 _In_ PIRP_CONTEXT IrpContext,
667 _In_ PUNICODE_STRING FileName,
668 _In_ ULONG DirentOffset,
669 _Out_writes_bytes_to_(BYTE_COUNT_8_DOT_3, *ShortByteCount) PWCHAR ShortFileName,
670 _Out_ PUSHORT ShortByteCount
671 );
672
673 BOOLEAN
674 CdIsNameInExpression (
675 _In_ PIRP_CONTEXT IrpContext,
676 _In_ PCD_NAME CurrentName,
677 _In_ PCD_NAME SearchExpression,
678 _In_ ULONG WildcardFlags,
679 _In_ BOOLEAN CheckVersion
680 );
681
682 ULONG
683 CdShortNameDirentOffset (
684 _In_ PIRP_CONTEXT IrpContext,
685 _In_ PUNICODE_STRING Name
686 );
687
688 FSRTL_COMPARISON_RESULT
689 CdFullCompareNames (
690 _In_ PIRP_CONTEXT IrpContext,
691 _In_ PUNICODE_STRING NameA,
692 _In_ PUNICODE_STRING NameB
693 );
694
695 \f
696 //
697 // Filesystem control operations. Implemented in Fsctrl.c
698 //
699
700 _Requires_lock_held_(_Global_critical_region_)
701 _Requires_lock_held_(Vcb->VcbResource)
702 NTSTATUS
703 CdLockVolumeInternal (
704 _In_ PIRP_CONTEXT IrpContext,
705 _Inout_ PVCB Vcb,
706 _In_opt_ PFILE_OBJECT FileObject
707 );
708
709 NTSTATUS
710 CdUnlockVolumeInternal (
711 _In_ PIRP_CONTEXT IrpContext,
712 _Inout_ PVCB Vcb,
713 _In_opt_ PFILE_OBJECT FileObject
714 );
715
716 \f
717 //
718 // Path table enumeration routines. Implemented in PathSup.c
719 //
720
721 VOID
722 CdLookupPathEntry (
723 _In_ PIRP_CONTEXT IrpContext,
724 _In_ ULONG PathEntryOffset,
725 _In_ ULONG Ordinal,
726 _In_ BOOLEAN VerifyBounds,
727 _Inout_ PCOMPOUND_PATH_ENTRY CompoundPathEntry
728 );
729
730 BOOLEAN
731 CdLookupNextPathEntry (
732 _In_ PIRP_CONTEXT IrpContext,
733 _Inout_ PPATH_ENUM_CONTEXT PathContext,
734 _Inout_ PPATH_ENTRY PathEntry
735 );
736
737 _Success_(return != FALSE)\f
738 BOOLEAN
739 CdFindPathEntry (
740 _In_ PIRP_CONTEXT IrpContext,
741 _In_ PFCB ParentFcb,
742 _In_ PCD_NAME DirName,
743 _In_ BOOLEAN IgnoreCase,
744 _Inout_ PCOMPOUND_PATH_ENTRY CompoundPathEntry
745 );
746
747 VOID
748 CdUpdatePathEntryName (
749 _In_ PIRP_CONTEXT IrpContext,
750 _Inout_ PPATH_ENTRY PathEntry,
751 _In_ BOOLEAN IgnoreCase
752 );
753
754 //
755 // VOID
756 // CdInitializeCompoundPathEntry (
757 // _In_ PIRP_CONTEXT IrpContext,
758 // _Out_ PCOMPOUND_PATH_ENTRY CompoundPathEntry
759 // );
760 //
761 // VOID
762 // CdCleanupCompoundPathEntry (
763 // _In_ PIRP_CONTEXT IrpContext,
764 // _Out_ PCOMPOUND_PATH_ENTRY CompoundPathEntry
765 // );
766 //
767
768 #define CdInitializeCompoundPathEntry(IC,CP) \
769 RtlZeroMemory( CP, sizeof( COMPOUND_PATH_ENTRY ))
770
771 #define CdCleanupCompoundPathEntry(IC,CP) { \
772 CdUnpinData( (IC), &(CP)->PathContext.Bcb ); \
773 if ((CP)->PathContext.AllocatedData) { \
774 CdFreePool( &(CP)->PathContext.Data ); \
775 } \
776 if (FlagOn( (CP)->PathEntry.Flags, PATH_ENTRY_FLAG_ALLOC_BUFFER )) { \
777 CdFreePool( &(CP)->PathEntry.CdDirName.FileName.Buffer ); \
778 } \
779 }
780
781 \f
782 //
783 // Largest matching prefix searching routines, implemented in PrefxSup.c
784 //
785
786 VOID
787 CdInsertPrefix (
788 _In_ PIRP_CONTEXT IrpContext,
789 _Inout_ PFCB Fcb,
790 _In_ PCD_NAME Name,
791 _In_ BOOLEAN IgnoreCase,
792 _In_ BOOLEAN ShortNameMatch,
793 _Inout_ PFCB ParentFcb
794 );
795
796 VOID
797 CdRemovePrefix (
798 _In_ PIRP_CONTEXT IrpContext,
799 _Inout_ PFCB Fcb
800 );
801
802 _Requires_lock_held_(_Global_critical_region_)
803 VOID
804 CdFindPrefix (
805 _In_ PIRP_CONTEXT IrpContext,
806 _Inout_ PFCB *CurrentFcb,
807 _Inout_ PUNICODE_STRING RemainingName,
808 _In_ BOOLEAN IgnoreCase
809 );
810
811 \f
812 //
813 // Synchronization routines. Implemented in Resrcsup.c
814 //
815 // The following routines/macros are used to synchronize the in-memory structures.
816 //
817 // Routine/Macro Synchronizes Subsequent
818 //
819 // CdAcquireCdData Volume Mounts/Dismounts,Vcb Queue CdReleaseCdData
820 // CdAcquireVcbExclusive Vcb for open/close CdReleaseVcb
821 // CdAcquireVcbShared Vcb for open/close CdReleaseVcb
822 // CdAcquireAllFiles Locks out operations to all files CdReleaseAllFiles
823 // CdAcquireFileExclusive Locks out file operations CdReleaseFile
824 // CdAcquireFileShared Files for file operations CdReleaseFile
825 // CdAcquireFcbExclusive Fcb for open/close CdReleaseFcb
826 // CdAcquireFcbShared Fcb for open/close CdReleaseFcb
827 // CdLockCdData Fields in CdData CdUnlockCdData
828 // CdLockVcb Vcb fields, FcbReference, FcbTable CdUnlockVcb
829 // CdLockFcb Fcb fields, prefix table, Mcb CdUnlockFcb
830 //
831
832 typedef enum _TYPE_OF_ACQUIRE {
833
834 AcquireExclusive,
835 AcquireShared,
836 AcquireSharedStarveExclusive
837
838 } TYPE_OF_ACQUIRE, *PTYPE_OF_ACQUIRE;
839
840 _Requires_lock_held_(_Global_critical_region_)
841 _When_(Type == AcquireExclusive && return != FALSE, _Acquires_exclusive_lock_(*Resource))
842 _When_(Type == AcquireShared && return != FALSE, _Acquires_shared_lock_(*Resource))
843 _When_(Type == AcquireSharedStarveExclusive && return != FALSE, _Acquires_shared_lock_(*Resource))
844 _When_(IgnoreWait == FALSE, _Post_satisfies_(return == TRUE))
845 BOOLEAN
846 CdAcquireResource (
847 _In_ PIRP_CONTEXT IrpContext,
848 _Inout_ PERESOURCE Resource,
849 _In_ BOOLEAN IgnoreWait,
850 _In_ TYPE_OF_ACQUIRE Type
851 );
852
853 //
854 // BOOLEAN
855 // CdAcquireCdData (
856 // _In_ PIRP_CONTEXT IrpContext
857 // );
858 //
859 // VOID
860 // CdReleaseCdData (
861 // _In_ PIRP_CONTEXT IrpContext
862 // );
863 //
864 // BOOLEAN
865 // CdAcquireVcbExclusive (
866 // _In_ PIRP_CONTEXT IrpContext,
867 // _Inout_ PVCB Vcb,
868 // _In_ BOOLEAN IgnoreWait
869 // );
870 //
871 // BOOLEAN
872 // CdAcquireVcbShared (
873 // _In_ PIRP_CONTEXT IrpContext,
874 // _Inout_ PVCB Vcb,
875 // _In_ BOOLEAN IgnoreWait
876 // );
877 //
878 // VOID
879 // CdReleaseVcb (
880 // _In_ PIRP_CONTEXT IrpContext,
881 // _Inout_ PVCB Vcb
882 // );
883 //
884 // VOID
885 // CdAcquireAllFiles (
886 // _In_ PIRP_CONTEXT,
887 // _In_ PVCB Vcb
888 // );
889 //
890 // VOID
891 // CdReleaseAllFiles (
892 // _In_ PIRP_CONTEXT,
893 // _In_ PVCB Vcb
894 // );
895 //
896 // VOID
897 // CdAcquireFileExclusive (
898 // _In_ PIRP_CONTEXT IrpContext,
899 // _Inout_ PFCB Fcb,
900 // );
901 //
902 // VOID
903 // CdAcquireFileShared (
904 // _In_ PIRP_CONTEXT IrpContext,
905 // _Inout_ PFCB Fcb
906 // );
907 //
908 // VOID
909 // CdReleaseFile (
910 // _In_ PIRP_CONTEXT IrpContext,
911 // _Inout_ PFCB Fcb
912 // );
913 //
914 // BOOLEAN
915 // CdAcquireFcbExclusive (
916 // _In_ PIRP_CONTEXT IrpContext,
917 // _Inout_ PFCB Fcb,
918 // _In_ BOOLEAN IgnoreWait
919 // );
920 //
921 // BOOLEAN
922 // CdAcquireFcbShared (
923 // _In_ PIRP_CONTEXT IrpContext,
924 // _Inout_ PFCB Fcb,
925 // _In_ BOOLEAN IgnoreWait
926 // );
927 //
928 // BOOLEAN
929 // CdReleaseFcb (
930 // _In_ PIRP_CONTEXT IrpContext,
931 // _Inout_ PFCB Fcb
932 // );
933 //
934 // VOID
935 // CdLockCdData (
936 // );
937 //
938 // VOID
939 // CdUnlockCdData (
940 // );
941 //
942 // VOID
943 // CdLockVcb (
944 // _In_ PIRP_CONTEXT IrpContext
945 // );
946 //
947 // VOID
948 // CdUnlockVcb (
949 // _In_ PIRP_CONTEXT IrpContext
950 // );
951 //
952 // VOID
953 // CdLockFcb (
954 // _In_ PIRP_CONTEXT IrpContext,
955 // _Inout_ PFCB Fcb
956 // );
957 //
958 // VOID
959 // CdUnlockFcb (
960 // _In_ PIRP_CONTEXT IrpContext,
961 // _Inout_ PFCB Fcb
962 // );
963 //
964
965
966 #define CdAcquireCacheForRead( IC) \
967 ExAcquireResourceSharedLite( &(IC)->Vcb->SectorCacheResource, TRUE)
968
969 #define CdAcquireCacheForUpdate( IC) \
970 ExAcquireResourceExclusiveLite( &(IC)->Vcb->SectorCacheResource, TRUE)
971
972 #define CdReleaseCache( IC) \
973 ExReleaseResourceLite( &(IC)->Vcb->SectorCacheResource);
974
975 #define CdConvertCacheToShared( IC) \
976 ExConvertExclusiveToSharedLite( &(IC)->Vcb->SectorCacheResource);
977
978 #define CdAcquireCdData(IC) \
979 ExAcquireResourceExclusiveLite( &CdData.DataResource, TRUE )
980
981 #define CdReleaseCdData(IC) \
982 ExReleaseResourceLite( &CdData.DataResource )
983
984 #define CdAcquireVcbExclusive(IC,V,I) \
985 CdAcquireResource( (IC), &(V)->VcbResource, (I), AcquireExclusive )
986
987 #define CdAcquireVcbShared(IC,V,I) \
988 CdAcquireResource( (IC), &(V)->VcbResource, (I), AcquireShared )
989
990 #define CdReleaseVcb(IC,V) \
991 ExReleaseResourceLite( &(V)->VcbResource )
992
993 #define CdAcquireAllFiles(IC,V) \
994 CdAcquireResource( (IC), &(V)->FileResource, FALSE, AcquireExclusive )
995
996 #define CdReleaseAllFiles(IC,V) \
997 ExReleaseResourceLite( &(V)->FileResource )
998
999 #define CdAcquireFileExclusive(IC,F) \
1000 CdAcquireResource( (IC), (F)->Resource, FALSE, AcquireExclusive )
1001
1002 #define CdAcquireFileShared(IC,F) \
1003 CdAcquireResource( (IC), (F)->Resource, FALSE, AcquireShared )
1004
1005 #define CdAcquireFileSharedStarveExclusive(IC,F) \
1006 CdAcquireResource( (IC), (F)->Resource, FALSE, AcquireSharedStarveExclusive )
1007
1008 #define CdReleaseFile(IC,F) \
1009 ExReleaseResourceLite( (F)->Resource )
1010
1011 #define CdAcquireFcbExclusive(IC,F,I) \
1012 CdAcquireResource( (IC), &(F)->FcbNonpaged->FcbResource, (I), AcquireExclusive )
1013
1014 #define CdAcquireFcbShared(IC,F,I) \
1015 CdAcquireResource( (IC), &(F)->FcbNonpaged->FcbResource, (I), AcquireShared )
1016
1017 #define CdReleaseFcb(IC,F) \
1018 ExReleaseResourceLite( &(F)->FcbNonpaged->FcbResource )
1019
1020 #define CdLockCdData() \
1021 ExAcquireFastMutex( &CdData.CdDataMutex ); \
1022 CdData.CdDataLockThread = PsGetCurrentThread()
1023
1024 #define CdUnlockCdData() \
1025 CdData.CdDataLockThread = NULL; \
1026 ExReleaseFastMutex( &CdData.CdDataMutex )
1027
1028 #define CdLockVcb(IC,V) \
1029 ExAcquireFastMutex( &(V)->VcbMutex ); \
1030 NT_ASSERT( NULL == (V)->VcbLockThread); \
1031 (V)->VcbLockThread = PsGetCurrentThread()
1032
1033 #define CdUnlockVcb(IC,V) \
1034 NT_ASSERT( NULL != (V)->VcbLockThread); \
1035 (V)->VcbLockThread = NULL; \
1036 ExReleaseFastMutex( &(V)->VcbMutex )
1037
1038 #if defined(_PREFAST_)
1039
1040 _Success_(return)
1041 _IRQL_saves_global_(OldIrql, FastMutex)
1042 BOOLEAN DummySaveIrql(_Inout_ PFAST_MUTEX FastMutex);
1043
1044 _Success_(return)
1045 _IRQL_restores_global_(OldIrql, FastMutex)
1046 BOOLEAN DummyRestoreIrql(_Inout_ PFAST_MUTEX FastMutex);
1047 #endif // _PREFAST_
1048
1049 #define CdLockFcb(IC,F) { \
1050 PVOID _CurrentThread = PsGetCurrentThread(); \
1051 if (_CurrentThread != (F)->FcbLockThread) { \
1052 ExAcquireFastMutex( &(F)->FcbNonpaged->FcbMutex ); \
1053 NT_ASSERT( (F)->FcbLockCount == 0 ); \
1054 _Analysis_assume_( (F)->FcbLockCount == 0 ); \
1055 (F)->FcbLockThread = _CurrentThread; \
1056 } \
1057 else \
1058 { \
1059 _Analysis_assume_lock_held_( (F)->FcbNonpaged->FcbMutex ); \
1060 _Analysis_assume_(FALSE != DummySaveIrql(&(F)->FcbNonpaged->FcbMutex)); \
1061 } \
1062 (F)->FcbLockCount += 1; \
1063 }
1064
1065 #define CdUnlockFcb(IC,F) { \
1066 (F)->FcbLockCount -= 1; \
1067 if ((F)->FcbLockCount == 0) { \
1068 (F)->FcbLockThread = NULL; \
1069 ExReleaseFastMutex( &(F)->FcbNonpaged->FcbMutex ); \
1070 } \
1071 else \
1072 { \
1073 _Analysis_assume_lock_not_held_( (F)->FcbNonpaged->FcbMutex ); \
1074 _Analysis_assume_(FALSE != DummyRestoreIrql(&(F)->FcbNonpaged->FcbMutex)); \
1075 } \
1076 }
1077
1078 //
1079 // The following macro is used to retrieve the oplock structure within
1080 // the Fcb. This structure was moved to the advanced Fcb header
1081 // in Win8.
1082 //
1083
1084 #if (NTDDI_VERSION >= NTDDI_WIN8)
1085
1086 #define CdGetFcbOplock(F) &(F)->Header.Oplock
1087
1088 #else
1089
1090 #define CdGetFcbOplock(F) &(F)->Oplock
1091
1092 #endif
1093
1094 BOOLEAN
1095 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
1096 CdNoopAcquire (
1097 _In_ PVOID Fcb,
1098 _In_ BOOLEAN Wait
1099 );
1100
1101 VOID
1102 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
1103 CdNoopRelease (
1104 _In_ PVOID Fcb
1105 );
1106
1107 _Requires_lock_held_(_Global_critical_region_)
1108 _When_(return!=0, _Acquires_shared_lock_(*Fcb->Resource))
1109 BOOLEAN
1110 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
1111 CdAcquireForCache (
1112 _Inout_ PFCB Fcb,
1113 _In_ BOOLEAN Wait
1114 );
1115
1116 _Requires_lock_held_(_Global_critical_region_)
1117 _Releases_lock_(*Fcb->Resource)
1118 VOID
1119 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
1120 CdReleaseFromCache (
1121 _Inout_ PFCB Fcb
1122 );
1123
1124 _Requires_lock_held_(_Global_critical_region_)
1125 NTSTATUS
1126 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
1127 CdFilterCallbackAcquireForCreateSection (
1128 _In_ PFS_FILTER_CALLBACK_DATA CallbackData,
1129 _Unreferenced_parameter_ PVOID *CompletionContext
1130 );
1131
1132 _Function_class_(FAST_IO_RELEASE_FILE)
1133 _Requires_lock_held_(_Global_critical_region_)
1134 VOID
1135 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
1136 CdReleaseForCreateSection (
1137 _In_ PFILE_OBJECT FileObject
1138 );
1139
1140 \f
1141 //
1142 // In-memory structure support routines. Implemented in StrucSup.c
1143 //
1144
1145 VOID
1146 CdInitializeVcb (
1147 _In_ PIRP_CONTEXT IrpContext,
1148 _Inout_ PVCB Vcb,
1149 _In_ __drv_aliasesMem PDEVICE_OBJECT TargetDeviceObject,
1150 _In_ __drv_aliasesMem PVPB Vpb,
1151 _In_ __drv_aliasesMem PCDROM_TOC_LARGE CdromToc,
1152 _In_ ULONG TocLength,
1153 _In_ ULONG TocTrackCount,
1154 _In_ ULONG TocDiskFlags,
1155 _In_ ULONG BlockFactor,
1156 _In_ ULONG MediaChangeCount
1157 );
1158
1159 VOID
1160 CdUpdateVcbFromVolDescriptor (
1161 _In_ PIRP_CONTEXT IrpContext,
1162 _Inout_ PVCB Vcb,
1163 _In_reads_bytes_opt_(SECTOR_SIZE) PCHAR RawIsoVd
1164 );
1165
1166 VOID
1167 CdDeleteVcb (
1168 _In_ PIRP_CONTEXT IrpContext,
1169 _Inout_ PVCB Vcb
1170 );
1171
1172 PFCB
1173 CdCreateFcb (
1174 _In_ PIRP_CONTEXT IrpContext,
1175 _In_ FILE_ID FileId,
1176 _In_ NODE_TYPE_CODE NodeTypeCode,
1177 _Out_opt_ PBOOLEAN FcbExisted
1178 );
1179
1180 VOID
1181 CdInitializeFcbFromPathEntry (
1182 _In_ PIRP_CONTEXT IrpContext,
1183 _Inout_ PFCB Fcb,
1184 _In_opt_ PFCB ParentFcb,
1185 _In_ PPATH_ENTRY PathEntry
1186 );
1187
1188 VOID
1189 CdInitializeFcbFromFileContext (
1190 _In_ PIRP_CONTEXT IrpContext,
1191 _Inout_ PFCB Fcb,
1192 _In_ PFCB ParentFcb,
1193 _In_ PFILE_ENUM_CONTEXT FileContext
1194 );
1195
1196 PCCB
1197 CdCreateCcb (
1198 _In_ PIRP_CONTEXT IrpContext,
1199 _In_ PFCB Fcb,
1200 _In_ ULONG Flags
1201 );
1202
1203 VOID
1204 CdDeleteCcb (
1205 _In_ PIRP_CONTEXT IrpContext,
1206 _In_ __drv_freesMem( Pool ) PCCB Ccb
1207 );
1208
1209 _When_(RaiseOnError || return, _At_(Fcb->FileLock, _Post_notnull_))
1210 _When_(RaiseOnError, _At_(IrpContext, _Pre_notnull_))
1211 BOOLEAN
1212 CdCreateFileLock (
1213 _In_opt_ PIRP_CONTEXT IrpContext,
1214 _Inout_ PFCB Fcb,
1215 _In_ BOOLEAN RaiseOnError
1216 );
1217
1218 VOID
1219 CdDeleteFileLock (
1220 _In_ PIRP_CONTEXT IrpContext,
1221 _Inout_ PFILE_LOCK FileLock
1222 );
1223
1224 _Ret_valid_ PIRP_CONTEXT
1225 CdCreateIrpContext (
1226 _In_ PIRP Irp,
1227 _In_ BOOLEAN Wait
1228 );
1229
1230 VOID
1231 CdCleanupIrpContext (
1232 _In_ PIRP_CONTEXT IrpContext,
1233 _In_ BOOLEAN Post
1234 );
1235
1236 VOID
1237 CdInitializeStackIrpContext (
1238 _Out_ PIRP_CONTEXT IrpContext,
1239 _In_ PIRP_CONTEXT_LITE IrpContextLite
1240 );
1241
1242 //
1243 // PIRP_CONTEXT_LITE
1244 // CdCreateIrpContextLite (
1245 // _In_ PIRP_CONTEXT IrpContext
1246 // );
1247 //
1248 // VOID
1249 // CdFreeIrpContextLite (
1250 // _Inout_ PIRP_CONTEXT_LITE IrpContextLite
1251 // );
1252 //
1253
1254 #define CdCreateIrpContextLite(IC) \
1255 ExAllocatePoolWithTag( CdNonPagedPool, sizeof( IRP_CONTEXT_LITE ), TAG_IRP_CONTEXT_LITE )
1256
1257 #define CdFreeIrpContextLite(ICL) \
1258 CdFreePool( &(ICL) )
1259
1260 _Requires_lock_held_(_Global_critical_region_)
1261 VOID
1262 CdTeardownStructures (
1263 _In_ PIRP_CONTEXT IrpContext,
1264 _Inout_ PFCB StartingFcb,
1265 _Out_ PBOOLEAN RemovedStartingFcb
1266 );
1267
1268 //
1269 // VOID
1270 // CdIncrementCleanupCounts (
1271 // _In_ PIRP_CONTEXT IrpContext,
1272 // _Inout_ PFCB Fcb
1273 // );
1274 //
1275 // VOID
1276 // CdDecrementCleanupCounts (
1277 // _In_ PIRP_CONTEXT IrpContext,
1278 // _Inout_ PFCB Fcb
1279 // );
1280 //
1281 // VOID
1282 // CdIncrementReferenceCounts (
1283 // _In_ PIRP_CONTEXT IrpContext,
1284 // _Inout_ PFCB Fcb,
1285 // _In_ ULONG ReferenceCount
1286 // _In_ ULONG UserReferenceCount
1287 // );
1288 //
1289 // VOID
1290 // CdDecrementReferenceCounts (
1291 // _In_ PIRP_CONTEXT IrpContext,
1292 // _Inout_ PFCB Fcb,
1293 // _In_ ULONG ReferenceCount
1294 // _In_ ULONG UserReferenceCount
1295 // );
1296 //
1297 // VOID
1298 // CdIncrementFcbReference (
1299 // _In_ PIRP_CONTEXT IrpContext,
1300 // _Inout_ PFCB Fcb
1301 // );
1302 //
1303 // VOID
1304 // CdDecrementFcbReference (
1305 // _In_ PIRP_CONTEXT IrpContext,
1306 // _Inout_ PFCB Fcb
1307 // );
1308 //
1309
1310 #define CdIncrementCleanupCounts(IC,F) { \
1311 ASSERT_LOCKED_VCB( (F)->Vcb ); \
1312 (F)->FcbCleanup += 1; \
1313 (F)->Vcb->VcbCleanup += 1; \
1314 }
1315
1316 #define CdDecrementCleanupCounts(IC,F) { \
1317 ASSERT_LOCKED_VCB( (F)->Vcb ); \
1318 (F)->FcbCleanup -= 1; \
1319 (F)->Vcb->VcbCleanup -= 1; \
1320 }
1321
1322 #define CdIncrementReferenceCounts(IC,F,C,UC) { \
1323 ASSERT_LOCKED_VCB( (F)->Vcb ); \
1324 (F)->FcbReference += (C); \
1325 (F)->FcbUserReference += (UC); \
1326 (F)->Vcb->VcbReference += (C); \
1327 (F)->Vcb->VcbUserReference += (UC); \
1328 }
1329
1330 #define CdDecrementReferenceCounts(IC,F,C,UC) { \
1331 ASSERT_LOCKED_VCB( (F)->Vcb ); \
1332 (F)->FcbReference -= (C); \
1333 (F)->FcbUserReference -= (UC); \
1334 (F)->Vcb->VcbReference -= (C); \
1335 (F)->Vcb->VcbUserReference -= (UC); \
1336 }
1337
1338 //
1339 // PCD_IO_CONTEXT
1340 // CdAllocateIoContext (
1341 // );
1342 //
1343 // VOID
1344 // CdFreeIoContext (
1345 // PCD_IO_CONTEXT IoContext
1346 // );
1347 //
1348
1349 #define CdAllocateIoContext() \
1350 FsRtlAllocatePoolWithTag( CdNonPagedPool, \
1351 sizeof( CD_IO_CONTEXT ), \
1352 TAG_IO_CONTEXT )
1353
1354 #define CdFreeIoContext(IO) CdFreePool( (PVOID) &(IO) ) /* ReactOS Change: GCC "passing argument 1 from incompatible pointer type" */
1355
1356 PFCB
1357 CdLookupFcbTable (
1358 _In_ PIRP_CONTEXT IrpContext,
1359 _In_ PVCB Vcb,
1360 _In_ FILE_ID FileId
1361 );
1362
1363 PFCB
1364 CdGetNextFcb (
1365 _In_ PIRP_CONTEXT IrpContext,
1366 _In_ PVCB Vcb,
1367 _In_ PVOID *RestartKey
1368 );
1369
1370 NTSTATUS
1371 CdProcessToc (
1372 _In_ PIRP_CONTEXT IrpContext,
1373 _In_ PDEVICE_OBJECT TargetDeviceObject,
1374 _In_ PCDROM_TOC_LARGE CdromToc,
1375 _Inout_ PULONG Length,
1376 _Out_ PULONG TrackCount,
1377 _Inout_ PULONG DiskFlags
1378 );
1379
1380 //
1381 // For debugging purposes we sometimes want to allocate our structures from nonpaged
1382 // pool so that in the kernel debugger we can walk all the structures.
1383 //
1384
1385 #define CdPagedPool PagedPool
1386 #ifndef __REACTOS__
1387 #define CdNonPagedPool NonPagedPoolNx
1388 #define CdNonPagedPoolCacheAligned NonPagedPoolNxCacheAligned
1389 #else
1390 #define CdNonPagedPool NonPagedPool
1391 #define CdNonPagedPoolCacheAligned NonPagedPoolCacheAligned
1392 #endif
1393
1394
1395 //
1396 // Verification support routines. Contained in verfysup.c
1397 //
1398
1399 static /* ReactOS Change: GCC "multiple definition" */
1400 INLINE
1401 BOOLEAN
1402 CdOperationIsDasdOpen (
1403 _In_ PIRP_CONTEXT IrpContext
1404 )
1405 {
1406 PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( IrpContext->Irp);
1407
1408 return ((IrpContext->MajorFunction == IRP_MJ_CREATE) &&
1409 (IrpSp->FileObject->FileName.Length == 0) &&
1410 (IrpSp->FileObject->RelatedFileObject == NULL));
1411 }
1412
1413 _Requires_lock_held_(_Global_critical_region_)
1414 NTSTATUS
1415 CdPerformVerify (
1416 _Inout_ PIRP_CONTEXT IrpContext,
1417 _Inout_ PIRP Irp,
1418 _In_ PDEVICE_OBJECT DeviceToVerify
1419 );
1420
1421 _Requires_lock_held_(_Global_critical_region_)
1422 BOOLEAN
1423 CdCheckForDismount (
1424 _In_ PIRP_CONTEXT IrpContext,
1425 _Inout_ PVCB Vcb,
1426 _In_ BOOLEAN Force
1427 );
1428
1429 BOOLEAN
1430 CdMarkDevForVerifyIfVcbMounted (
1431 _Inout_ PVCB Vcb
1432 );
1433
1434 VOID
1435 CdVerifyVcb (
1436 _In_ PIRP_CONTEXT IrpContext,
1437 _Inout_ PVCB Vcb
1438 );
1439
1440 BOOLEAN
1441 CdVerifyFcbOperation (
1442 _In_opt_ PIRP_CONTEXT IrpContext,
1443 _In_ PFCB Fcb
1444 );
1445
1446 _Requires_lock_held_(_Global_critical_region_)
1447 BOOLEAN
1448 CdDismountVcb (
1449 _In_ PIRP_CONTEXT IrpContext,
1450 _Inout_ PVCB Vcb
1451 );
1452
1453
1454 //
1455 // Macros to abstract device verify flag changes.
1456 //
1457
1458 #define CdUpdateMediaChangeCount( V, C) (V)->MediaChangeCount = (C)
1459 #define CdUpdateVcbCondition( V, C) (V)->VcbCondition = (C)
1460
1461 #define CdMarkRealDevForVerify( DO) SetFlag( (DO)->Flags, DO_VERIFY_VOLUME)
1462
1463 #define CdMarkRealDevVerifyOk( DO) ClearFlag( (DO)->Flags, DO_VERIFY_VOLUME)
1464
1465
1466 #define CdRealDevNeedsVerify( DO) BooleanFlagOn( (DO)->Flags, DO_VERIFY_VOLUME)
1467
1468 //
1469 // BOOLEAN
1470 // CdIsRawDevice (
1471 // _In_ PIRP_CONTEXT IrpContext,
1472 // _In_ NTSTATUS Status
1473 // );
1474 //
1475
1476 #define CdIsRawDevice(IC,S) ( \
1477 ((S) == STATUS_DEVICE_NOT_READY) || \
1478 ((S) == STATUS_NO_MEDIA_IN_DEVICE) \
1479 )
1480
1481 \f
1482 //
1483 // Work queue routines for posting and retrieving an Irp, implemented in
1484 // workque.c
1485 //
1486
1487 _Requires_lock_held_(_Global_critical_region_)
1488 NTSTATUS
1489 CdFsdPostRequest (
1490 _Inout_ PIRP_CONTEXT IrpContext,
1491 _Inout_ PIRP Irp
1492 );
1493
1494 _Requires_lock_held_(_Global_critical_region_)
1495 VOID
1496 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
1497 CdPrePostIrp (
1498 _Inout_ PIRP_CONTEXT IrpContext,
1499 _Inout_ PIRP Irp
1500 );
1501
1502 _Requires_lock_held_(_Global_critical_region_)
1503 VOID
1504 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
1505 CdOplockComplete (
1506 _Inout_ PIRP_CONTEXT IrpContext,
1507 _Inout_ PIRP Irp
1508 );
1509
1510 \f
1511 //
1512 // Miscellaneous support routines
1513 //
1514
1515 //
1516 // This macro returns TRUE if a flag in a set of flags is on and FALSE
1517 // otherwise
1518 //
1519
1520 /* GCC complains about multi-line comments.
1521 //#ifndef BooleanFlagOn
1522 //#define BooleanFlagOn(F,SF) ( \
1523 // (BOOLEAN)(((F) & (SF)) != 0) \
1524 //)
1525 //#endif
1526
1527 //#ifndef SetFlag
1528 //#define SetFlag(Flags,SingleFlag) { \
1529 // (Flags) |= (SingleFlag); \
1530 //}
1531 //#endif
1532
1533 //#ifndef ClearFlag
1534 //#define ClearFlag(Flags,SingleFlag) { \
1535 // (Flags) &= ~(SingleFlag); \
1536 //}
1537 //#endif
1538 */
1539
1540 //
1541 // CAST
1542 // Add2Ptr (
1543 // _In_ PVOID Pointer,
1544 // _In_ ULONG Increment
1545 // _In_ (CAST)
1546 // );
1547 //
1548 // ULONG
1549 // PtrOffset (
1550 // _In_ PVOID BasePtr,
1551 // _In_ PVOID OffsetPtr
1552 // );
1553 //
1554
1555 #define Add2Ptr(PTR,INC,CAST) ((CAST)((PUCHAR)(PTR) + (INC)))
1556
1557 #define PtrOffset(BASE,OFFSET) ((ULONG)((ULONG_PTR)(OFFSET) - (ULONG_PTR)(BASE)))
1558
1559 //
1560 // This macro takes a pointer (or ulong) and returns its rounded up word
1561 // value
1562 //
1563
1564 #define WordAlign(Ptr) ( \
1565 ((((ULONG)(Ptr)) + 1) & 0xfffffffe) \
1566 )
1567
1568 //
1569 // This macro takes a pointer (or ulong) and returns its rounded up longword
1570 // value
1571 //
1572
1573 #define LongAlign(Ptr) ( \
1574 ((((ULONG)(Ptr)) + 3) & 0xfffffffc) \
1575 )
1576
1577 //
1578 // This macro takes a pointer (or ulong) and returns its rounded up quadword
1579 // value
1580 //
1581
1582 #define QuadAlign(Ptr) ( \
1583 ((((ULONG)(Ptr)) + 7) & 0xfffffff8) \
1584 )
1585
1586 //
1587 // The following macros round up and down to sector boundaries.
1588 //
1589
1590 #define SectorAlign(L) ( \
1591 ((((ULONG)(L)) + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1)) \
1592 )
1593
1594 #define LlSectorAlign(L) ( \
1595 ((((LONGLONG)(L)) + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1)) \
1596 )
1597
1598 #define SectorTruncate(L) ( \
1599 ((ULONG)(L)) & ~(SECTOR_SIZE - 1) \
1600 )
1601
1602 #define LlSectorTruncate(L) ( \
1603 ((LONGLONG)(L)) & ~(SECTOR_SIZE - 1) \
1604 )
1605
1606 #define BytesFromSectors(L) ( \
1607 ((ULONG) (L)) << SECTOR_SHIFT \
1608 )
1609
1610 #define SectorsFromBytes(L) ( \
1611 ((ULONG) (L)) >> SECTOR_SHIFT \
1612 )
1613
1614 static /* ReactOS Change: GCC "multiple definition" */
1615 INLINE
1616 ULONG
1617 SectorsFromLlBytes(
1618 ULONGLONG Bytes
1619 ) {
1620
1621 return (ULONG)(Bytes >> SECTOR_SHIFT);
1622 }
1623
1624 #define LlBytesFromSectors(L) ( \
1625 Int64ShllMod32( (LONGLONG)(L), SECTOR_SHIFT ) \
1626 )
1627
1628 #define LlSectorsFromBytes(L) ( \
1629 Int64ShraMod32( (LONGLONG)(L), SECTOR_SHIFT ) \
1630 )
1631
1632 #define SectorOffset(L) ( \
1633 ((ULONG)(ULONG_PTR) (L)) & SECTOR_MASK \
1634 )
1635
1636 #define SectorBlockOffset(V,LB) ( \
1637 ((ULONG) (LB)) & ((V)->BlocksPerSector - 1) \
1638 )
1639
1640 #define BytesFromBlocks(V,B) ( \
1641 (ULONG) (B) << (V)->BlockToByteShift \
1642 )
1643
1644 #define LlBytesFromBlocks(V,B) ( \
1645 Int64ShllMod32( (LONGLONG) (B), (V)->BlockToByteShift ) \
1646 )
1647
1648 #define BlockAlign(V,L) ( \
1649 ((ULONG)(L) + (V)->BlockMask) & (V)->BlockInverseMask \
1650 )
1651
1652 //
1653 // Carefully make sure the mask is sign extended to 64bits
1654 //
1655
1656 #define LlBlockAlign(V,L) ( \
1657 ((LONGLONG)(L) + (V)->BlockMask) & (LONGLONG)((LONG)(V)->BlockInverseMask) \
1658 )
1659
1660 #define BlockOffset(V,L) ( \
1661 ((ULONG) (L)) & (V)->BlockMask \
1662 )
1663
1664 #define RawSectorAlign( B) ((((B)+(RAW_SECTOR_SIZE - 1)) / RAW_SECTOR_SIZE) * RAW_SECTOR_SIZE)
1665
1666 //
1667 // The following types and macros are used to help unpack the packed and
1668 // misaligned fields found in the Bios parameter block
1669 //
1670
1671 typedef union _UCHAR1 {
1672 UCHAR Uchar[1];
1673 UCHAR ForceAlignment;
1674 } UCHAR1, *PUCHAR1;
1675
1676 typedef union _UCHAR2 {
1677 UCHAR Uchar[2];
1678 USHORT ForceAlignment;
1679 } UCHAR2, *PUCHAR2;
1680
1681 typedef union _UCHAR4 {
1682 UCHAR Uchar[4];
1683 ULONG ForceAlignment;
1684 } UCHAR4, *PUCHAR4;
1685
1686 typedef union _USHORT2 {
1687 USHORT Ushort[2];
1688 ULONG ForceAlignment;
1689 } USHORT2, *PUSHORT2;
1690
1691 //
1692 // This macro copies an unaligned src byte to an aligned dst byte
1693 //
1694
1695 #define CopyUchar1(Dst,Src) { \
1696 *((UCHAR1 *)(Dst)) = *((UNALIGNED UCHAR1 *)(Src)); \
1697 }
1698
1699 //
1700 // This macro copies an unaligned src word to an aligned dst word
1701 //
1702
1703 #define CopyUchar2(Dst,Src) { \
1704 *((UCHAR2 *)(Dst)) = *((UNALIGNED UCHAR2 *)(Src)); \
1705 }
1706
1707 //
1708 // This macro copies an unaligned src longword to an aligned dsr longword
1709 //
1710
1711 #define CopyUchar4(Dst,Src) { \
1712 *((UCHAR4 *)(Dst)) = *((UNALIGNED UCHAR4 *)(Src)); \
1713 }
1714
1715 //
1716 // This macro copies an unaligned src longword to an aligned dsr longword
1717 // accessing the source on a word boundary.
1718 //
1719
1720 #define CopyUshort2(Dst,Src) { \
1721 *((USHORT2 *)(Dst)) = *((UNALIGNED USHORT2 *)(Src));\
1722 }
1723
1724 //
1725 // This macro copies an unaligned src longword to a dst longword,
1726 // performing an little/big endian swap.
1727 //
1728
1729 #define SwapCopyUchar4(Dst,Src) { \
1730 *((UNALIGNED UCHAR1 *)(Dst)) = *((UNALIGNED UCHAR1 *)(Src) + 3); \
1731 *((UNALIGNED UCHAR1 *)(Dst) + 1) = *((UNALIGNED UCHAR1 *)(Src) + 2); \
1732 *((UNALIGNED UCHAR1 *)(Dst) + 2) = *((UNALIGNED UCHAR1 *)(Src) + 1); \
1733 *((UNALIGNED UCHAR1 *)(Dst) + 3) = *((UNALIGNED UCHAR1 *)(Src)); \
1734 }
1735
1736 VOID
1737 CdLbnToMmSsFf (
1738 _In_ ULONG Blocks,
1739 _Out_writes_(3) PUCHAR Msf
1740 );
1741
1742 //
1743 // Following routines handle entry in and out of the filesystem. They are
1744 // contained in CdData.c
1745 //
1746
1747 _IRQL_requires_max_(APC_LEVEL)
1748 __drv_dispatchType(DRIVER_DISPATCH)
1749 __drv_dispatchType(IRP_MJ_CREATE)
1750 __drv_dispatchType(IRP_MJ_CLOSE)
1751 __drv_dispatchType(IRP_MJ_READ)
1752 __drv_dispatchType(IRP_MJ_WRITE)
1753 __drv_dispatchType(IRP_MJ_QUERY_INFORMATION)
1754 __drv_dispatchType(IRP_MJ_SET_INFORMATION)
1755 __drv_dispatchType(IRP_MJ_QUERY_VOLUME_INFORMATION)
1756 __drv_dispatchType(IRP_MJ_DIRECTORY_CONTROL)
1757 __drv_dispatchType(IRP_MJ_FILE_SYSTEM_CONTROL)
1758 __drv_dispatchType(IRP_MJ_DEVICE_CONTROL)
1759 __drv_dispatchType(IRP_MJ_LOCK_CONTROL)
1760 __drv_dispatchType(IRP_MJ_CLEANUP)
1761 __drv_dispatchType(IRP_MJ_PNP)
1762 __drv_dispatchType(IRP_MJ_SHUTDOWN)
1763 NTSTATUS
1764 NTAPI
1765 CdFsdDispatch (
1766 _In_ PDEVICE_OBJECT DeviceObject,
1767 _Inout_ PIRP Irp
1768 );
1769
1770 // DRIVER_DISPATCH CdFsdDispatch;
1771
1772 LONG
1773 CdExceptionFilter (
1774 _Inout_ PIRP_CONTEXT IrpContext,
1775 _In_ PEXCEPTION_POINTERS ExceptionPointer
1776 );
1777
1778 _Requires_lock_held_(_Global_critical_region_)
1779 NTSTATUS
1780 CdProcessException (
1781 _In_opt_ PIRP_CONTEXT IrpContext,
1782 _Inout_ PIRP Irp,
1783 _In_ NTSTATUS ExceptionCode
1784 );
1785
1786 VOID
1787 CdCompleteRequest (
1788 _Inout_opt_ PIRP_CONTEXT IrpContext,
1789 _Inout_opt_ PIRP Irp,
1790 _In_ NTSTATUS Status
1791 );
1792
1793 //
1794 // VOID
1795 // CdRaiseStatus (
1796 // _In_ PRIP_CONTEXT IrpContext,
1797 // _In_ NT_STATUS Status
1798 // );
1799 //
1800 // VOID
1801 // CdNormalizeAndRaiseStatus (
1802 // _In_ PRIP_CONTEXT IrpContext,
1803 // _In_ NT_STATUS Status
1804 // );
1805 //
1806
1807 #if 0
1808 #define AssertVerifyDevice(C, S) \
1809 NT_ASSERT( (C) == NULL || \
1810 FlagOn( (C)->Flags, IRP_CONTEXT_FLAG_IN_FSP ) || \
1811 !((S) == STATUS_VERIFY_REQUIRED && \
1812 IoGetDeviceToVerify( PsGetCurrentThread() ) == NULL ));
1813
1814 #define AssertVerifyDeviceIrp(I) \
1815 NT_ASSERT( (I) == NULL || \
1816 !(((I)->IoStatus.Status) == STATUS_VERIFY_REQUIRED && \
1817 ((I)->Tail.Overlay.Thread == NULL || \
1818 IoGetDeviceToVerify( (I)->Tail.Overlay.Thread ) == NULL )));
1819 #else
1820 #define AssertVerifyDevice(C, S)
1821 #define AssertVerifyDeviceIrp(I)
1822 #endif
1823
1824
1825 #ifdef CD_SANITY
1826
1827 DECLSPEC_NORETURN
1828 VOID
1829 CdRaiseStatusEx (
1830 _In_ PIRP_CONTEXT IrpContext,
1831 _In_ NTSTATUS Status,
1832 _In_ BOOLEAN NormalizeStatus,
1833 _In_opt_ ULONG FileId,
1834 _In_opt_ ULONG Line
1835 );
1836
1837 #else
1838
1839 INLINE
1840 DECLSPEC_NORETURN
1841 VOID
1842 CdRaiseStatusEx(
1843 _In_ PIRP_CONTEXT IrpContext,
1844 _In_ NTSTATUS Status,
1845 _In_ BOOLEAN NormalizeStatus,
1846 _In_ ULONG Fileid,
1847 _In_ ULONG Line
1848 )
1849 {
1850 if (NormalizeStatus) {
1851
1852 IrpContext->ExceptionStatus = FsRtlNormalizeNtstatus( Status, STATUS_UNEXPECTED_IO_ERROR);
1853 }
1854 else {
1855
1856 IrpContext->ExceptionStatus = Status;
1857 }
1858
1859 IrpContext->RaisedAtLineFile = (Fileid << 16) | Line;
1860
1861 ExRaiseStatus( IrpContext->ExceptionStatus );
1862 }
1863
1864 #endif
1865
1866 #define CdRaiseStatus( IC, S) CdRaiseStatusEx( (IC), (S), FALSE, BugCheckFileId, __LINE__);
1867 #define CdNormalizeAndRaiseStatus( IC, S) CdRaiseStatusEx( (IC), (S), TRUE, BugCheckFileId, __LINE__);
1868
1869 //
1870 // Following are the fast entry points.
1871 //
1872
1873 // _Success_(return != FALSE)
1874 // BOOLEAN
1875 // CdFastQueryBasicInfo (
1876 // _In_ PFILE_OBJECT FileObject,
1877 // _In_ BOOLEAN Wait,
1878 // _Out_ PFILE_BASIC_INFORMATION Buffer,
1879 // _Out_ PIO_STATUS_BLOCK IoStatus,
1880 // _In_ PDEVICE_OBJECT DeviceObject
1881 // );
1882
1883 FAST_IO_QUERY_BASIC_INFO CdFastQueryBasicInfo;
1884
1885 // _Success_(return != FALSE)
1886 // BOOLEAN
1887 // CdFastQueryStdInfo (
1888 // _In_ PFILE_OBJECT FileObject,
1889 // _In_ BOOLEAN Wait,
1890 // _Out_ PFILE_STANDARD_INFORMATION Buffer,
1891 // _Out_ PIO_STATUS_BLOCK IoStatus,
1892 // _In_ PDEVICE_OBJECT DeviceObject
1893 // );
1894
1895 FAST_IO_QUERY_STANDARD_INFO CdFastQueryStdInfo;
1896
1897 // BOOLEAN
1898 // CdFastLock (
1899 // _In_ PFILE_OBJECT FileObject,
1900 // _In_ PLARGE_INTEGER FileOffset,
1901 // _In_ PLARGE_INTEGER Length,
1902 // _In_ PEPROCESS ProcessId,
1903 // _In_ ULONG Key,
1904 // _In_ BOOLEAN FailImmediately,
1905 // _In_ BOOLEAN ExclusiveLock,
1906 // _Out_ PIO_STATUS_BLOCK IoStatus,
1907 // _In_ PDEVICE_OBJECT DeviceObject
1908 // );
1909
1910 FAST_IO_LOCK CdFastLock;
1911
1912 // BOOLEAN
1913 // CdFastUnlockSingle (
1914 // _In_ PFILE_OBJECT FileObject,
1915 // _In_ PLARGE_INTEGER FileOffset,
1916 // _In_ PLARGE_INTEGER Length,
1917 // _In_ PEPROCESS ProcessId,
1918 // _In_ ULONG Key,
1919 // _Out_ PIO_STATUS_BLOCK IoStatus,
1920 // _In_ PDEVICE_OBJECT DeviceObject
1921 // );
1922
1923 FAST_IO_UNLOCK_SINGLE CdFastUnlockSingle;
1924
1925 // BOOLEAN
1926 // CdFastUnlockAll (
1927 // _In_ PFILE_OBJECT FileObject,
1928 // _In_ PEPROCESS ProcessId,
1929 // _Out_ PIO_STATUS_BLOCK IoStatus,
1930 // _In_ PDEVICE_OBJECT DeviceObject
1931 // );
1932
1933 FAST_IO_UNLOCK_ALL CdFastUnlockAll;
1934
1935 // BOOLEAN
1936 // CdFastUnlockAllByKey (
1937 // _In_ PFILE_OBJECT FileObject,
1938 // _In_ PVOID ProcessId,
1939 // _In_ ULONG Key,
1940 // _Out_ PIO_STATUS_BLOCK IoStatus,
1941 // _In_ PDEVICE_OBJECT DeviceObject
1942 // );
1943
1944 FAST_IO_UNLOCK_ALL_BY_KEY CdFastUnlockAllByKey;
1945
1946 // BOOLEAN
1947 // CdFastIoCheckIfPossible (
1948 // _In_ PFILE_OBJECT FileObject,
1949 // _In_ PLARGE_INTEGER FileOffset,
1950 // _In_ ULONG Length,
1951 // _In_ BOOLEAN Wait,
1952 // _In_ ULONG LockKey,
1953 // _In_ BOOLEAN CheckForReadOperation,
1954 // _Out_ PIO_STATUS_BLOCK IoStatus,
1955 // _In_ PDEVICE_OBJECT DeviceObject
1956 // );
1957
1958 FAST_IO_CHECK_IF_POSSIBLE CdFastIoCheckIfPossible;
1959
1960 // _Success_(return != FALSE)
1961 // BOOLEAN
1962 // CdFastQueryNetworkInfo (
1963 // _In_ PFILE_OBJECT FileObject,
1964 // _In_ BOOLEAN Wait,
1965 // _Out_ PFILE_NETWORK_OPEN_INFORMATION Buffer,
1966 // _Out_ PIO_STATUS_BLOCK IoStatus,
1967 // _In_ PDEVICE_OBJECT DeviceObject
1968 // );
1969
1970 FAST_IO_QUERY_NETWORK_OPEN_INFO CdFastQueryNetworkInfo;
1971
1972 //
1973 // Following are the routines to handle the top level thread logic.
1974 //
1975
1976 VOID
1977 CdSetThreadContext (
1978 _Inout_ PIRP_CONTEXT IrpContext,
1979 _In_ PTHREAD_CONTEXT ThreadContext
1980 );
1981
1982
1983 //
1984 // VOID
1985 // CdRestoreThreadContext (
1986 // _Inout_ PIRP_CONTEXT IrpContext
1987 // );
1988 //
1989
1990 #define CdRestoreThreadContext(IC) \
1991 (IC)->ThreadContext->Cdfs = 0; \
1992 IoSetTopLevelIrp( (IC)->ThreadContext->SavedTopLevelIrp ); \
1993 (IC)->ThreadContext = NULL
1994
1995 ULONG
1996 CdSerial32 (
1997 _In_reads_bytes_(ByteCount) PCHAR Buffer,
1998 _In_ ULONG ByteCount
1999 );
2000
2001 //
2002 // The following macro is used to determine if an FSD thread can block
2003 // for I/O or wait for a resource. It returns TRUE if the thread can
2004 // block and FALSE otherwise. This attribute can then be used to call
2005 // the FSD & FSP common work routine with the proper wait value.
2006 //
2007
2008 #define CanFsdWait(I) IoIsOperationSynchronous(I)
2009
2010 //
2011 // The following macro is used to set the fast i/o possible bits in the
2012 // FsRtl header.
2013 //
2014 // FastIoIsNotPossible - If the Fcb is bad or there are oplocks on the file.
2015 //
2016 // FastIoIsQuestionable - If there are file locks.
2017 //
2018 // FastIoIsPossible - In all other cases.
2019 //
2020 //
2021
2022 #define CdIsFastIoPossible(F) ((BOOLEAN) \
2023 ((((F)->Vcb->VcbCondition != VcbMounted ) || \
2024 !FsRtlOplockIsFastIoPossible( CdGetFcbOplock(F) )) ? \
2025 \
2026 FastIoIsNotPossible : \
2027 \
2028 ((((F)->FileLock != NULL) && FsRtlAreThereCurrentFileLocks( (F)->FileLock )) ? \
2029 \
2030 FastIoIsQuestionable : \
2031 \
2032 FastIoIsPossible)) \
2033 )
2034
2035 \f
2036 //
2037 // The FSP level dispatch/main routine. This is the routine that takes
2038 // IRP's off of the work queue and calls the appropriate FSP level
2039 // work routine.
2040 //
2041
2042 // VOID
2043 // CdFspDispatch ( // implemented in FspDisp.c
2044 // _Inout_ PIRP_CONTEXT IrpContext
2045 // );
2046
2047 WORKER_THREAD_ROUTINE CdFspDispatch;
2048
2049 VOID
2050 CdFspClose ( // implemented in Close.c
2051 _In_opt_ PVCB Vcb
2052 );
2053
2054 //
2055 // The following routines are the entry points for the different operations
2056 // based on the IrpSp major functions.
2057 //
2058
2059 _Requires_lock_held_(_Global_critical_region_)
2060 NTSTATUS
2061 CdCommonCreate ( // Implemented in Create.c
2062 _Inout_ PIRP_CONTEXT IrpContext,
2063 _Inout_ PIRP Irp
2064 );
2065
2066 _Requires_lock_held_(_Global_critical_region_)
2067 NTSTATUS
2068 CdCommonClose ( // Implemented in Close.c
2069 _Inout_ PIRP_CONTEXT IrpContext,
2070 _Inout_ PIRP Irp
2071 );
2072
2073 _Requires_lock_held_(_Global_critical_region_)
2074 NTSTATUS
2075 CdCommonRead ( // Implemented in Read.c
2076 _Inout_ PIRP_CONTEXT IrpContext,
2077 _Inout_ PIRP Irp
2078 );
2079
2080 _Requires_lock_held_(_Global_critical_region_)
2081 NTSTATUS
2082 CdCommonWrite ( // Implemented in Write.c
2083 _Inout_ PIRP_CONTEXT IrpContext,
2084 _Inout_ PIRP Irp
2085 );
2086
2087 _Requires_lock_held_(_Global_critical_region_)
2088 NTSTATUS
2089 CdCommonQueryInfo ( // Implemented in FileInfo.c
2090 _Inout_ PIRP_CONTEXT IrpContext,
2091 _Inout_ PIRP Irp
2092 );
2093
2094 _Requires_lock_held_(_Global_critical_region_)
2095 NTSTATUS
2096 CdCommonSetInfo ( // Implemented in FileInfo.c
2097 _Inout_ PIRP_CONTEXT IrpContext,
2098 _Inout_ PIRP Irp
2099 );
2100
2101 _Requires_lock_held_(_Global_critical_region_)
2102 NTSTATUS
2103 CdCommonQueryVolInfo ( // Implemented in VolInfo.c
2104 _Inout_ PIRP_CONTEXT IrpContext,
2105 _Inout_ PIRP Irp
2106 );
2107
2108 _Requires_lock_held_(_Global_critical_region_)
2109 NTSTATUS
2110 CdCommonDirControl ( // Implemented in DirCtrl.c
2111 _Inout_ PIRP_CONTEXT IrpContext,
2112 _Inout_ PIRP Irp
2113 );
2114
2115 _Requires_lock_held_(_Global_critical_region_)
2116 NTSTATUS
2117 CdCommonFsControl ( // Implemented in FsCtrl.c
2118 _Inout_ PIRP_CONTEXT IrpContext,
2119 _Inout_ PIRP Irp
2120 );
2121
2122 NTSTATUS
2123 CdCommonDevControl ( // Implemented in DevCtrl.c
2124 _Inout_ PIRP_CONTEXT IrpContext,
2125 _Inout_ PIRP Irp
2126 );
2127
2128 NTSTATUS
2129 CdCommonLockControl ( // Implemented in LockCtrl.c
2130 _Inout_ PIRP_CONTEXT IrpContext,
2131 _Inout_ PIRP Irp
2132 );
2133
2134 _Requires_lock_held_(_Global_critical_region_)
2135 NTSTATUS
2136 CdCommonCleanup ( // Implemented in Cleanup.c
2137 _Inout_ PIRP_CONTEXT IrpContext,
2138 _Inout_ PIRP Irp
2139 );
2140
2141 _Requires_lock_held_(_Global_critical_region_)
2142 NTSTATUS
2143 CdCommonPnp ( // Implemented in Pnp.c
2144 _Inout_ PIRP_CONTEXT IrpContext,
2145 _Inout_ PIRP Irp
2146 );
2147
2148 _Requires_lock_held_(_Global_critical_region_)
2149 NTSTATUS
2150 CdCommonShutdown ( // Implemented in Shutdown.c
2151 _Inout_ PIRP_CONTEXT IrpContext,
2152 _Inout_ PIRP Irp
2153 );
2154
2155
2156 \f
2157 //
2158 // The following macros are used to establish the semantics needed
2159 // to do a return from within a try-finally clause. As a rule every
2160 // try clause must end with a label call try_exit. For example,
2161 //
2162 // try {
2163 // :
2164 // :
2165 //
2166 // try_exit: NOTHING;
2167 // } finally {
2168 //
2169 // :
2170 // :
2171 // }
2172 //
2173 // Every return statement executed inside of a try clause should use the
2174 // try_return macro. If the compiler fully supports the try-finally construct
2175 // then the macro should be
2176 //
2177 // #define try_return(S) { return(S); }
2178 //
2179 // If the compiler does not support the try-finally construct then the macro
2180 // should be
2181 //
2182 // #define try_return(S) { S; goto try_exit; }
2183 //
2184
2185 #ifndef __REACTOS__
2186 #define try_return(S) { S; goto try_exit; }
2187 #define try_leave(S) { S; leave; }
2188 #else
2189 #define try_return(S) { S; goto try_exit; }
2190 #define try_leave(S) { S; _SEH2_LEAVE; }
2191 #endif
2192
2193 //
2194 // Encapsulate safe pool freeing
2195 //
2196 /* ReactOS Change: GCC "passing argument 1 of CdFreePool from incompatible pointer type" */
2197 #define CdFreePool(x) _CdFreePool((PVOID*)(x))
2198
2199 static /* ReactOS Change: GCC "multiple definition" */
2200 INLINE
2201 VOID
2202 _CdFreePool(
2203 _Inout_ _At_(*Pool, __drv_freesMem(Mem) _Post_null_) PVOID *Pool
2204 )
2205 {
2206 if (*Pool != NULL) {
2207
2208 ExFreePool(*Pool);
2209 *Pool = NULL;
2210 }
2211 }
2212
2213 #ifdef CDFS_TELEMETRY_DATA
2214
2215 //
2216 // CDFS Telemetry. Current implementation uses the Telemetry TraceLogging APIs.
2217 //
2218 // The Telemetry TraceLoggingWrite() routines use a lot of stack space. We must
2219 // therefor wrap all our telemetry points with our own routines, and add a guard to
2220 // make sure there's enough stack space to call these routines.
2221 //
2222 // These telemetry routines should not be called on high-performance code paths.
2223 //
2224
2225 TRACELOGGING_DECLARE_PROVIDER( CdTelemetryProvider );
2226
2227 VOID
2228 CdInitializeTelemetry (
2229 VOID
2230 );
2231
2232 DECLSPEC_NOINLINE
2233 VOID
2234 CdTelemetryMount (
2235 __in PGUID VolumeGuid,
2236 __in NTSTATUS Status,
2237 __in PVCB Vcb
2238 );
2239
2240 //
2241 // Every additional argument passed to TraceLoggingWrite() consumes an additional
2242 // 16 to 32 bytes extra stack space. Having 512 bytes reserved space should be
2243 // sufficient for up to 20 arguments or so. This will be less of course if our
2244 // wrapper routines also declare their own local variables.
2245 //
2246
2247 #define CDFS_TELEMETRY_STACK_THRESHOLD_DEFAULT 512 // for "small" telemetry points
2248 #define CDFS_TELEMETRY_STACK_THRESHOLD_LARGE 2048 // for "large" telemetry points
2249
2250 INLINE
2251 BOOLEAN
2252 CdTelemetryGuard (
2253 __in ULONG StackSpaceNeeded )
2254 /*++
2255
2256 Routine Description:
2257
2258 This routine returns TRUE only when:
2259
2260 1) There is an ETW listener, AND
2261 2) There is enough free stack space to safely call the Telemetry TraceLogging APIs
2262
2263 We'll also count how many times there wasn't enough stack space, and include this
2264 value as part of the periodic cdfs Telemetry.
2265
2266 Arguments:
2267
2268 StackSpaceNeeded - Stack space needed in bytes
2269
2270 --*/
2271 {
2272 ASSERT( IoGetRemainingStackSize() >= StackSpaceNeeded );
2273
2274 if (CdTelemetryProvider->LevelPlus1 <= 5) {
2275
2276 //
2277 // Bail out early if there are no ETW listeners
2278 //
2279
2280 return FALSE;
2281 }
2282
2283 if (IoGetRemainingStackSize() < StackSpaceNeeded) {
2284
2285 //
2286 // Count how many times it was unsafe to generate telemetry because of
2287 // not enough stack space.
2288 //
2289
2290 InterlockedIncrement( &CdTelemetryData.MissedTelemetryPoints );
2291
2292 return FALSE;
2293 }
2294
2295 return TRUE;
2296 }
2297
2298 #define CdTelemetryMountSafe( VolumeGuid, Status, Vcb ) \
2299 if (CdTelemetryGuard( CDFS_TELEMETRY_STACK_THRESHOLD_LARGE )) { \
2300 CdTelemetryMount( VolumeGuid, Status, Vcb ); \
2301 }
2302
2303 #if DBG
2304 #define CDFS_TELEMETRY_PERIODIC_INTERVAL CdTelemetryData.PeriodicInterval
2305 #else
2306 #define CDFS_TELEMETRY_PERIODIC_INTERVAL INTERVAL_ONE_DAY
2307 #endif
2308
2309 #else // CDFS_TELEMETRY_DATA
2310
2311 //
2312 // When CDFS_TELEMETRY_DATA is not defined then the CdTelemetry___Safe() routines
2313 // expand to nothing. This minimizes the cdfs.sys binary footprint. This also
2314 // means that the places where these Safe() routines are called do not
2315 // have to have to be surrounded by #ifdef CDFS_TELEMETRY_DATA .. #endif
2316 //
2317
2318
2319 #define CdTelemetryMountSafe( ... ) NOTHING
2320
2321 #endif // CDFS_TELEMETRY_DATA
2322
2323 #endif // _CDPROCS_
2324
2325