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