[CDFS_NEW] _SEH2_FINALLY implement SEH support for real instead of its current stub.
[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 #include <ntifs.h>
21
22 #include <ntddcdrm.h>
23 #include <ntdddisk.h>
24 #include <ntddscsi.h>
25 #ifdef __REACTOS__
26 #include <pseh/pseh2.h>
27 #endif
28
29 #ifndef INLINE
30 #define INLINE __inline
31 #endif
32
33 #include "nodetype.h"
34 #include "cd.h"
35 #include "cdstruc.h"
36 #include "cddata.h"
37
38
39 //**** x86 compiler bug ****
40
41 #if defined(_M_IX86)
42 #undef Int64ShraMod32
43 #define Int64ShraMod32(a, b) ((LONGLONG)(a) >> (b))
44 #endif
45
46 //
47 // Here are the different pool tags.
48 //
49
50 #define TAG_CCB 'ccdC' // Ccb
51 #define TAG_CDROM_TOC 'ctdC' // TOC
52 #define TAG_DIRENT_NAME 'nddC' // CdName in dirent
53 #define TAG_ENUM_EXPRESSION 'eedC' // Search expression for enumeration
54 #define TAG_FCB_DATA 'dfdC' // Data Fcb
55 #define TAG_FCB_INDEX 'ifdC' // Index Fcb
56 #define TAG_FCB_NONPAGED 'nfdC' // Nonpaged Fcb
57 #define TAG_FCB_TABLE 'tfdC' // Fcb Table entry
58 #define TAG_FILE_NAME 'nFdC' // Filename buffer
59 #define TAG_GEN_SHORT_NAME 'sgdC' // Generated short name
60 #define TAG_IO_BUFFER 'fbdC' // Temporary IO buffer
61 #define TAG_IO_CONTEXT 'oidC' // Io context for async reads
62 #define TAG_IRP_CONTEXT 'cidC' // Irp Context
63 #define TAG_IRP_CONTEXT_LITE 'lidC' // Irp Context lite
64 #define TAG_MCB_ARRAY 'amdC' // Mcb array
65 #define TAG_PATH_ENTRY_NAME 'nPdC' // CdName in path entry
66 #define TAG_PREFIX_ENTRY 'epdC' // Prefix Entry
67 #define TAG_PREFIX_NAME 'npdC' // Prefix Entry name
68 #define TAG_SPANNING_PATH_TABLE 'psdC' // Buffer for spanning path table
69 #define TAG_UPCASE_NAME 'nudC' // Buffer for upcased name
70 #define TAG_VOL_DESC 'dvdC' // Buffer for volume descriptor
71 #define TAG_VPB 'pvdC' // Vpb allocated in filesystem
72
73 //
74 // Tag all of our allocations if tagging is turned on
75 //
76
77 #ifdef POOL_TAGGING
78
79 #undef FsRtlAllocatePool
80 #undef FsRtlAllocatePoolWithQuota
81 #define FsRtlAllocatePool(a,b) FsRtlAllocatePoolWithTag(a,b,'sfdC')
82 #define FsRtlAllocatePoolWithQuota(a,b) FsRtlAllocatePoolWithQuotaTag(a,b,'sfdC')
83
84 #endif // POOL_TAGGING
85
86
87 //
88 // File access check routine, implemented in AcChkSup.c
89 //
90
91 //
92 // BOOLEAN
93 // CdIllegalFcbAccess (
94 // IN PIRP_CONTEXT IrpContext,
95 // IN TYPE_OF_OPEN TypeOfOpen,
96 // IN ACCESS_MASK DesiredAccess
97 // );
98 //
99
100 #define CdIllegalFcbAccess(IC,T,DA) ( \
101 BooleanFlagOn( (DA), \
102 ((T) != UserVolumeOpen ? \
103 (FILE_WRITE_ATTRIBUTES | \
104 FILE_WRITE_DATA | \
105 FILE_WRITE_EA | \
106 FILE_ADD_FILE | \
107 FILE_ADD_SUBDIRECTORY | \
108 FILE_APPEND_DATA) : 0) | \
109 FILE_DELETE_CHILD | \
110 DELETE | \
111 WRITE_DAC ))
112
113 \f
114 //
115 // Allocation support routines, implemented in AllocSup.c
116 //
117 // These routines are for querying allocation on individual streams.
118 //
119
120 VOID
121 CdLookupAllocation (
122 IN PIRP_CONTEXT IrpContext,
123 IN PFCB Fcb,
124 IN LONGLONG FileOffset,
125 OUT PLONGLONG DiskOffset,
126 OUT PULONG ByteCount
127 );
128
129 VOID
130 CdAddAllocationFromDirent (
131 IN PIRP_CONTEXT IrpContext,
132 IN PFCB Fcb,
133 IN ULONG McbEntryOffset,
134 IN LONGLONG StartingFileOffset,
135 IN PDIRENT Dirent
136 );
137
138 VOID
139 CdAddInitialAllocation (
140 IN PIRP_CONTEXT IrpContext,
141 IN PFCB Fcb,
142 IN ULONG StartingBlock,
143 IN LONGLONG DataLength
144 );
145
146 VOID
147 CdTruncateAllocation (
148 IN PIRP_CONTEXT IrpContext,
149 IN PFCB Fcb,
150 IN LONGLONG StartingFileOffset
151 );
152
153 VOID
154 CdInitializeMcb (
155 IN PIRP_CONTEXT IrpContext,
156 IN PFCB Fcb
157 );
158
159 VOID
160 CdUninitializeMcb (
161 IN PIRP_CONTEXT IrpContext,
162 IN PFCB Fcb
163 );
164
165 \f
166 //
167 // Buffer control routines for data caching, implemented in CacheSup.c
168 //
169
170 VOID
171 CdCreateInternalStream (
172 IN PIRP_CONTEXT IrpContext,
173 IN PVCB Vcb,
174 IN PFCB Fcb
175 );
176
177 VOID
178 CdDeleteInternalStream (
179 IN PIRP_CONTEXT IrpContext,
180 IN PFCB Fcb
181 );
182
183 NTSTATUS
184 CdCompleteMdl (
185 IN PIRP_CONTEXT IrpContext,
186 IN PIRP Irp
187 );
188
189 NTSTATUS
190 CdPurgeVolume (
191 IN PIRP_CONTEXT IrpContext,
192 IN PVCB Vcb,
193 IN BOOLEAN DismountUnderway
194 );
195
196 //
197 // VOID
198 // CdUnpinData (
199 // IN PIRP_CONTEXT IrpContext,
200 // IN OUT PBCB *Bcb
201 // );
202 //
203
204 #define CdUnpinData(IC,B) \
205 if (*(B) != NULL) { CcUnpinData( *(B) ); *(B) = NULL; }
206
207 \f
208 //
209 // Device I/O routines, implemented in DevIoSup.c
210 //
211 // These routines perform the actual device read and writes. They only affect
212 // the on disk structure and do not alter any other data structures.
213 //
214
215 NTSTATUS
216 CdNonCachedRead (
217 IN PIRP_CONTEXT IrpContext,
218 IN PFCB Fcb,
219 IN LONGLONG StartingOffset,
220 IN ULONG ByteCount
221 );
222
223 NTSTATUS
224 CdNonCachedXARead (
225 IN PIRP_CONTEXT IrpContext,
226 IN PFCB Fcb,
227 IN LONGLONG StartingOffset,
228 IN ULONG ByteCount
229 );
230
231 BOOLEAN
232 CdReadSectors (
233 IN PIRP_CONTEXT IrpContext,
234 IN LONGLONG StartingOffset,
235 IN ULONG ByteCount,
236 IN BOOLEAN RaiseOnError,
237 IN OUT PVOID Buffer,
238 IN PDEVICE_OBJECT TargetDeviceObject
239 );
240
241 NTSTATUS
242 CdCreateUserMdl (
243 IN PIRP_CONTEXT IrpContext,
244 IN ULONG BufferLength,
245 IN BOOLEAN RaiseOnError
246 );
247
248 NTSTATUS
249 CdPerformDevIoCtrl (
250 IN PIRP_CONTEXT IrpContext,
251 IN ULONG IoControlCode,
252 IN PDEVICE_OBJECT Device,
253 OUT PVOID OutputBuffer OPTIONAL,
254 IN ULONG OutputBufferLength,
255 IN BOOLEAN InternalDeviceIoControl,
256 IN BOOLEAN OverrideVerify,
257 OUT PIO_STATUS_BLOCK Iosb OPTIONAL
258 );
259
260 //
261 // VOID
262 // CdMapUserBuffer (
263 // IN PIRP_CONTEXT IrpContext
264 // OUT PVOID UserBuffer
265 // );
266 //
267 // Returns pointer to sys address. Will raise on failure.
268 //
269 //
270 // VOID
271 // CdLockUserBuffer (
272 // IN PIRP_CONTEXT IrpContext,
273 // IN ULONG BufferLength
274 // );
275 //
276
277 #define CdMapUserBuffer(IC, UB) { \
278 *(UB) = (PVOID) ( ((IC)->Irp->MdlAddress == NULL) ? \
279 (IC)->Irp->UserBuffer : \
280 (MmGetSystemAddressForMdlSafe( (IC)->Irp->MdlAddress, NormalPagePriority))); \
281 if (NULL == *(UB)) { \
282 CdRaiseStatus( (IC), STATUS_INSUFFICIENT_RESOURCES); \
283 } \
284 }
285
286
287 #define CdLockUserBuffer(IC,BL) { \
288 if ((IC)->Irp->MdlAddress == NULL) { \
289 (VOID) CdCreateUserMdl( (IC), (BL), TRUE ); \
290 } \
291 }
292
293 \f
294 //
295 // Dirent support routines, implemented in DirSup.c
296 //
297
298 VOID
299 CdLookupDirent (
300 IN PIRP_CONTEXT IrpContext,
301 IN PFCB Fcb,
302 IN ULONG DirentOffset,
303 OUT PDIRENT_ENUM_CONTEXT DirContext
304 );
305
306 BOOLEAN
307 CdLookupNextDirent (
308 IN PIRP_CONTEXT IrpContext,
309 IN PFCB Fcb,
310 IN PDIRENT_ENUM_CONTEXT CurrentDirContext,
311 OUT PDIRENT_ENUM_CONTEXT NextDirContext
312 );
313
314 VOID
315 CdUpdateDirentFromRawDirent (
316 IN PIRP_CONTEXT IrpContext,
317 IN PFCB Fcb,
318 IN PDIRENT_ENUM_CONTEXT DirContext,
319 IN OUT PDIRENT Dirent
320 );
321
322 VOID
323 CdUpdateDirentName (
324 IN PIRP_CONTEXT IrpContext,
325 IN OUT PDIRENT Dirent,
326 IN ULONG IgnoreCase
327 );
328
329 BOOLEAN
330 CdFindFile (
331 IN PIRP_CONTEXT IrpContext,
332 IN PFCB Fcb,
333 IN PCD_NAME Name,
334 IN BOOLEAN IgnoreCase,
335 IN OUT PFILE_ENUM_CONTEXT FileContext,
336 OUT PCD_NAME *MatchingName
337 );
338
339 BOOLEAN
340 CdFindDirectory (
341 IN PIRP_CONTEXT IrpContext,
342 IN PFCB Fcb,
343 IN PCD_NAME Name,
344 IN BOOLEAN IgnoreCase,
345 IN OUT PFILE_ENUM_CONTEXT FileContext
346 );
347
348 BOOLEAN
349 CdFindFileByShortName (
350 IN PIRP_CONTEXT IrpContext,
351 IN PFCB Fcb,
352 IN PCD_NAME Name,
353 IN BOOLEAN IgnoreCase,
354 IN ULONG ShortNameDirentOffset,
355 IN OUT PFILE_ENUM_CONTEXT FileContext
356 );
357
358 BOOLEAN
359 CdLookupNextInitialFileDirent (
360 IN PIRP_CONTEXT IrpContext,
361 IN PFCB Fcb,
362 IN OUT PFILE_ENUM_CONTEXT FileContext
363 );
364
365 VOID
366 CdLookupLastFileDirent (
367 IN PIRP_CONTEXT IrpContext,
368 IN PFCB Fcb,
369 IN PFILE_ENUM_CONTEXT FileContext
370 );
371
372 VOID
373 CdCleanupFileContext (
374 IN PIRP_CONTEXT IrpContext,
375 IN PFILE_ENUM_CONTEXT FileContext
376 );
377
378 //
379 // VOID
380 // CdInitializeFileContext (
381 // IN PIRP_CONTEXT IrpContext,
382 // IN PFILE_ENUM_CONTEXT FileContext
383 // );
384 //
385 //
386 // VOID
387 // CdInitializeDirent (
388 // IN PIRP_CONTEXT IrpContext,
389 // IN PDIRENT Dirent
390 // );
391 //
392 // VOID
393 // CdInitializeDirContext (
394 // IN PIRP_CONTEXT IrpContext,
395 // IN PDIRENT_ENUM_CONTEXT DirContext
396 // );
397 //
398 // VOID
399 // CdCleanupDirent (
400 // IN PIRP_CONTEXT IrpContext,
401 // IN PDIRENT Dirent
402 // );
403 //
404 // VOID
405 // CdCleanupDirContext (
406 // IN PIRP_CONTEXT IrpContext,
407 // IN PDIRENT_ENUM_CONTEXT DirContext
408 // );
409 //
410 // VOID
411 // CdLookupInitialFileDirent (
412 // IN PIRP_CONTEXT IrpContext,
413 // IN PFCB Fcb,
414 // IN PFILE_ENUM_CONTEXT FileContext,
415 // IN ULONG DirentOffset
416 // );
417 //
418
419 #define CdInitializeFileContext(IC,FC) { \
420 RtlZeroMemory( FC, sizeof( FILE_ENUM_CONTEXT )); \
421 (FC)->PriorDirent = &(FC)->Dirents[0]; \
422 (FC)->InitialDirent = &(FC)->Dirents[1]; \
423 (FC)->CurrentDirent = &(FC)->Dirents[2]; \
424 (FC)->ShortName.FileName.MaximumLength = BYTE_COUNT_8_DOT_3; \
425 (FC)->ShortName.FileName.Buffer = (FC)->ShortNameBuffer; \
426 }
427
428 #define CdInitializeDirent(IC,D) \
429 RtlZeroMemory( D, sizeof( DIRENT ))
430
431 #define CdInitializeDirContext(IC,DC) \
432 RtlZeroMemory( DC, sizeof( DIRENT_ENUM_CONTEXT ))
433
434 #define CdCleanupDirent(IC,D) { \
435 if (FlagOn( (D)->Flags, DIRENT_FLAG_ALLOC_BUFFER )) { \
436 CdFreePool( &(D)->CdFileName.FileName.Buffer ); \
437 } \
438 }
439
440 #define CdCleanupDirContext(IC,DC) \
441 CdUnpinData( (IC), &(DC)->Bcb )
442
443 #define CdLookupInitialFileDirent(IC,F,FC,DO) \
444 CdLookupDirent( IC, \
445 F, \
446 DO, \
447 &(FC)->InitialDirent->DirContext ); \
448 CdUpdateDirentFromRawDirent( IC, \
449 F, \
450 &(FC)->InitialDirent->DirContext, \
451 &(FC)->InitialDirent->Dirent )
452
453 \f
454 //
455 // The following routines are used to manipulate the fscontext fields
456 // of the file object, implemented in FilObSup.c
457 //
458
459 //
460 // Type of opens. FilObSup.c depends on this order.
461 //
462
463 typedef enum _TYPE_OF_OPEN {
464
465 UnopenedFileObject = 0,
466 StreamFileOpen,
467 UserVolumeOpen,
468 UserDirectoryOpen,
469 UserFileOpen,
470 BeyondValidType
471
472 } TYPE_OF_OPEN;
473 typedef TYPE_OF_OPEN *PTYPE_OF_OPEN;
474
475 VOID
476 CdSetFileObject (
477 IN PIRP_CONTEXT IrpContext,
478 IN PFILE_OBJECT FileObject,
479 IN TYPE_OF_OPEN TypeOfOpen,
480 IN PFCB Fcb OPTIONAL,
481 IN PCCB Ccb OPTIONAL
482 );
483
484 TYPE_OF_OPEN
485 CdDecodeFileObject (
486 IN PIRP_CONTEXT IrpContext,
487 IN PFILE_OBJECT FileObject,
488 OUT PFCB *Fcb,
489 OUT PCCB *Ccb
490 );
491
492 TYPE_OF_OPEN
493 CdFastDecodeFileObject (
494 IN PFILE_OBJECT FileObject,
495 OUT PFCB *Fcb
496 );
497
498 \f
499 //
500 // Name support routines, implemented in NameSup.c
501 //
502
503 VOID
504 CdConvertNameToCdName (
505 IN PIRP_CONTEXT IrpContext,
506 IN OUT PCD_NAME CdName
507 );
508
509 VOID
510 CdConvertBigToLittleEndian (
511 IN PIRP_CONTEXT IrpContext,
512 IN PCHAR BigEndian,
513 IN ULONG ByteCount,
514 OUT PCHAR LittleEndian
515 );
516
517 VOID
518 CdUpcaseName (
519 IN PIRP_CONTEXT IrpContext,
520 IN PCD_NAME Name,
521 IN OUT PCD_NAME UpcaseName
522 );
523
524 VOID
525 CdDissectName (
526 IN PIRP_CONTEXT IrpContext,
527 IN OUT PUNICODE_STRING RemainingName,
528 OUT PUNICODE_STRING FinalName
529 );
530
531 BOOLEAN
532 CdIs8dot3Name (
533 IN PIRP_CONTEXT IrpContext,
534 IN UNICODE_STRING FileName
535 );
536
537 VOID
538 CdGenerate8dot3Name (
539 IN PIRP_CONTEXT IrpContext,
540 IN PUNICODE_STRING FileName,
541 IN ULONG DirentOffset,
542 OUT PWCHAR ShortFileName,
543 OUT PUSHORT ShortByteCount
544 );
545
546 BOOLEAN
547 CdIsNameInExpression (
548 IN PIRP_CONTEXT IrpContext,
549 IN PCD_NAME CurrentName,
550 IN PCD_NAME SearchExpression,
551 IN ULONG WildcardFlags,
552 IN BOOLEAN CheckVersion
553 );
554
555 ULONG
556 CdShortNameDirentOffset (
557 IN PIRP_CONTEXT IrpContext,
558 IN PUNICODE_STRING Name
559 );
560
561 FSRTL_COMPARISON_RESULT
562 CdFullCompareNames (
563 IN PIRP_CONTEXT IrpContext,
564 IN PUNICODE_STRING NameA,
565 IN PUNICODE_STRING NameB
566 );
567
568 \f
569 //
570 // Filesystem control operations. Implemented in Fsctrl.c
571 //
572
573 NTSTATUS
574 CdLockVolumeInternal (
575 IN PIRP_CONTEXT IrpContext,
576 IN PVCB Vcb,
577 IN PFILE_OBJECT FileObject OPTIONAL
578 );
579
580 NTSTATUS
581 CdUnlockVolumeInternal (
582 IN PIRP_CONTEXT IrpContext,
583 IN PVCB Vcb,
584 IN PFILE_OBJECT FileObject OPTIONAL
585 );
586
587 \f
588 //
589 // Path table enumeration routines. Implemented in PathSup.c
590 //
591
592 VOID
593 CdLookupPathEntry (
594 IN PIRP_CONTEXT IrpContext,
595 IN ULONG PathEntryOffset,
596 IN ULONG Ordinal,
597 IN BOOLEAN VerifyBounds,
598 IN OUT PCOMPOUND_PATH_ENTRY CompoundPathEntry
599 );
600
601 BOOLEAN
602 CdLookupNextPathEntry (
603 IN PIRP_CONTEXT IrpContext,
604 IN OUT PPATH_ENUM_CONTEXT PathContext,
605 IN OUT PPATH_ENTRY PathEntry
606 );
607
608 BOOLEAN
609 CdFindPathEntry (
610 IN PIRP_CONTEXT IrpContext,
611 IN PFCB ParentFcb,
612 IN PCD_NAME DirName,
613 IN BOOLEAN IgnoreCase,
614 IN OUT PCOMPOUND_PATH_ENTRY CompoundPathEntry
615 );
616
617 VOID
618 CdUpdatePathEntryName (
619 IN PIRP_CONTEXT IrpContext,
620 IN OUT PPATH_ENTRY PathEntry,
621 IN BOOLEAN IgnoreCase
622 );
623
624 //
625 // VOID
626 // CdInitializeCompoundPathEntry (
627 // IN PIRP_CONTEXT IrpContext,
628 // IN PCOMPOUND_PATH_ENTRY CompoundPathEntry
629 // );
630 //
631 // VOID
632 // CdCleanupCompoundPathEntry (
633 // IN PIRP_CONTEXT IrpContext,
634 // IN PCOMPOUND_PATH_ENTRY CompoundPathEntry
635 // );
636 //
637
638 #define CdInitializeCompoundPathEntry(IC,CP) \
639 RtlZeroMemory( CP, sizeof( COMPOUND_PATH_ENTRY ))
640
641 #define CdCleanupCompoundPathEntry(IC,CP) { \
642 CdUnpinData( (IC), &(CP)->PathContext.Bcb ); \
643 if ((CP)->PathContext.AllocatedData) { \
644 CdFreePool( &(CP)->PathContext.Data ); \
645 } \
646 if (FlagOn( (CP)->PathEntry.Flags, PATH_ENTRY_FLAG_ALLOC_BUFFER )) { \
647 CdFreePool( &(CP)->PathEntry.CdDirName.FileName.Buffer ); \
648 } \
649 }
650
651 \f
652 //
653 // Largest matching prefix searching routines, implemented in PrefxSup.c
654 //
655
656 VOID
657 CdInsertPrefix (
658 IN PIRP_CONTEXT IrpContext,
659 IN PFCB Fcb,
660 IN PCD_NAME Name,
661 IN BOOLEAN IgnoreCase,
662 IN BOOLEAN ShortNameMatch,
663 IN PFCB ParentFcb
664 );
665
666 VOID
667 CdRemovePrefix (
668 IN PIRP_CONTEXT IrpContext,
669 IN PFCB Fcb
670 );
671
672 VOID
673 CdFindPrefix (
674 IN PIRP_CONTEXT IrpContext,
675 IN OUT PFCB *CurrentFcb,
676 IN OUT PUNICODE_STRING RemainingName,
677 IN BOOLEAN IgnoreCase
678 );
679
680 \f
681 //
682 // Synchronization routines. Implemented in Resrcsup.c
683 //
684 // The following routines/macros are used to synchronize the in-memory structures.
685 //
686 // Routine/Macro Synchronizes Subsequent
687 //
688 // CdAcquireCdData Volume Mounts/Dismounts,Vcb Queue CdReleaseCdData
689 // CdAcquireVcbExclusive Vcb for open/close CdReleaseVcb
690 // CdAcquireVcbShared Vcb for open/close CdReleaseVcb
691 // CdAcquireAllFiles Locks out operations to all files CdReleaseAllFiles
692 // CdAcquireFileExclusive Locks out file operations CdReleaseFile
693 // CdAcquireFileShared Files for file operations CdReleaseFile
694 // CdAcquireFcbExclusive Fcb for open/close CdReleaseFcb
695 // CdAcquireFcbShared Fcb for open/close CdReleaseFcb
696 // CdLockCdData Fields in CdData CdUnlockCdData
697 // CdLockVcb Vcb fields, FcbReference, FcbTable CdUnlockVcb
698 // CdLockFcb Fcb fields, prefix table, Mcb CdUnlockFcb
699 //
700
701 typedef enum _TYPE_OF_ACQUIRE {
702
703 AcquireExclusive,
704 AcquireShared,
705 AcquireSharedStarveExclusive
706
707 } TYPE_OF_ACQUIRE, *PTYPE_OF_ACQUIRE;
708
709 BOOLEAN
710 CdAcquireResource (
711 IN PIRP_CONTEXT IrpContext,
712 IN PERESOURCE Resource,
713 IN BOOLEAN IgnoreWait,
714 IN TYPE_OF_ACQUIRE Type
715 );
716
717 //
718 // BOOLEAN
719 // CdAcquireCdData (
720 // IN PIRP_CONTEXT IrpContext
721 // );
722 //
723 // VOID
724 // CdReleaseCdData (
725 // IN PIRP_CONTEXT IrpContext
726 // );
727 //
728 // BOOLEAN
729 // CdAcquireVcbExclusive (
730 // IN PIRP_CONTEXT IrpContext,
731 // IN PVCB Vcb,
732 // IN BOOLEAN IgnoreWait
733 // );
734 //
735 // BOOLEAN
736 // CdAcquireVcbShared (
737 // IN PIRP_CONTEXT IrpContext,
738 // IN PVCB Vcb,
739 // IN BOOLEAN IgnoreWait
740 // );
741 //
742 // VOID
743 // CdReleaseVcb (
744 // IN PIRP_CONTEXT IrpContext,
745 // IN PVCB Vcb
746 // );
747 //
748 // VOID
749 // CdAcquireAllFiles (
750 // IN PIRP_CONTEXT,
751 // IN PVCB Vcb
752 // );
753 //
754 // VOID
755 // CdReleaseAllFiles (
756 // IN PIRP_CONTEXT,
757 // IN PVCB Vcb
758 // );
759 //
760 // VOID
761 // CdAcquireFileExclusive (
762 // IN PIRP_CONTEXT IrpContext,
763 // IN PFCB Fcb,
764 // );
765 //
766 // VOID
767 // CdAcquireFileShared (
768 // IN PIRP_CONTEXT IrpContext,
769 // IN PFCB Fcb
770 // );
771 //
772 // VOID
773 // CdReleaseFile (
774 // IN PIRP_CONTEXT IrpContext,
775 // IN PFCB Fcb
776 // );
777 //
778 // BOOLEAN
779 // CdAcquireFcbExclusive (
780 // IN PIRP_CONTEXT IrpContext,
781 // IN PFCB Fcb,
782 // IN BOOLEAN IgnoreWait
783 // );
784 //
785 // BOOLEAN
786 // CdAcquireFcbShared (
787 // IN PIRP_CONTEXT IrpContext,
788 // IN PFCB Fcb,
789 // IN BOOLEAN IgnoreWait
790 // );
791 //
792 // BOOLEAN
793 // CdReleaseFcb (
794 // IN PIRP_CONTEXT IrpContext,
795 // IN PFCB Fcb
796 // );
797 //
798 // VOID
799 // CdLockCdData (
800 // );
801 //
802 // VOID
803 // CdUnlockCdData (
804 // );
805 //
806 // VOID
807 // CdLockVcb (
808 // IN PIRP_CONTEXT IrpContext
809 // );
810 //
811 // VOID
812 // CdUnlockVcb (
813 // IN PIRP_CONTEXT IrpContext
814 // );
815 //
816 // VOID
817 // CdLockFcb (
818 // IN PIRP_CONTEXT IrpContext,
819 // IN PFCB Fcb
820 // );
821 //
822 // VOID
823 // CdUnlockFcb (
824 // IN PIRP_CONTEXT IrpContext,
825 // IN PFCB Fcb
826 // );
827 //
828
829 #define CdAcquireCdData(IC) \
830 ExAcquireResourceExclusiveLite( &CdData.DataResource, TRUE )
831
832 #define CdReleaseCdData(IC) \
833 ExReleaseResourceLite( &CdData.DataResource )
834
835 #define CdAcquireVcbExclusive(IC,V,I) \
836 CdAcquireResource( (IC), &(V)->VcbResource, (I), AcquireExclusive )
837
838 #define CdAcquireVcbShared(IC,V,I) \
839 CdAcquireResource( (IC), &(V)->VcbResource, (I), AcquireShared )
840
841 #define CdReleaseVcb(IC,V) \
842 ExReleaseResourceLite( &(V)->VcbResource )
843
844 #define CdAcquireAllFiles(IC,V) \
845 CdAcquireResource( (IC), &(V)->FileResource, FALSE, AcquireExclusive )
846
847 #define CdReleaseAllFiles(IC,V) \
848 ExReleaseResourceLite( &(V)->FileResource )
849
850 #define CdAcquireFileExclusive(IC,F) \
851 CdAcquireResource( (IC), (F)->Resource, FALSE, AcquireExclusive )
852
853 #define CdAcquireFileShared(IC,F) \
854 CdAcquireResource( (IC), (F)->Resource, FALSE, AcquireShared )
855
856 #define CdAcquireFileSharedStarveExclusive(IC,F) \
857 CdAcquireResource( (IC), (F)->Resource, FALSE, AcquireSharedStarveExclusive )
858
859 #define CdReleaseFile(IC,F) \
860 ExReleaseResourceLite( (F)->Resource )
861
862 #define CdAcquireFcbExclusive(IC,F,I) \
863 CdAcquireResource( (IC), &(F)->FcbNonpaged->FcbResource, (I), AcquireExclusive )
864
865 #define CdAcquireFcbShared(IC,F,I) \
866 CdAcquireResource( (IC), &(F)->FcbNonpaged->FcbResource, (I), AcquireShared )
867
868 #define CdReleaseFcb(IC,F) \
869 ExReleaseResourceLite( &(F)->FcbNonpaged->FcbResource )
870
871 #define CdLockCdData() \
872 ExAcquireFastMutex( &CdData.CdDataMutex ); \
873 CdData.CdDataLockThread = PsGetCurrentThread()
874
875 #define CdUnlockCdData() \
876 CdData.CdDataLockThread = NULL; \
877 ExReleaseFastMutex( &CdData.CdDataMutex )
878
879 #define CdLockVcb(IC,V) \
880 ExAcquireFastMutex( &(V)->VcbMutex ); \
881 ASSERT( NULL == (V)->VcbLockThread); \
882 (V)->VcbLockThread = PsGetCurrentThread()
883
884 #define CdUnlockVcb(IC,V) \
885 ASSERT( NULL != (V)->VcbLockThread); \
886 (V)->VcbLockThread = NULL; \
887 ExReleaseFastMutex( &(V)->VcbMutex )
888
889 #define CdLockFcb(IC,F) { \
890 PVOID _CurrentThread = PsGetCurrentThread(); \
891 if (_CurrentThread != (F)->FcbLockThread) { \
892 ExAcquireFastMutex( &(F)->FcbNonpaged->FcbMutex ); \
893 ASSERT( (F)->FcbLockCount == 0 ); \
894 (F)->FcbLockThread = _CurrentThread; \
895 } \
896 (F)->FcbLockCount += 1; \
897 }
898
899 #define CdUnlockFcb(IC,F) { \
900 (F)->FcbLockCount -= 1; \
901 if ((F)->FcbLockCount == 0) { \
902 (F)->FcbLockThread = NULL; \
903 ExReleaseFastMutex( &(F)->FcbNonpaged->FcbMutex ); \
904 } \
905 }
906
907 BOOLEAN
908 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
909 CdNoopAcquire (
910 IN PVOID Fcb,
911 IN BOOLEAN Wait
912 );
913
914 VOID
915 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
916 CdNoopRelease (
917 IN PVOID Fcb
918 );
919
920 BOOLEAN
921 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
922 CdAcquireForCache (
923 IN PFCB Fcb,
924 IN BOOLEAN Wait
925 );
926
927 VOID
928 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
929 CdReleaseFromCache (
930 IN PFCB Fcb
931 );
932
933 VOID
934 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
935 CdAcquireForCreateSection (
936 IN PFILE_OBJECT FileObject
937 );
938
939 VOID
940 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
941 CdReleaseForCreateSection (
942 IN PFILE_OBJECT FileObject
943 );
944
945 \f
946 //
947 // In-memory structure support routines. Implemented in StrucSup.c
948 //
949
950 VOID
951 CdInitializeVcb (
952 IN PIRP_CONTEXT IrpContext,
953 IN OUT PVCB Vcb,
954 IN PDEVICE_OBJECT TargetDeviceObject,
955 IN PVPB Vpb,
956 IN PCDROM_TOC CdromToc,
957 IN ULONG TocLength,
958 IN ULONG TocTrackCount,
959 IN ULONG TocDiskFlags,
960 IN ULONG BlockFactor,
961 IN ULONG MediaChangeCount
962 );
963
964 VOID
965 CdUpdateVcbFromVolDescriptor (
966 IN PIRP_CONTEXT IrpContext,
967 IN OUT PVCB Vcb,
968 IN PCHAR RawIsoVd OPTIONAL
969 );
970
971 VOID
972 CdDeleteVcb (
973 IN PIRP_CONTEXT IrpContext,
974 IN OUT PVCB Vcb
975 );
976
977 PFCB
978 CdCreateFcb (
979 IN PIRP_CONTEXT IrpContext,
980 IN FILE_ID FileId,
981 IN NODE_TYPE_CODE NodeTypeCode,
982 OUT PBOOLEAN FcbExisted OPTIONAL
983 );
984
985 VOID
986 CdInitializeFcbFromPathEntry (
987 IN PIRP_CONTEXT IrpContext,
988 IN PFCB Fcb,
989 IN PFCB ParentFcb OPTIONAL,
990 IN PPATH_ENTRY PathEntry
991 );
992
993 VOID
994 CdInitializeFcbFromFileContext (
995 IN PIRP_CONTEXT IrpContext,
996 IN PFCB Fcb,
997 IN PFCB ParentFcb OPTIONAL,
998 IN PFILE_ENUM_CONTEXT FileContext
999 );
1000
1001 PCCB
1002 CdCreateCcb (
1003 IN PIRP_CONTEXT IrpContext,
1004 IN PFCB Fcb,
1005 IN ULONG Flags
1006 );
1007
1008 VOID
1009 CdDeleteCcb (
1010 IN PIRP_CONTEXT IrpContext,
1011 IN PCCB Ccb
1012 );
1013
1014 BOOLEAN
1015 CdCreateFileLock (
1016 IN PIRP_CONTEXT IrpContext OPTIONAL,
1017 IN PFCB Fcb,
1018 IN BOOLEAN RaiseOnError
1019 );
1020
1021 VOID
1022 CdDeleteFileLock (
1023 IN PIRP_CONTEXT IrpContext,
1024 IN PFILE_LOCK FileLock
1025 );
1026
1027 PIRP_CONTEXT
1028 CdCreateIrpContext (
1029 IN PIRP Irp,
1030 IN BOOLEAN Wait
1031 );
1032
1033 VOID
1034 CdCleanupIrpContext (
1035 IN PIRP_CONTEXT IrpContext,
1036 IN BOOLEAN Post
1037 );
1038
1039 VOID
1040 CdInitializeStackIrpContext (
1041 OUT PIRP_CONTEXT IrpContext,
1042 IN PIRP_CONTEXT_LITE IrpContextLite
1043 );
1044
1045 //
1046 // PIRP_CONTEXT_LITE
1047 // CdCreateIrpContextLite (
1048 // IN PIRP_CONTEXT IrpContext
1049 // );
1050 //
1051 // VOID
1052 // CdFreeIrpContextLite (
1053 // IN PIRP_CONTEXT_LITE IrpContextLite
1054 // );
1055 //
1056
1057 #define CdCreateIrpContextLite(IC) \
1058 ExAllocatePoolWithTag( CdNonPagedPool, sizeof( IRP_CONTEXT_LITE ), TAG_IRP_CONTEXT_LITE )
1059
1060 #define CdFreeIrpContextLite(ICL) \
1061 CdFreePool( &(ICL) )
1062
1063 VOID
1064 CdTeardownStructures (
1065 IN PIRP_CONTEXT IrpContext,
1066 IN PFCB StartingFcb,
1067 OUT PBOOLEAN RemovedStartingFcb
1068 );
1069
1070 //
1071 // VOID
1072 // CdIncrementCleanupCounts (
1073 // IN PIRP_CONTEXT IrpContext,
1074 // IN PFCB Fcb
1075 // );
1076 //
1077 // VOID
1078 // CdDecrementCleanupCounts (
1079 // IN PIRP_CONTEXT IrpContext,
1080 // IN PFCB Fcb
1081 // );
1082 //
1083 // VOID
1084 // CdIncrementReferenceCounts (
1085 // IN PIRP_CONTEXT IrpContext,
1086 // IN PFCB Fcb,
1087 // IN ULONG ReferenceCount
1088 // IN ULONG UserReferenceCount
1089 // );
1090 //
1091 // VOID
1092 // CdDecrementReferenceCounts (
1093 // IN PIRP_CONTEXT IrpContext,
1094 // IN PFCB Fcb,
1095 // IN ULONG ReferenceCount
1096 // IN ULONG UserReferenceCount
1097 // );
1098 //
1099 // VOID
1100 // CdIncrementFcbReference (
1101 // IN PIRP_CONTEXT IrpContext,
1102 // IN PFCB Fcb
1103 // );
1104 //
1105 // VOID
1106 // CdDecrementFcbReference (
1107 // IN PIRP_CONTEXT IrpContext,
1108 // IN PFCB Fcb
1109 // );
1110 //
1111
1112 #define CdIncrementCleanupCounts(IC,F) { \
1113 ASSERT_LOCKED_VCB( (F)->Vcb ); \
1114 (F)->FcbCleanup += 1; \
1115 (F)->Vcb->VcbCleanup += 1; \
1116 }
1117
1118 #define CdDecrementCleanupCounts(IC,F) { \
1119 ASSERT_LOCKED_VCB( (F)->Vcb ); \
1120 (F)->FcbCleanup -= 1; \
1121 (F)->Vcb->VcbCleanup -= 1; \
1122 }
1123
1124 #define CdIncrementReferenceCounts(IC,F,C,UC) { \
1125 ASSERT_LOCKED_VCB( (F)->Vcb ); \
1126 (F)->FcbReference += (C); \
1127 (F)->FcbUserReference += (UC); \
1128 (F)->Vcb->VcbReference += (C); \
1129 (F)->Vcb->VcbUserReference += (UC); \
1130 }
1131
1132 #define CdDecrementReferenceCounts(IC,F,C,UC) { \
1133 ASSERT_LOCKED_VCB( (F)->Vcb ); \
1134 (F)->FcbReference -= (C); \
1135 (F)->FcbUserReference -= (UC); \
1136 (F)->Vcb->VcbReference -= (C); \
1137 (F)->Vcb->VcbUserReference -= (UC); \
1138 }
1139
1140 //
1141 // PCD_IO_CONTEXT
1142 // CdAllocateIoContext (
1143 // );
1144 //
1145 // VOID
1146 // CdFreeIoContext (
1147 // PCD_IO_CONTEXT IoContext
1148 // );
1149 //
1150
1151 #define CdAllocateIoContext() \
1152 FsRtlAllocatePoolWithTag( CdNonPagedPool, \
1153 sizeof( CD_IO_CONTEXT ), \
1154 TAG_IO_CONTEXT )
1155
1156 #define CdFreeIoContext(IO) CdFreePool( &(IO) )
1157
1158 PFCB
1159 CdLookupFcbTable (
1160 IN PIRP_CONTEXT IrpContext,
1161 IN PVCB Vcb,
1162 IN FILE_ID FileId
1163 );
1164
1165 PFCB
1166 CdGetNextFcb (
1167 IN PIRP_CONTEXT IrpContext,
1168 IN PVCB Vcb,
1169 IN PVOID *RestartKey
1170 );
1171
1172 NTSTATUS
1173 CdProcessToc (
1174 IN PIRP_CONTEXT IrpContext,
1175 IN PDEVICE_OBJECT TargetDeviceObject,
1176 IN PCDROM_TOC CdromToc,
1177 IN OUT PULONG Length,
1178 OUT PULONG TrackCount,
1179 OUT PULONG DiskFlags
1180 );
1181
1182 //
1183 // For debugging purposes we sometimes want to allocate our structures from nonpaged
1184 // pool so that in the kernel debugger we can walk all the structures.
1185 //
1186
1187 #define CdPagedPool PagedPool
1188 #define CdNonPagedPool NonPagedPool
1189 #define CdNonPagedPoolCacheAligned NonPagedPoolCacheAligned
1190
1191
1192 //
1193 // Verification support routines. Contained in verfysup.c
1194 //
1195
1196 /* ReactOS Change: "LD multiple definition of `_CdOperationIsDasdOpen'" */
1197 static inline
1198 BOOLEAN
1199 CdOperationIsDasdOpen(
1200 IN PIRP_CONTEXT IrpContext
1201 )
1202 {
1203 PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( IrpContext->Irp);
1204
1205 return ((IrpContext->MajorFunction == IRP_MJ_CREATE) &&
1206 (IrpSp->FileObject->FileName.Length == 0) &&
1207 (IrpSp->FileObject->RelatedFileObject == NULL));
1208 }
1209
1210
1211 NTSTATUS
1212 CdPerformVerify (
1213 IN PIRP_CONTEXT IrpContext,
1214 IN PIRP Irp,
1215 IN PDEVICE_OBJECT DeviceToVerify
1216 );
1217
1218 BOOLEAN
1219 CdCheckForDismount (
1220 IN PIRP_CONTEXT IrpContext,
1221 IN PVCB,
1222 IN BOOLEAN Force
1223 );
1224
1225 VOID
1226 CdVerifyVcb (
1227 IN PIRP_CONTEXT IrpContext,
1228 IN PVCB Vcb
1229 );
1230
1231 BOOLEAN
1232 CdVerifyFcbOperation (
1233 IN PIRP_CONTEXT IrpContext OPTIONAL,
1234 IN PFCB Fcb
1235 );
1236
1237 BOOLEAN
1238 CdDismountVcb (
1239 IN PIRP_CONTEXT IrpContext,
1240 IN PVCB Vcb
1241 );
1242
1243
1244 //
1245 // Macros to abstract device verify flag changes.
1246 //
1247
1248 #define CdUpdateMediaChangeCount( V, C) (V)->MediaChangeCount = (C)
1249 #define CdUpdateVcbCondition( V, C) (V)->VcbCondition = (C)
1250
1251 #define CdMarkRealDevForVerify( DO) SetFlag( (DO)->Flags, DO_VERIFY_VOLUME)
1252
1253 #define CdMarkRealDevVerifyOk( DO) ClearFlag( (DO)->Flags, DO_VERIFY_VOLUME)
1254
1255
1256 #define CdRealDevNeedsVerify( DO) BooleanFlagOn( (DO)->Flags, DO_VERIFY_VOLUME)
1257
1258 //
1259 // BOOLEAN
1260 // CdIsRawDevice (
1261 // IN PIRP_CONTEXT IrpContext,
1262 // IN NTSTATUS Status
1263 // );
1264 //
1265
1266 #define CdIsRawDevice(IC,S) ( \
1267 ((S) == STATUS_DEVICE_NOT_READY) || \
1268 ((S) == STATUS_NO_MEDIA_IN_DEVICE) \
1269 )
1270
1271 \f
1272 //
1273 // Work queue routines for posting and retrieving an Irp, implemented in
1274 // workque.c
1275 //
1276
1277 NTSTATUS
1278 CdFsdPostRequest(
1279 IN PIRP_CONTEXT IrpContext,
1280 IN PIRP Irp
1281 );
1282
1283 VOID
1284 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
1285 CdPrePostIrp (
1286 IN PIRP_CONTEXT IrpContext,
1287 IN PIRP Irp
1288 );
1289
1290 VOID
1291 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
1292 CdOplockComplete (
1293 IN PIRP_CONTEXT IrpContext,
1294 IN PIRP Irp
1295 );
1296
1297 \f
1298 //
1299 // Miscellaneous support routines
1300 //
1301
1302 //
1303 // This macro returns TRUE if a flag in a set of flags is on and FALSE
1304 // otherwise
1305 //
1306
1307 /* ReactOS Change: GCC doesn't understand the comment style */
1308 /*
1309 //#ifndef BooleanFlagOn
1310 //#define BooleanFlagOn(F,SF) ( \
1311 // (BOOLEAN)(((F) & (SF)) != 0) \
1312 //)
1313 //#endif
1314
1315 //#ifndef SetFlag
1316 //#define SetFlag(Flags,SingleFlag) { \
1317 // (Flags) |= (SingleFlag); \
1318 //}
1319 //#endif
1320
1321 //#ifndef ClearFlag
1322 //#define ClearFlag(Flags,SingleFlag) { \
1323 // (Flags) &= ~(SingleFlag); \
1324 //}
1325 //#endif
1326 */
1327
1328 //
1329 // CAST
1330 // Add2Ptr (
1331 // IN PVOID Pointer,
1332 // IN ULONG Increment
1333 // IN (CAST)
1334 // );
1335 //
1336 // ULONG
1337 // PtrOffset (
1338 // IN PVOID BasePtr,
1339 // IN PVOID OffsetPtr
1340 // );
1341 //
1342
1343 #define Add2Ptr(PTR,INC,CAST) ((CAST)((PUCHAR)(PTR) + (INC)))
1344
1345 #define PtrOffset(BASE,OFFSET) ((ULONG)((ULONG_PTR)(OFFSET) - (ULONG_PTR)(BASE)))
1346
1347 //
1348 // This macro takes a pointer (or ulong) and returns its rounded up word
1349 // value
1350 //
1351
1352 #define WordAlign(Ptr) ( \
1353 ((((ULONG)(Ptr)) + 1) & 0xfffffffe) \
1354 )
1355
1356 //
1357 // This macro takes a pointer (or ulong) and returns its rounded up longword
1358 // value
1359 //
1360
1361 #define LongAlign(Ptr) ( \
1362 ((((ULONG)(Ptr)) + 3) & 0xfffffffc) \
1363 )
1364
1365 //
1366 // This macro takes a pointer (or ulong) and returns its rounded up quadword
1367 // value
1368 //
1369
1370 #define QuadAlign(Ptr) ( \
1371 ((((ULONG)(Ptr)) + 7) & 0xfffffff8) \
1372 )
1373
1374 //
1375 // The following macros round up and down to sector boundaries.
1376 //
1377
1378 #define SectorAlign(L) ( \
1379 ((((ULONG)(L)) + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1)) \
1380 )
1381
1382 #define LlSectorAlign(L) ( \
1383 ((((LONGLONG)(L)) + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1)) \
1384 )
1385
1386 #define SectorTruncate(L) ( \
1387 ((ULONG)(L)) & ~(SECTOR_SIZE - 1) \
1388 )
1389
1390 #define LlSectorTruncate(L) ( \
1391 ((LONGLONG)(L)) & ~(SECTOR_SIZE - 1) \
1392 )
1393
1394 #define BytesFromSectors(L) ( \
1395 ((ULONG) (L)) << SECTOR_SHIFT \
1396 )
1397
1398 #define SectorsFromBytes(L) ( \
1399 ((ULONG) (L)) >> SECTOR_SHIFT \
1400 )
1401
1402 #define LlBytesFromSectors(L) ( \
1403 Int64ShllMod32( (LONGLONG)(L), SECTOR_SHIFT ) \
1404 )
1405
1406 #define LlSectorsFromBytes(L) ( \
1407 Int64ShraMod32( (LONGLONG)(L), SECTOR_SHIFT ) \
1408 )
1409
1410 #define SectorOffset(L) ( \
1411 ((ULONG)(ULONG_PTR) (L)) & SECTOR_MASK \
1412 )
1413
1414 #define SectorBlockOffset(V,LB) ( \
1415 ((ULONG) (LB)) & ((V)->BlocksPerSector - 1) \
1416 )
1417
1418 #define BytesFromBlocks(V,B) ( \
1419 (ULONG) (B) << (V)->BlockToByteShift \
1420 )
1421
1422 #define LlBytesFromBlocks(V,B) ( \
1423 Int64ShllMod32( (LONGLONG) (B), (V)->BlockToByteShift ) \
1424 )
1425
1426 #define BlockAlign(V,L) ( \
1427 ((ULONG)(L) + (V)->BlockMask) & (V)->BlockInverseMask \
1428 )
1429
1430 //
1431 // Carefully make sure the mask is sign extended to 64bits
1432 //
1433
1434 #define LlBlockAlign(V,L) ( \
1435 ((LONGLONG)(L) + (V)->BlockMask) & (LONGLONG)((LONG)(V)->BlockInverseMask) \
1436 )
1437
1438 #define BlockOffset(V,L) ( \
1439 ((ULONG) (L)) & (V)->BlockMask \
1440 )
1441
1442 #define RawSectorAlign( B) ((((B)+(RAW_SECTOR_SIZE - 1)) / RAW_SECTOR_SIZE) * RAW_SECTOR_SIZE)
1443
1444 //
1445 // The following types and macros are used to help unpack the packed and
1446 // misaligned fields found in the Bios parameter block
1447 //
1448
1449 typedef union _UCHAR1 {
1450 UCHAR Uchar[1];
1451 UCHAR ForceAlignment;
1452 } UCHAR1, *PUCHAR1;
1453
1454 typedef union _UCHAR2 {
1455 UCHAR Uchar[2];
1456 USHORT ForceAlignment;
1457 } UCHAR2, *PUCHAR2;
1458
1459 typedef union _UCHAR4 {
1460 UCHAR Uchar[4];
1461 ULONG ForceAlignment;
1462 } UCHAR4, *PUCHAR4;
1463
1464 typedef union _USHORT2 {
1465 USHORT Ushort[2];
1466 ULONG ForceAlignment;
1467 } USHORT2, *PUSHORT2;
1468
1469 //
1470 // This macro copies an unaligned src byte to an aligned dst byte
1471 //
1472
1473 #define CopyUchar1(Dst,Src) { \
1474 *((UCHAR1 *)(Dst)) = *((UNALIGNED UCHAR1 *)(Src)); \
1475 }
1476
1477 //
1478 // This macro copies an unaligned src word to an aligned dst word
1479 //
1480
1481 #define CopyUchar2(Dst,Src) { \
1482 *((UCHAR2 *)(Dst)) = *((UNALIGNED UCHAR2 *)(Src)); \
1483 }
1484
1485 //
1486 // This macro copies an unaligned src longword to an aligned dsr longword
1487 //
1488
1489 #define CopyUchar4(Dst,Src) { \
1490 *((UCHAR4 *)(Dst)) = *((UNALIGNED UCHAR4 *)(Src)); \
1491 }
1492
1493 //
1494 // This macro copies an unaligned src longword to an aligned dsr longword
1495 // accessing the source on a word boundary.
1496 //
1497
1498 #define CopyUshort2(Dst,Src) { \
1499 *((USHORT2 *)(Dst)) = *((UNALIGNED USHORT2 *)(Src));\
1500 }
1501
1502 \f
1503 //
1504 // Following routines handle entry in and out of the filesystem. They are
1505 // contained in CdData.c
1506 //
1507
1508 NTSTATUS
1509 CdFsdDispatch (
1510 IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
1511 IN PIRP Irp
1512 );
1513
1514 LONG
1515 CdExceptionFilter (
1516 IN PIRP_CONTEXT IrpContext,
1517 IN PEXCEPTION_POINTERS ExceptionPointer
1518 );
1519
1520 NTSTATUS
1521 CdProcessException (
1522 IN PIRP_CONTEXT IrpContext OPTIONAL,
1523 IN PIRP Irp,
1524 IN NTSTATUS ExceptionCode
1525 );
1526
1527 VOID
1528 CdCompleteRequest (
1529 IN PIRP_CONTEXT IrpContext OPTIONAL,
1530 IN PIRP Irp OPTIONAL,
1531 IN NTSTATUS Status
1532 );
1533
1534 //
1535 // VOID
1536 // CdRaiseStatus (
1537 // IN PRIP_CONTEXT IrpContext,
1538 // IN NT_STATUS Status
1539 // );
1540 //
1541 // VOID
1542 // CdNormalizeAndRaiseStatus (
1543 // IN PRIP_CONTEXT IrpContext,
1544 // IN NT_STATUS Status
1545 // );
1546 //
1547
1548 #if 0
1549 #define AssertVerifyDevice(C, S) \
1550 ASSERT( (C) == NULL || \
1551 FlagOn( (C)->Flags, IRP_CONTEXT_FLAG_IN_FSP ) || \
1552 !((S) == STATUS_VERIFY_REQUIRED && \
1553 IoGetDeviceToVerify( PsGetCurrentThread() ) == NULL ));
1554
1555 #define AssertVerifyDeviceIrp(I) \
1556 ASSERT( (I) == NULL || \
1557 !(((I)->IoStatus.Status) == STATUS_VERIFY_REQUIRED && \
1558 ((I)->Tail.Overlay.Thread == NULL || \
1559 IoGetDeviceToVerify( (I)->Tail.Overlay.Thread ) == NULL )));
1560 #else
1561 #define AssertVerifyDevice(C, S)
1562 #define AssertVerifyDeviceIrp(I)
1563 #endif
1564
1565
1566 #ifdef CD_SANITY
1567
1568 DECLSPEC_NORETURN
1569 VOID
1570 CdRaiseStatusEx(
1571 IN PIRP_CONTEXT IrpContext,
1572 IN NTSTATUS Status,
1573 IN BOOLEAN NormalizeStatus,
1574 IN OPTIONAL ULONG FileId,
1575 IN OPTIONAL ULONG Line
1576 );
1577
1578 #else
1579
1580 INLINE
1581 DECLSPEC_NORETURN
1582 VOID
1583 CdRaiseStatusEx(
1584 IN PIRP_CONTEXT IrpContext,
1585 IN NTSTATUS Status,
1586 IN BOOLEAN NormalizeStatus,
1587 IN ULONG Fileid,
1588 IN ULONG Line
1589 )
1590 {
1591 if (NormalizeStatus) {
1592
1593 IrpContext->ExceptionStatus = FsRtlNormalizeNtstatus( Status, STATUS_UNEXPECTED_IO_ERROR);
1594 }
1595 else {
1596
1597 IrpContext->ExceptionStatus = Status;
1598 }
1599
1600 IrpContext->RaisedAtLineFile = (Fileid << 16) | Line;
1601
1602 ExRaiseStatus( IrpContext->ExceptionStatus );
1603 }
1604
1605 #endif
1606
1607 #define CdRaiseStatus( IC, S) CdRaiseStatusEx( (IC), (S), FALSE, BugCheckFileId, __LINE__);
1608 #define CdNormalizeAndRaiseStatus( IC, S) CdRaiseStatusEx( (IC), (S), TRUE, BugCheckFileId, __LINE__);
1609
1610 //
1611 // Following are the fast entry points.
1612 //
1613
1614 BOOLEAN
1615 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
1616 CdFastQueryBasicInfo (
1617 IN PFILE_OBJECT FileObject,
1618 IN BOOLEAN Wait,
1619 IN OUT PFILE_BASIC_INFORMATION Buffer,
1620 OUT PIO_STATUS_BLOCK IoStatus,
1621 IN PDEVICE_OBJECT DeviceObject
1622 );
1623
1624 BOOLEAN
1625 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
1626 CdFastQueryStdInfo (
1627 IN PFILE_OBJECT FileObject,
1628 IN BOOLEAN Wait,
1629 IN OUT PFILE_STANDARD_INFORMATION Buffer,
1630 OUT PIO_STATUS_BLOCK IoStatus,
1631 IN PDEVICE_OBJECT DeviceObject
1632 );
1633
1634 BOOLEAN
1635 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
1636 CdFastLock (
1637 IN PFILE_OBJECT FileObject,
1638 IN PLARGE_INTEGER FileOffset,
1639 IN PLARGE_INTEGER Length,
1640 PEPROCESS ProcessId,
1641 ULONG Key,
1642 BOOLEAN FailImmediately,
1643 BOOLEAN ExclusiveLock,
1644 OUT PIO_STATUS_BLOCK IoStatus,
1645 IN PDEVICE_OBJECT DeviceObject
1646 );
1647
1648 BOOLEAN
1649 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
1650 CdFastUnlockSingle (
1651 IN PFILE_OBJECT FileObject,
1652 IN PLARGE_INTEGER FileOffset,
1653 IN PLARGE_INTEGER Length,
1654 PEPROCESS ProcessId,
1655 ULONG Key,
1656 OUT PIO_STATUS_BLOCK IoStatus,
1657 IN PDEVICE_OBJECT DeviceObject
1658 );
1659
1660 BOOLEAN
1661 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
1662 CdFastUnlockAll (
1663 IN PFILE_OBJECT FileObject,
1664 PEPROCESS ProcessId,
1665 OUT PIO_STATUS_BLOCK IoStatus,
1666 IN PDEVICE_OBJECT DeviceObject
1667 );
1668
1669 BOOLEAN
1670 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
1671 CdFastUnlockAllByKey (
1672 IN PFILE_OBJECT FileObject,
1673 PVOID ProcessId,
1674 ULONG Key,
1675 OUT PIO_STATUS_BLOCK IoStatus,
1676 IN PDEVICE_OBJECT DeviceObject
1677 );
1678
1679 BOOLEAN
1680 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
1681 CdFastIoCheckIfPossible (
1682 IN PFILE_OBJECT FileObject,
1683 IN PLARGE_INTEGER FileOffset,
1684 IN ULONG Length,
1685 IN BOOLEAN Wait,
1686 IN ULONG LockKey,
1687 IN BOOLEAN CheckForReadOperation,
1688 OUT PIO_STATUS_BLOCK IoStatus,
1689 IN PDEVICE_OBJECT DeviceObject
1690 );
1691
1692 BOOLEAN
1693 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
1694 CdFastQueryNetworkInfo (
1695 IN PFILE_OBJECT FileObject,
1696 IN BOOLEAN Wait,
1697 OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
1698 OUT PIO_STATUS_BLOCK IoStatus,
1699 IN PDEVICE_OBJECT DeviceObject
1700 );
1701
1702 //
1703 // Following are the routines to handle the top level thread logic.
1704 //
1705
1706 VOID
1707 CdSetThreadContext (
1708 IN PIRP_CONTEXT IrpContext,
1709 IN PTHREAD_CONTEXT ThreadContext
1710 );
1711
1712
1713 //
1714 // VOID
1715 // CdRestoreThreadContext (
1716 // IN PIRP_CONTEXT IrpContext
1717 // );
1718 //
1719
1720 #define CdRestoreThreadContext(IC) \
1721 (IC)->ThreadContext->Cdfs = 0; \
1722 IoSetTopLevelIrp( (IC)->ThreadContext->SavedTopLevelIrp ); \
1723 (IC)->ThreadContext = NULL
1724
1725 ULONG
1726 CdSerial32 (
1727 IN PCHAR Buffer,
1728 IN ULONG ByteCount
1729 );
1730
1731 //
1732 // The following macro is used to determine if an FSD thread can block
1733 // for I/O or wait for a resource. It returns TRUE if the thread can
1734 // block and FALSE otherwise. This attribute can then be used to call
1735 // the FSD & FSP common work routine with the proper wait value.
1736 //
1737
1738 #define CanFsdWait(I) IoIsOperationSynchronous(I)
1739
1740 //
1741 // The following macro is used to set the fast i/o possible bits in the
1742 // FsRtl header.
1743 //
1744 // FastIoIsNotPossible - If the Fcb is bad or there are oplocks on the file.
1745 //
1746 // FastIoIsQuestionable - If there are file locks.
1747 //
1748 // FastIoIsPossible - In all other cases.
1749 //
1750 //
1751
1752 #define CdIsFastIoPossible(F) ((BOOLEAN) \
1753 ((((F)->Vcb->VcbCondition != VcbMounted ) || \
1754 !FsRtlOplockIsFastIoPossible( &(F)->Oplock )) ? \
1755 \
1756 FastIoIsNotPossible : \
1757 \
1758 ((((F)->FileLock != NULL) && FsRtlAreThereCurrentFileLocks( (F)->FileLock )) ? \
1759 \
1760 FastIoIsQuestionable : \
1761 \
1762 FastIoIsPossible)) \
1763 )
1764
1765 \f
1766 //
1767 // The FSP level dispatch/main routine. This is the routine that takes
1768 // IRP's off of the work queue and calls the appropriate FSP level
1769 // work routine.
1770 //
1771
1772 VOID
1773 CdFspDispatch ( // implemented in FspDisp.c
1774 IN PIRP_CONTEXT IrpContext
1775 );
1776
1777 VOID
1778 CdFspClose ( // implemented in Close.c
1779 IN PVCB Vcb OPTIONAL
1780 );
1781
1782 //
1783 // The following routines are the entry points for the different operations
1784 // based on the IrpSp major functions.
1785 //
1786
1787 NTSTATUS
1788 CdCommonCreate ( // Implemented in Create.c
1789 IN PIRP_CONTEXT IrpContext,
1790 IN PIRP Irp
1791 );
1792
1793 NTSTATUS
1794 CdCommonClose ( // Implemented in Close.c
1795 IN PIRP_CONTEXT IrpContext,
1796 IN PIRP Irp
1797 );
1798
1799 NTSTATUS
1800 CdCommonRead ( // Implemented in Read.c
1801 IN PIRP_CONTEXT IrpContext,
1802 IN PIRP Irp
1803 );
1804
1805 NTSTATUS
1806 CdCommonQueryInfo ( // Implemented in FileInfo.c
1807 IN PIRP_CONTEXT IrpContext,
1808 IN PIRP Irp
1809 );
1810
1811 NTSTATUS
1812 CdCommonSetInfo ( // Implemented in FileInfo.c
1813 IN PIRP_CONTEXT IrpContext,
1814 IN PIRP Irp
1815 );
1816
1817 NTSTATUS
1818 CdCommonQueryVolInfo ( // Implemented in VolInfo.c
1819 IN PIRP_CONTEXT IrpContext,
1820 IN PIRP Irp
1821 );
1822
1823 NTSTATUS
1824 CdCommonDirControl ( // Implemented in DirCtrl.c
1825 IN PIRP_CONTEXT IrpContext,
1826 IN PIRP Irp
1827 );
1828
1829 NTSTATUS
1830 CdCommonFsControl ( // Implemented in FsCtrl.c
1831 IN PIRP_CONTEXT IrpContext,
1832 IN PIRP Irp
1833 );
1834
1835 NTSTATUS
1836 CdCommonDevControl ( // Implemented in DevCtrl.c
1837 IN PIRP_CONTEXT IrpContext,
1838 IN PIRP Irp
1839 );
1840
1841 NTSTATUS
1842 CdCommonLockControl ( // Implemented in LockCtrl.c
1843 IN PIRP_CONTEXT IrpContext,
1844 IN PIRP Irp
1845 );
1846
1847 NTSTATUS
1848 CdCommonCleanup ( // Implemented in Cleanup.c
1849 IN PIRP_CONTEXT IrpContext,
1850 IN PIRP Irp
1851 );
1852
1853 NTSTATUS
1854 CdCommonPnp ( // Implemented in Pnp.c
1855 IN PIRP_CONTEXT IrpContext,
1856 IN PIRP Irp
1857 );
1858
1859 \f
1860 //
1861 // The following macros are used to establish the semantics needed
1862 // to do a return from within a try-finally clause. As a rule every
1863 // try clause must end with a label call try_exit. For example,
1864 //
1865 // try {
1866 // :
1867 // :
1868 //
1869 // try_exit: NOTHING;
1870 // } finally {
1871 //
1872 // :
1873 // :
1874 // }
1875 //
1876 // Every return statement executed inside of a try clause should use the
1877 // try_return macro. If the compiler fully supports the try-finally construct
1878 // then the macro should be
1879 //
1880 // #define try_return(S) { return(S); }
1881 //
1882 // If the compiler does not support the try-finally construct then the macro
1883 // should be
1884 //
1885 // #define try_return(S) { S; goto try_exit; }
1886 //
1887
1888 #ifndef __REACTOS__
1889 #define try_return(S) { S; goto try_exit; }
1890 #define try_leave(S) { S; leave; }
1891 #else
1892 #define try_return(S) { S; goto try_exit; }
1893 #define try_leave(S) { S; _SEH2_LEAVE; }
1894 #endif
1895
1896
1897 //
1898 // Encapsulate safe pool freeing
1899 //
1900 /* ReactOS Change: GCC "passing argument 1 of CdFreePool from incompatible pointer type" */
1901 #define CdFreePool(x) _CdFreePool((PVOID*)(x))
1902
1903 /* ReactOS Change: "LD multiple definition of `_CdOperationIsDasdOpen'" */
1904 static inline void _CdFreePool(
1905 IN PVOID *Pool
1906 )
1907 {
1908 if (*Pool != NULL) {
1909
1910 ExFreePool(*Pool);
1911 *Pool = NULL;
1912 }
1913 }
1914
1915 #endif // _CDPROCS_
1916
1917