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