Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

udfprocs.h

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1989 Microsoft Corporation 00004 00005 Module Name: 00006 00007 UdfProcs.h 00008 00009 Abstract: 00010 00011 This module defines all of the globally used procedures in the Udfs 00012 file system. 00013 00014 Author: 00015 00016 Dan Lovinger [DanLo] 29-May-1996 00017 00018 Revision History: 00019 00020 --*/ 00021 00022 #ifndef _UDFPROCS_ 00023 #define _UDFPROCS_ 00024 00025 #include <ntifs.h> 00026 00027 #include <ntddcdrm.h> 00028 #include <ntddcdvd.h> 00029 #include <ntdddisk.h> 00030 00031 #ifndef INLINE 00032 #define INLINE __inline 00033 #endif 00034 00035 #include "nodetype.h" 00036 #include "Udf.h" 00037 #include "UdfStruc.h" 00038 #include "UdfData.h" 00039 00040 // 00041 // The Bug check file id for this module 00042 // 00043 00044 #define BugCheckFileId (UDFS_BUG_CHECK_STRUCSUP) 00045 00046 // 00047 // The local debug trace level 00048 // 00049 00050 #define Dbg (UDFS_DEBUG_LEVEL_STRUCSUP) 00051 00052 00053 // 00054 // Miscellaneous support routines/macros 00055 // 00056 00057 // 00058 // Yet another declaration of Min/Max 00059 // 00060 00061 #define Min(a, b) ((a) < (b) ? (a) : (b)) 00062 #define Max(a, b) ((a) > (b) ? (a) : (b)) 00063 00064 // 00065 // Yet another declaration of the basic bit fiddlers 00066 // 00067 00068 #define FlagMask(F,SF) ( \ 00069 ((F) & (SF)) \ 00070 ) 00071 00072 #define BooleanFlagOn(F,SF) ( \ 00073 (BOOLEAN)(FlagOn(F, SF) != 0) \ 00074 ) 00075 00076 #define BooleanFlagOff(F,SF) ( \ 00077 (BOOLEAN)(FlagOn(F, SF)) == 0) \ 00078 ) 00079 00080 #define SetFlag(Flags,SingleFlag) ( \ 00081 (Flags) |= (SingleFlag) \ 00082 ) 00083 00084 #define ClearFlag(Flags,SingleFlag) ( \ 00085 (Flags) &= ~(SingleFlag) \ 00086 ) 00087 00088 // 00089 // CAST 00090 // Add2Ptr ( 00091 // IN PVOID Pointer, 00092 // IN ULONG Increment 00093 // IN (CAST) 00094 // ); 00095 // 00096 // ULONG 00097 // PtrOffset ( 00098 // IN PVOID BasePtr, 00099 // IN PVOID OffsetPtr 00100 // ); 00101 // 00102 00103 #define Add2Ptr(PTR,INC,CAST) ((CAST)((ULONG_PTR)(PTR) + (INC))) 00104 00105 #define PtrOffset(BASE,OFFSET) ((ULONG)((ULONG)(OFFSET) - (ULONG)(BASE))) 00106 00107 // 00108 // Generic truncation/align/offset/remainder macros for power-of-two units. 00109 // 00110 // The offset and remainder functions range from zero to (unit - 1). The 00111 // re-offset in the remainder performs this work. 00112 // 00113 00114 #define GenericTruncate(B, U) ( \ 00115 (B) & ~((U) - 1) \ 00116 ) 00117 00118 #define GenericAlign(B, U) ( \ 00119 GenericTruncate((B) + (U) - 1, U) \ 00120 ) 00121 00122 #define GenericOffset(B, U) ( \ 00123 (B) & ((U) - 1) \ 00124 ) 00125 00126 #define GenericRemainder(B, U) ( \ 00127 GenericOffset( (U) - GenericOffset((B), (U)), (U) ) \ 00128 ) 00129 00130 00131 #define GenericTruncatePtr(B, U) ( \ 00132 (PVOID)(((ULONG_PTR)(B)) & ~((U) - 1)) \ 00133 ) 00134 00135 #define GenericAlignPtr(B, U) ( \ 00136 GenericTruncatePtr((B) + (U) - 1, (U)) \ 00137 ) 00138 00139 #define GenericOffsetPtr(B, U) ( \ 00140 (ULONG)(((ULONG_PTR)(B)) & ((U) - 1)) \ 00141 ) 00142 00143 #define GenericRemainderPtr(B, U) ( \ 00144 (ULONG)GenericOffset( (U) - GenericOffsetPtr((B), (U)), (U) ) \ 00145 ) 00146 00147 // 00148 // Useful compositions of the defaults for common types. 00149 // 00150 00151 #define WordAlign(B) GenericAlign((B), 2) 00152 00153 #define LongAlign(B) GenericAlign((B), 4) 00154 00155 #define QuadAlign(B) GenericAlign((B), 8) 00156 00157 00158 #define WordOffset(B) GenericOffset((B), 2) 00159 00160 #define LongOffset(B) GenericOffset((B), 4) 00161 00162 #define QuadOffset(B) GenericOffset((B), 8) 00163 00164 00165 #define WordAlignPtr(P) GenericAlignPtr((P), 2) 00166 00167 #define LongAlignPtr(P) GenericAlignPtr((P), 4) 00168 00169 #define QuadAlignPtr(P) GenericAlignPtr((P), 8) 00170 00171 00172 #define WordOffsetPtr(P) GenericOffsetPtr((P), 2) 00173 00174 #define LongOffsetPtr(P) GenericOffsetPtr((P), 4) 00175 00176 #define QuadOffsetPtr(P) GenericOffsetPtr((P), 8) 00177 00178 00179 // 00180 // Macros to round up and down on sector and logical block boundaries. Although 00181 // UDF 1.01 specifies that a physical sector is the logical block size we will 00182 // be general and treat sectors and logical blocks as distinct. Since UDF may 00183 // at some point relax the restriction, these definitions will be the only 00184 // acknowledgement outside of the mount path (which merely checks the volume's 00185 // conformance). 00186 // 00187 00188 // 00189 // Sector 00190 // 00191 00192 #define SectorAlignN(SECTORSIZE, L) ( \ 00193 ((((ULONG)(L)) + ((SECTORSIZE) - 1)) & ~((SECTORSIZE) - 1)) \ 00194 ) 00195 00196 #define SectorAlign(V, L) ( \ 00197 ((((ULONG)(L)) + (((V)->SectorSize) - 1)) & ~(((V)->SectorSize) - 1)) \ 00198 ) 00199 00200 #define LlSectorAlign(V, L) ( \ 00201 ((((LONGLONG)(L)) + (((V)->SectorSize) - 1)) & ~(((LONGLONG)(V)->SectorSize) - 1)) \ 00202 ) 00203 00204 #define SectorTruncate(V, L) ( \ 00205 ((ULONG)(L)) & ~(((V)->SectorSize) - 1) \ 00206 ) 00207 00208 #define LlSectorTruncate(V, L) ( \ 00209 ((LONGLONG)(L)) & ~(((LONGLONG)(V)->SectorSize) - 1) \ 00210 ) 00211 00212 #define BytesFromSectors(V, L) ( \ 00213 ((ULONG) (L)) << ((V)->SectorShift) \ 00214 ) 00215 00216 #define SectorsFromBytes(V, L) ( \ 00217 ((ULONG) (L)) >> ((V)->SectorShift) \ 00218 ) 00219 00220 #define LlBytesFromSectors(V, L) ( \ 00221 Int64ShllMod32( (ULONGLONG)(L), ((V)->SectorShift) ) \ 00222 ) 00223 00224 #define LlSectorsFromBytes(V, L) ( \ 00225 Int64ShrlMod32( (ULONGLONG)(L), ((V)->SectorShift) ) \ 00226 ) 00227 00228 #define SectorsFromBlocks(V, B) (B) 00229 00230 #define SectorSize(V) ((V)->SectorSize) 00231 00232 #define SectorOffset(V, L) ( \ 00233 ((ULONG) (L)) & (((V)->SectorSize) - 1) \ 00234 ) 00235 00236 // 00237 // Logical Block 00238 // 00239 00240 #define BlockAlignN(BLOCKSIZE, L) ( \ 00241 SectorAlighN((BLOCKSIZE), (L)) \ 00242 ) 00243 00244 #define BlockAlign(V, L) ( \ 00245 SectorAlign((V), (L)) \ 00246 ) 00247 00248 #define LlBlockAlign(V, L) ( \ 00249 LlSectorAlign((V), (L)) \ 00250 ) 00251 00252 #define BlockTruncate(V, L) ( \ 00253 SectorTruncate((V), (L)) \ 00254 ) 00255 00256 #define LlBlockTruncate(V, L) ( \ 00257 LlSectorTruncate((V), (L)) \ 00258 ) 00259 00260 #define BytesFromBlocks(V, L) ( \ 00261 BytesFromSectors((V), (L)) \ 00262 ) 00263 00264 #define BlocksFromBytes(V, L) ( \ 00265 SectorsFromBytes((V), (L)) \ 00266 ) 00267 00268 #define LlBytesFromBlocks(V, L) ( \ 00269 LlBytesFromSectors((V), (L)) \ 00270 ) 00271 00272 #define LlBlocksFromBytes(V, L) ( \ 00273 LlSectorsFromBytes((V), (L)) \ 00274 ) 00275 00276 #define BlocksFromSectors(V, S) (S) 00277 00278 #define BlockSize(V) (SectorSize(V)) 00279 00280 #define BlockOffset(V, L) ( \ 00281 SectorOffset((V), (L)) \ 00282 ) 00283 00284 // 00285 // The following types and macros are used to help unpack the packed and 00286 // misaligned fields found in various structures. 00287 // 00288 00289 typedef union _UCHAR1 { 00290 UCHAR Uchar[1]; 00291 UCHAR ForceAlignment; 00292 } UCHAR1, *PUCHAR1; 00293 00294 typedef union _UCHAR2 { 00295 UCHAR Uchar[2]; 00296 USHORT ForceAlignment; 00297 } UCHAR2, *PUCHAR2; 00298 00299 typedef union _UCHAR4 { 00300 UCHAR Uchar[4]; 00301 ULONG ForceAlignment; 00302 } UCHAR4, *PUCHAR4; 00303 00304 typedef union _USHORT2 { 00305 USHORT Ushort[2]; 00306 ULONG ForceAlignment; 00307 } USHORT2, *PUSHORT2; 00308 00309 // 00310 // This macro copies an unaligned src byte to an aligned dst byte 00311 // 00312 00313 #define CopyUchar1(Dst,Src) { \ 00314 *((UCHAR1 *)(Dst)) = *((UNALIGNED UCHAR1 *)(Src)); \ 00315 } 00316 00317 // 00318 // This macro copies an unaligned src word to an aligned dst word 00319 // 00320 00321 #define CopyUchar2(Dst,Src) { \ 00322 *((UCHAR2 *)(Dst)) = *((UNALIGNED UCHAR2 *)(Src)); \ 00323 } 00324 00325 // 00326 // This macro copies an unaligned src word to a dst word, 00327 // performing an little/big endian swap. 00328 // 00329 00330 #define SwapCopyUchar2(Dst,Src) { \ 00331 *((UNALIGNED UCHAR1 *)(Dst)) = *((UNALIGNED UCHAR1 *)(Src) + 1); \ 00332 *((UNALIGNED UCHAR1 *)(Dst) + 1) = *((UNALIGNED UCHAR1 *)(Src)); \ 00333 } 00334 00335 // 00336 // This macro copies an unaligned src longword to an aligned dst longword 00337 // 00338 00339 #define CopyUchar4(Dst,Src) { \ 00340 *((UCHAR4 *)(Dst)) = *((UNALIGNED UCHAR4 *)(Src)); \ 00341 } 00342 00343 // 00344 // This macro copies an unaligned src longword to a dst longword, 00345 // performing an little/big endian swap. 00346 // 00347 00348 #define SwapCopyUchar4(Dst,Src) { \ 00349 *((UNALIGNED UCHAR1 *)(Dst)) = *((UNALIGNED UCHAR1 *)(Src) + 3); \ 00350 *((UNALIGNED UCHAR1 *)(Dst) + 1) = *((UNALIGNED UCHAR1 *)(Src) + 2); \ 00351 *((UNALIGNED UCHAR1 *)(Dst) + 2) = *((UNALIGNED UCHAR1 *)(Src) + 1); \ 00352 *((UNALIGNED UCHAR1 *)(Dst) + 3) = *((UNALIGNED UCHAR1 *)(Src)); \ 00353 } 00354 00355 // 00356 // This macro copies an unaligned src longword to an aligned dsr longword 00357 // accessing the source on a word boundary. 00358 // 00359 00360 #define CopyUshort2(Dst,Src) { \ 00361 *((USHORT2 *)(Dst)) = *((UNALIGNED USHORT2 *)(Src));\ 00362 } 00363 00364 // 00365 // The following macro is used to determine if an FSD thread can block 00366 // for I/O or wait for a resource. It returns TRUE if the thread can 00367 // block and FALSE otherwise. This attribute can then be used to call 00368 // the FSD & FSP common work routine with the proper wait value. 00369 // 00370 00371 #define CanFsdWait(I) IoIsOperationSynchronous(I) 00372 00373 // 00374 // The following macro is used to set the fast i/o possible bits in the 00375 // FsRtl header. 00376 // 00377 // FastIoIsNotPossible - If the Fcb is bad or there are oplocks on the file. 00378 // 00379 // FastIoIsQuestionable - If there are file locks. 00380 // 00381 // FastIoIsPossible - In all other cases. 00382 // 00383 // 00384 00385 #define UdfIsFastIoPossible(F) ((BOOLEAN) \ 00386 ((((F)->Vcb->VcbCondition != VcbMounted ) || \ 00387 !FsRtlOplockIsFastIoPossible( &(F)->Oplock )) ? \ 00388 \ 00389 FastIoIsNotPossible : \ 00390 \ 00391 ((((F)->FileLock != NULL) && FsRtlAreThereCurrentFileLocks( (F)->FileLock )) ? \ 00392 \ 00393 FastIoIsQuestionable : \ 00394 \ 00395 FastIoIsPossible)) \ 00396 ) 00397 00398 // 00399 // The following macros encapsulate the common work of raising exceptions while storing 00400 // the exception in the IrpContext. 00401 // 00402 00403 INLINE 00404 DECLSPEC_NORETURN 00405 VOID 00406 UdfRaiseStatus ( 00407 IN PIRP_CONTEXT IrpContext, 00408 IN NTSTATUS Status 00409 ) 00410 { 00411 IrpContext->ExceptionStatus = Status; 00412 DebugBreakOnStatus( Status ); 00413 ExRaiseStatus( Status ); 00414 } 00415 00416 INLINE 00417 VOID 00418 UdfNormalizeAndRaiseStatus ( 00419 IN PIRP_CONTEXT IrpContext, 00420 IN NTSTATUS Status 00421 ) 00422 { 00423 IrpContext->ExceptionStatus = FsRtlNormalizeNtstatus( Status, STATUS_UNEXPECTED_IO_ERROR ); 00424 ExRaiseStatus( IrpContext->ExceptionStatus ); 00425 } 00426 00427 // 00428 // The following is a convenience macro to execute a little code before making 00429 // a shortcircuit out of a surrounding try-finally clause. This is usually to 00430 // set a status value. 00431 // 00432 // Note that our compilers support the leave keyword now and we don't have to 00433 // use the old try_exit: labels and goto. 00434 // 00435 00436 #define try_leave(S) { S; leave; } 00437 00438 // 00439 // For debugging purposes we sometimes want to allocate our structures from nonpaged 00440 // pool so that in the kernel debugger we can walk all the structures. 00441 // 00442 00443 #define UdfPagedPool PagedPool 00444 #define UdfNonPagedPool NonPagedPool 00445 #define UdfNonPagedPoolCacheAligned NonPagedPoolCacheAligned 00446 00447 // 00448 // Encapsulate safe pool freeing 00449 // 00450 00451 INLINE 00452 VOID 00453 UdfFreePool( 00454 IN PVOID *Pool 00455 ) 00456 { 00457 if (*Pool != NULL) { 00458 00459 ExFreePool(*Pool); 00460 *Pool = NULL; 00461 } 00462 } 00463 00464 // 00465 // Encapsulate counted string compares with uncounted fields. Thanks to a 00466 // very smart compiler, we have to carefully tell it that no matter what it 00467 // thinks, it *cannot* do anything other than a bytewise compare. 00468 // 00469 00470 INLINE 00471 BOOLEAN 00472 UdfEqualCountedString( 00473 IN PSTRING String, 00474 IN PCHAR Field 00475 ) 00476 { 00477 return (RtlEqualMemory( (CHAR UNALIGNED *)String->Buffer, 00478 (CHAR UNALIGNED *)Field, 00479 String->Length ) != 0); 00480 } 00481 00482 00483 // 00484 // Type of opens. FilObSup.c depends on this order. 00485 // 00486 00487 typedef enum _TYPE_OF_OPEN { 00488 00489 UnopenedFileObject = 0, 00490 StreamFileOpen, 00491 UserVolumeOpen, 00492 UserDirectoryOpen, 00493 UserFileOpen, 00494 BeyondValidType 00495 00496 } TYPE_OF_OPEN, *PTYPE_OF_OPEN; 00497 00498 00499 // 00500 // Following routines handle entry in and out of the filesystem. They are 00501 // contained in UdfData.c. We also get some very generic utility functions 00502 // here that aren't associated with any particular datastructure. 00503 // 00504 00505 NTSTATUS 00506 UdfFsdDispatch ( 00507 IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject, 00508 IN PIRP Irp 00509 ); 00510 00511 LONG 00512 UdfExceptionFilter ( 00513 IN PIRP_CONTEXT IrpContext, 00514 IN PEXCEPTION_POINTERS ExceptionPointer 00515 ); 00516 00517 NTSTATUS 00518 UdfProcessException ( 00519 IN PIRP_CONTEXT IrpContext OPTIONAL, 00520 IN PIRP Irp, 00521 IN NTSTATUS ExceptionCode 00522 ); 00523 00524 VOID 00525 UdfCompleteRequest ( 00526 IN PIRP_CONTEXT IrpContext OPTIONAL, 00527 IN PIRP Irp OPTIONAL, 00528 IN NTSTATUS Status 00529 ); 00530 00531 // 00532 // Following are the routines to handle the top level thread logic. 00533 // 00534 00535 VOID 00536 UdfSetThreadContext ( 00537 IN PIRP_CONTEXT IrpContext, 00538 IN PTHREAD_CONTEXT ThreadContext 00539 ); 00540 00541 INLINE 00542 VOID 00543 UdfRestoreThreadContext ( 00544 IN PIRP_CONTEXT IrpContext 00545 ) 00546 { 00547 IrpContext->ThreadContext->Udfs = 0; 00548 IoSetTopLevelIrp( IrpContext->ThreadContext->SavedTopLevelIrp ); 00549 IrpContext->ThreadContext = NULL; 00550 } 00551 00552 // 00553 // Following are some generic utility functions we have to carry along for the ride 00554 // 00555 00556 ULONG 00557 UdfSerial32 ( 00558 IN PCHAR Buffer, 00559 IN ULONG ByteCount 00560 ); 00561 00562 VOID 00563 UdfInitializeCrc16 ( 00564 ULONG Polynomial 00565 ); 00566 00567 USHORT 00568 UdfComputeCrc16 ( 00569 IN PUCHAR Buffer, 00570 IN ULONG ByteCount 00571 ); 00572 00573 USHORT 00574 UdfComputeCrc16Uni ( 00575 PWCHAR Buffer, 00576 ULONG CharCount 00577 ); 00578 00579 ULONG 00580 UdfHighBit ( 00581 ULONG Word 00582 ); 00583 00584 // 00585 // Following are the fast entry points. 00586 // 00587 00588 BOOLEAN 00589 UdfFastQueryBasicInfo ( 00590 IN PFILE_OBJECT FileObject, 00591 IN BOOLEAN Wait, 00592 IN OUT PFILE_BASIC_INFORMATION Buffer, 00593 OUT PIO_STATUS_BLOCK IoStatus, 00594 IN PDEVICE_OBJECT DeviceObject 00595 ); 00596 00597 BOOLEAN 00598 UdfFastIoCheckIfPossible ( 00599 IN PFILE_OBJECT FileObject, 00600 IN PLARGE_INTEGER FileOffset, 00601 IN ULONG Length, 00602 IN BOOLEAN Wait, 00603 IN ULONG LockKey, 00604 IN BOOLEAN CheckForReadOperation, 00605 OUT PIO_STATUS_BLOCK IoStatus, 00606 IN PDEVICE_OBJECT DeviceObject 00607 ); 00608 00609 BOOLEAN 00610 UdfFastLock ( 00611 IN PFILE_OBJECT FileObject, 00612 IN PLARGE_INTEGER FileOffset, 00613 IN PLARGE_INTEGER Length, 00614 PEPROCESS ProcessId, 00615 ULONG Key, 00616 BOOLEAN FailImmediately, 00617 BOOLEAN ExclusiveLock, 00618 OUT PIO_STATUS_BLOCK IoStatus, 00619 IN PDEVICE_OBJECT DeviceObject 00620 ); 00621 00622 BOOLEAN 00623 UdfFastQueryNetworkInfo ( 00624 IN PFILE_OBJECT FileObject, 00625 IN BOOLEAN Wait, 00626 OUT PFILE_NETWORK_OPEN_INFORMATION Buffer, 00627 OUT PIO_STATUS_BLOCK IoStatus, 00628 IN PDEVICE_OBJECT DeviceObject 00629 ); 00630 00631 BOOLEAN 00632 UdfFastQueryStdInfo ( 00633 IN PFILE_OBJECT FileObject, 00634 IN BOOLEAN Wait, 00635 IN OUT PFILE_STANDARD_INFORMATION Buffer, 00636 OUT PIO_STATUS_BLOCK IoStatus, 00637 IN PDEVICE_OBJECT DeviceObject 00638 ); 00639 00640 BOOLEAN 00641 UdfFastUnlockSingle ( 00642 IN PFILE_OBJECT FileObject, 00643 IN PLARGE_INTEGER FileOffset, 00644 IN PLARGE_INTEGER Length, 00645 PEPROCESS ProcessId, 00646 ULONG Key, 00647 OUT PIO_STATUS_BLOCK IoStatus, 00648 IN PDEVICE_OBJECT DeviceObject 00649 ); 00650 00651 BOOLEAN 00652 UdfFastUnlockAll ( 00653 IN PFILE_OBJECT FileObject, 00654 PEPROCESS ProcessId, 00655 OUT PIO_STATUS_BLOCK IoStatus, 00656 IN PDEVICE_OBJECT DeviceObject 00657 ); 00658 00659 BOOLEAN 00660 UdfFastUnlockAllByKey ( 00661 IN PFILE_OBJECT FileObject, 00662 PVOID ProcessId, 00663 ULONG Key, 00664 OUT PIO_STATUS_BLOCK IoStatus, 00665 IN PDEVICE_OBJECT DeviceObject 00666 ); 00667 00668 00669 // 00670 // File access check routine, implemented in AcChkSup.c 00671 // 00672 00673 INLINE 00674 BOOLEAN 00675 UdfIllegalFcbAccess ( 00676 IN PIRP_CONTEXT IrpContext, 00677 IN TYPE_OF_OPEN TypeOfOpen, 00678 IN ACCESS_MASK DesiredAccess 00679 ) 00680 00681 /*++ 00682 00683 Routine Description: 00684 00685 This routine simply asserts that the access is legal for a readonly filesystem. 00686 00687 Arguments: 00688 00689 TypeOfOpen - type of open for the Fcb in question. 00690 00691 DesiredAccess - mask of access the caller is trying for. 00692 00693 Return Value: 00694 00695 BOOLEAN True if illegal access, false otherwise. 00696 00697 --*/ 00698 00699 { 00700 return BooleanFlagOn( DesiredAccess, 00701 (TypeOfOpen != UserVolumeOpen ? 00702 (FILE_WRITE_ATTRIBUTES | 00703 FILE_WRITE_DATA | 00704 FILE_WRITE_EA | 00705 FILE_ADD_FILE | 00706 FILE_ADD_SUBDIRECTORY | 00707 FILE_APPEND_DATA) : 0) | 00708 FILE_DELETE_CHILD | 00709 DELETE | 00710 WRITE_DAC ); 00711 } 00712 00713 00714 // 00715 // Sector lookup routines, implemented in AllocSup.c 00716 // 00717 00718 BOOLEAN 00719 UdfLookupAllocation ( 00720 IN PIRP_CONTEXT IrpContext, 00721 IN PFCB Fcb, 00722 IN LONGLONG FileOffset, 00723 OUT PLONGLONG DiskOffset, 00724 OUT PULONG ByteCount 00725 ); 00726 00727 VOID 00728 UdfDeletePcb ( 00729 IN PPCB Pcb 00730 ); 00731 00732 NTSTATUS 00733 UdfInitializePcb ( 00734 IN PIRP_CONTEXT IrpContext, 00735 IN PVCB Vcb, 00736 IN OUT PPCB *Pcb, 00737 IN PNSR_LVOL LVD 00738 ); 00739 00740 VOID 00741 UdfAddToPcb ( 00742 IN PPCB Pcb, 00743 IN PNSR_PART PartitionDescriptor 00744 ); 00745 00746 NTSTATUS 00747 UdfCompletePcb( 00748 IN PIRP_CONTEXT IrpContext, 00749 IN PVCB Vcb, 00750 IN PPCB Pcb ); 00751 00752 BOOLEAN 00753 UdfEquivalentPcb ( 00754 IN PIRP_CONTEXT IrpContext, 00755 IN PPCB Pcb1, 00756 IN PPCB Pcb2 00757 ); 00758 00759 ULONG 00760 UdfLookupPsnOfExtent ( 00761 IN PIRP_CONTEXT IrpContext, 00762 IN PVCB Vcb, 00763 IN USHORT Reference, 00764 IN ULONG Lbn, 00765 IN ULONG Len 00766 ); 00767 00768 ULONG 00769 UdfLookupMetaVsnOfExtent ( 00770 IN PIRP_CONTEXT IrpContext, 00771 IN PVCB Vcb, 00772 IN USHORT Reference, 00773 IN ULONG Lbn, 00774 IN ULONG Len, 00775 IN BOOLEAN ExactEnd 00776 ); 00777 00778 00779 // 00780 // 00781 // Buffer control routines for data caching, implemented in CacheSup.c 00782 // 00783 00784 VOID 00785 UdfCreateInternalStream ( 00786 IN PIRP_CONTEXT IrpContext, 00787 IN PVCB Vcb, 00788 IN PFCB Fcb 00789 ); 00790 00791 VOID 00792 UdfDeleteInternalStream ( 00793 IN PIRP_CONTEXT IrpContext, 00794 IN PFCB Fcb 00795 ); 00796 00797 00798 NTSTATUS 00799 UdfCompleteMdl ( 00800 IN PIRP_CONTEXT IrpContext, 00801 IN PIRP Irp 00802 ); 00803 00804 VOID 00805 UdfMapMetadataView ( 00806 IN PIRP_CONTEXT IrpContext, 00807 IN PMAPPED_PVIEW View, 00808 IN PVCB Vcb, 00809 IN USHORT Partition, 00810 IN ULONG Lbn, 00811 IN ULONG Length 00812 ); 00813 00814 NTSTATUS 00815 UdfPurgeVolume ( 00816 IN PIRP_CONTEXT IrpContext, 00817 IN PVCB Vcb, 00818 IN BOOLEAN DismountUnderway 00819 ); 00820 00821 // VOID 00822 // UdfUnpinView ( 00823 // IN PIRP_CONTEXT IrpContext, 00824 // IN PMAPPED_VIEW View 00825 // ); 00826 // 00827 00828 #define UdfUnpinView(IC,V) \ 00829 if (((V)->Bcb) != NULL) { CcUnpinData( ((V)->Bcb) ); ((V)->Bcb) = NULL; ((V)->View) = NULL; } 00830 00831 // VOID 00832 // UdfUnpinData ( 00833 // IN PIRP_CONTEXT IrpContext, 00834 // IN OUT PBCB *Bcb 00835 // ); 00836 // 00837 00838 #define UdfUnpinData(IC,B) \ 00839 if (*(B) != NULL) { CcUnpinData( *(B) ); *(B) = NULL; } 00840 00841 00842 // 00843 // Device I/O routines, implemented in DevIoSup.c 00844 // 00845 // These routines perform the actual device reads and other communcation. 00846 // They do not affect any data structures. 00847 // 00848 00849 NTSTATUS 00850 UdfPerformDevIoCtrl ( 00851 IN PIRP_CONTEXT IrpContext, 00852 IN ULONG IoControlCode, 00853 IN PDEVICE_OBJECT Device, 00854 OUT PVOID OutputBuffer OPTIONAL, 00855 IN ULONG OutputBufferLength, 00856 IN BOOLEAN InternalDeviceIoControl, 00857 IN BOOLEAN OverrideVerify, 00858 OUT PIO_STATUS_BLOCK Iosb OPTIONAL 00859 ); 00860 00861 NTSTATUS 00862 UdfReadSectors ( 00863 IN PIRP_CONTEXT IrpContext, 00864 IN LONGLONG StartingOffset, 00865 IN ULONG ByteCount, 00866 IN BOOLEAN ReturnError, 00867 IN OUT PVOID Buffer, 00868 IN PDEVICE_OBJECT TargetDeviceObject 00869 ); 00870 00871 NTSTATUS 00872 UdfNonCachedRead ( 00873 IN PIRP_CONTEXT IrpContext, 00874 IN PFCB Fcb, 00875 IN LONGLONG StartingOffset, 00876 IN ULONG ByteCount 00877 ); 00878 00879 NTSTATUS 00880 UdfCreateUserMdl ( 00881 IN PIRP_CONTEXT IrpContext, 00882 IN ULONG BufferLength, 00883 IN BOOLEAN RaiseOnError 00884 ); 00885 00886 // 00887 // VOID 00888 // UdfMapUserBuffer ( 00889 // IN PIRP_CONTEXT IrpContext, 00890 // OUT PVOID Buffer 00891 // ); 00892 // 00893 // Will raise on failure. 00894 // 00895 // VOID 00896 // UdfLockUserBuffer ( 00897 // IN PIRP_CONTEXT IrpContext, 00898 // IN ULONG BufferLength 00899 // ); 00900 // 00901 00902 #define UdfMapUserBuffer(IC,UB) { \ 00903 *(UB) = ((PVOID) (((IC)->Irp->MdlAddress == NULL) ? \ 00904 (IC)->Irp->UserBuffer : \ 00905 MmGetSystemAddressForMdlSafe( (IC)->Irp->MdlAddress, NormalPagePriority ))); \ 00906 if (NULL == *(UB)) { \ 00907 UdfRaiseStatus( IrpContext, STATUS_INSUFFICIENT_RESOURCES); \ 00908 } \ 00909 } 00910 00911 #define UdfLockUserBuffer(IC,BL) { \ 00912 if ((IC)->Irp->MdlAddress == NULL) { \ 00913 (VOID) UdfCreateUserMdl( (IC), (BL), TRUE ); \ 00914 } \ 00915 } 00916 00917 // 00918 // Udf*RawBufferSize and Udf*RawReadSize calculate how big a buffer must be 00919 // to do a direct read of a given sector aligned structure (UdfReadSectors) 00920 // and how much data the read must recover. Reads must write into whole-page 00921 // sized buffers and be in whole-sector units. 00922 // 00923 // Note that although all descriptors are constrained to fit in one logical 00924 // block, it is not always going to be neccesary to read the entire logical 00925 // block to get the descriptor. The underlying restriction is the physical 00926 // sector. 00927 // 00928 00929 INLINE 00930 ULONG 00931 UdfRawBufferSize ( 00932 IN PVCB Vcb, 00933 IN ULONG StructureSize 00934 ) 00935 { 00936 return (ULONG)ROUND_TO_PAGES( SectorAlign( Vcb, StructureSize )); 00937 } 00938 00939 INLINE 00940 ULONG 00941 UdfRawReadSize ( 00942 IN PVCB Vcb, 00943 IN ULONG StructureSize 00944 ) 00945 { 00946 return SectorAlign( Vcb, StructureSize ); 00947 } 00948 00949 INLINE 00950 ULONG 00951 UdfRawBufferSizeN ( 00952 IN ULONG SectorSize, 00953 IN ULONG StructureSize 00954 ) 00955 { 00956 return (ULONG)ROUND_TO_PAGES( SectorAlignN( SectorSize, StructureSize )); 00957 } 00958 00959 INLINE 00960 ULONG 00961 UdfRawReadSizeN ( 00962 IN ULONG SectorSize, 00963 IN ULONG StructureSize 00964 ) 00965 { 00966 return SectorAlignN( SectorSize, StructureSize ); 00967 } 00968 00969 00970 // 00971 // The following routines are used to read on-disk directory structures, implemented 00972 // in DirSup.c 00973 // 00974 00975 VOID 00976 UdfInitializeDirContext ( 00977 IN PIRP_CONTEXT IrpContext, 00978 IN PDIR_ENUM_CONTEXT DirContext 00979 ); 00980 00981 VOID 00982 UdfCleanupDirContext ( 00983 IN PIRP_CONTEXT IrpContext, 00984 IN PDIR_ENUM_CONTEXT DirContext 00985 ); 00986 00987 BOOLEAN 00988 UdfLookupInitialDirEntry ( 00989 IN PIRP_CONTEXT IrpContext, 00990 IN PFCB Fcb, 00991 IN PDIR_ENUM_CONTEXT DirContext, 00992 IN PLONGLONG InitialOffset OPTIONAL 00993 ); 00994 00995 BOOLEAN 00996 UdfLookupNextDirEntry ( 00997 IN PIRP_CONTEXT IrpContext, 00998 IN PFCB Fcb, 00999 IN PDIR_ENUM_CONTEXT DirContext 01000 ); 01001 01002 VOID 01003 UdfUpdateDirNames ( 01004 IN PIRP_CONTEXT IrpContext, 01005 IN PDIR_ENUM_CONTEXT DirContext, 01006 IN BOOLEAN IgnoreCase 01007 ); 01008 01009 BOOLEAN 01010 UdfFindDirEntry ( 01011 IN PIRP_CONTEXT IrpContext, 01012 IN PFCB Fcb, 01013 IN PUNICODE_STRING Name, 01014 IN BOOLEAN IgnoreCase, 01015 IN BOOLEAN ShortName, 01016 IN PDIR_ENUM_CONTEXT DirContext 01017 ); 01018 01019 01020 // 01021 // The following routines are used to manipulate the fscontext fields 01022 // of the file object, implemented in FilObSup.c 01023 // 01024 01025 VOID 01026 UdfSetFileObject ( 01027 IN PIRP_CONTEXT IrpContext, 01028 IN PFILE_OBJECT FileObject, 01029 IN TYPE_OF_OPEN TypeOfOpen, 01030 IN PFCB Fcb OPTIONAL, 01031 IN PCCB Ccb OPTIONAL 01032 ); 01033 01034 TYPE_OF_OPEN 01035 UdfDecodeFileObject ( 01036 IN PFILE_OBJECT FileObject, 01037 OUT PFCB *Fcb, 01038 OUT PCCB *Ccb 01039 ); 01040 01041 TYPE_OF_OPEN 01042 UdfFastDecodeFileObject ( 01043 IN PFILE_OBJECT FileObject, 01044 OUT PFCB *Fcb 01045 ); 01046 01047 01048 // 01049 // FSCTL request support routines. Contained in FsCtrl.c 01050 // 01051 01052 VOID 01053 UdfStoreVolumeDescriptorIfPrevailing ( 01054 IN OUT PNSR_VD_GENERIC *StoredVD, 01055 IN OUT PNSR_VD_GENERIC NewVD 01056 ); 01057 01058 01059 // 01060 // Name mangling routines. Implemented in Namesup.c 01061 // 01062 01063 VOID 01064 UdfDissectName ( 01065 IN PIRP_CONTEXT IrpContext, 01066 IN OUT PUNICODE_STRING RemainingName, 01067 OUT PUNICODE_STRING FinalName 01068 ); 01069 01070 BOOLEAN 01071 UdfIs8dot3Name ( 01072 IN PIRP_CONTEXT IrpContext, 01073 IN UNICODE_STRING FileName 01074 ); 01075 01076 BOOLEAN 01077 UdfCandidateShortName ( 01078 IN PIRP_CONTEXT IrpContext, 01079 IN PUNICODE_STRING Name 01080 ); 01081 01082 VOID 01083 UdfGenerate8dot3Name ( 01084 IN PIRP_CONTEXT IrpContext, 01085 IN PUNICODE_STRING FileName, 01086 OUT PUNICODE_STRING ShortFileName 01087 ); 01088 01089 VOID 01090 UdfConvertCS0DstringToUnicode ( 01091 IN PIRP_CONTEXT IrpContext, 01092 IN PUCHAR Dstring, 01093 IN UCHAR Length OPTIONAL, 01094 IN UCHAR FieldLength OPTIONAL, 01095 IN OUT PUNICODE_STRING Name 01096 ); 01097 01098 BOOLEAN 01099 UdfCheckLegalCS0Dstring ( 01100 PIRP_CONTEXT IrpContext, 01101 PUCHAR Dstring, 01102 UCHAR Length OPTIONAL, 01103 UCHAR FieldLength OPTIONAL, 01104 BOOLEAN ReturnOnError 01105 ); 01106 01107 VOID 01108 UdfRenderNameToLegalUnicode ( 01109 IN PIRP_CONTEXT IrpContext, 01110 IN PUNICODE_STRING Name, 01111 IN PUNICODE_STRING RenderedName 01112 ); 01113 01114 BOOLEAN 01115 UdfIsNameInExpression ( 01116 IN PIRP_CONTEXT IrpContext, 01117 IN PUNICODE_STRING CurrentName, 01118 IN PUNICODE_STRING SearchExpression, 01119 IN BOOLEAN Wild 01120 ); 01121 01122 FSRTL_COMPARISON_RESULT 01123 UdfFullCompareNames ( 01124 IN PIRP_CONTEXT IrpContext, 01125 IN PUNICODE_STRING NameA, 01126 IN PUNICODE_STRING NameB 01127 ); 01128 01129 INLINE 01130 VOID 01131 UdfUpcaseName ( 01132 IN PIRP_CONTEXT IrpContext, 01133 IN PUNICODE_STRING Name, 01134 IN OUT PUNICODE_STRING UpcaseName 01135 ) 01136 01137 /*++ 01138 01139 Routine Description: 01140 01141 This routine upcases a name with an assertion of success. 01142 01143 Arguments: 01144 01145 Name - an name to upcase 01146 01147 Length - a place to put the upcased name (can be the same as Name) 01148 01149 Return Value: 01150 01151 None. 01152 01153 --*/ 01154 01155 { 01156 NTSTATUS Status; 01157 01158 // 01159 // Upcase the string using the correct upcase routine. 01160 // 01161 01162 Status = RtlUpcaseUnicodeString( UpcaseName, 01163 Name, 01164 FALSE ); 01165 01166 // 01167 // This should never fail. 01168 // 01169 01170 ASSERT( Status == STATUS_SUCCESS ); 01171 01172 return; 01173 } 01174 01175 INLINE 01176 USHORT 01177 UdfCS0DstringUnicodeSize ( 01178 PIRP_CONTEXT IrpContext, 01179 PCHAR Dstring, 01180 UCHAR Length 01181 ) 01182 01183 /*++ 01184 01185 Routine Description: 01186 01187 This routine computes the number of bytes required for the UNICODE representation 01188 of a CS0 Dstring (1/7.2.12) 01189 01190 Arguments: 01191 01192 Dstring - a dstring 01193 01194 Length - length of the dstring 01195 01196 Return Value: 01197 01198 ULONG number of bytes. 01199 01200 --*/ 01201 01202 { 01203 return (16 / *Dstring) * (Length - 1); 01204 } 01205 01206 INLINE 01207 BOOLEAN 01208 UdfIsCharacterLegal ( 01209 IN WCHAR Character 01210 ) 01211 01212 /*++ 01213 01214 Routine Description: 01215 01216 This routine checks that a given UNICODE character is legal. 01217 01218 Arguments: 01219 01220 Character - a character to check 01221 01222 Return Value: 01223 01224 BOOLEAN True if a legal character, False otherwise. 01225 01226 --*/ 01227 01228 { 01229 if (Character < 0xff && !FsRtlIsAnsiCharacterLegalHpfs( Character, FALSE )) { 01230 01231 return FALSE; 01232 } 01233 01234 return TRUE; 01235 } 01236 01237 INLINE 01238 BOOLEAN 01239 UdfCS0DstringContainsLegalCharacters ( 01240 IN PCHAR Dstring, 01241 IN ULONG Length 01242 ) 01243 01244 /*++ 01245 01246 Routine Description: 01247 01248 This routine inspects a CS0 dstring for illegal characters. The assumption is 01249 made that the string is legal CS0. 01250 01251 Arguments: 01252 01253 Name - a name to check 01254 01255 Return Value: 01256 01257 BOOLEAN True if legal characters are found, False otherwise. 01258 01259 --*/ 01260 01261 { 01262 ULONG Step; 01263 WCHAR Char; 01264 PCHAR Bound = Dstring + Length; 01265 01266 // 01267 // Determine how big a step we take in the string according to the 01268 // "compression" applied. 01269 // 01270 01271 if (*Dstring == 16) { 01272 01273 Step = sizeof( WCHAR ); 01274 01275 } else { 01276 01277 Step = sizeof( CHAR ); 01278 } 01279 01280 // 01281 // Advance past the compression marker and loop over the string. 01282 // 01283 01284 for (Dstring++; Dstring < Bound; Dstring += Step) { 01285 01286 // 01287 // Perform the endianess swapcopy to convert from UDF bigendian CS0 to our 01288 // little endian wide characters. 01289 // 01290 01291 SwapCopyUchar2( &Char, Dstring ); 01292 01293 if (!UdfIsCharacterLegal( Char )) { 01294 01295 DebugTrace(( 0, Dbg, "UdfCS0DstringContainsLegalCharacters, Char %04x @ %08x\n", (WCHAR) Char, Dstring )); 01296 01297 return FALSE; 01298 } 01299 } 01300 01301 return TRUE; 01302 } 01303 01304 01305 // 01306 // Filesystem control operations. Implemented in Fsctrl.c 01307 // 01308 01309 NTSTATUS 01310 UdfLockVolumeInternal ( 01311 IN PIRP_CONTEXT IrpContext, 01312 IN PVCB Vcb, 01313 IN PFILE_OBJECT FileObject OPTIONAL 01314 ); 01315 01316 NTSTATUS 01317 UdfUnlockVolumeInternal ( 01318 IN PIRP_CONTEXT IrpContext, 01319 IN PVCB Vcb, 01320 IN PFILE_OBJECT FileObject OPTIONAL 01321 ); 01322 01323 01324 // 01325 // Routines to handle the prefix trees attached to directories, used to quickly travel common 01326 // bits of the hierarchy. Implemented in PrefxSup.c 01327 // 01328 01329 PLCB 01330 UdfFindPrefix ( 01331 IN PIRP_CONTEXT IrpContext, 01332 IN OUT PFCB *CurrentFcb, 01333 IN OUT PUNICODE_STRING RemainingName, 01334 IN BOOLEAN IgnoreCase 01335 ); 01336 01337 VOID 01338 UdfInitializeLcbFromDirContext ( 01339 IN PIRP_CONTEXT IrpContext, 01340 IN PLCB Lcb, 01341 IN PDIR_ENUM_CONTEXT DirContext 01342 ); 01343 01344 PLCB 01345 UdfInsertPrefix ( 01346 IN PIRP_CONTEXT IrpContext, 01347 IN PFCB Fcb, 01348 IN PUNICODE_STRING Name, 01349 IN BOOLEAN ShortNameMatch, 01350 IN BOOLEAN IgnoreCase, 01351 IN PFCB ParentFcb 01352 ); 01353 01354 VOID 01355 UdfRemovePrefix ( 01356 IN PIRP_CONTEXT IrpContext, 01357 IN PLCB Lcb 01358 ); 01359 01360 01361 // 01362 // Synchronization routines. Implemented in Resrcsup.c 01363 // 01364 // The following routines/macros are used to synchronize the in-memory structures. 01365 // 01366 // Routine/Macro Synchronizes Subsequent 01367 // 01368 // UdfAcquireUdfData Volume Mounts/Dismounts,Vcb Queue UdfReleaseUdfData 01369 // UdfAcquireVcbExclusive Vcb for open/close UdfReleaseVcb 01370 // UdfAcquireVcbShared Vcb for open/close UdfReleaseVcb 01371 // UdfAcquireAllFiles Locks out operations to all files UdfReleaseAllFiles 01372 // UdfAcquireFileExclusive Locks out file operations UdfReleaseFile 01373 // UdfAcquireFileShared Files for file operations UdfReleaseFile 01374 // UdfAcquireFcbExclusive Fcb for open/close UdfReleaseFcb 01375 // UdfAcquireFcbShared Fcb for open/close UdfReleaseFcb 01376 // UdfLockUdfData Fields in UdfData UdfUnlockUdfData 01377 // UdfLockVcb Vcb fields, FcbReference, FcbTable UdfUnlockVcb 01378 // UdfLockFcb Fcb fields, prefix table, Mcb UdfUnlockFcb 01379 // 01380 01381 typedef enum _TYPE_OF_ACQUIRE { 01382 01383 AcquireExclusive, 01384 AcquireShared, 01385 AcquireSharedStarveExclusive 01386 01387 } TYPE_OF_ACQUIRE, *PTYPE_OF_ACQUIRE; 01388 01389 BOOLEAN 01390 UdfAcquireResource ( 01391 IN PIRP_CONTEXT IrpContext, 01392 IN PERESOURCE Resource, 01393 IN BOOLEAN IgnoreWait, 01394 IN TYPE_OF_ACQUIRE Type 01395 ); 01396 01397 // 01398 // BOOLEAN 01399 // UdfAcquireUdfData ( 01400 // IN PIRP_CONTEXT IrpContext 01401 // ); 01402 // 01403 // VOID 01404 // UdfReleaseUdfData ( 01405 // IN PIRP_CONTEXT IrpContext 01406 // ); 01407 // 01408 // BOOLEAN 01409 // UdfAcquireVcbExclusive ( 01410 // IN PIRP_CONTEXT IrpContext, 01411 // IN PVCB Vcb, 01412 // IN BOOLEAN IgnoreWait 01413 // ); 01414 // 01415 // BOOLEAN 01416 // UdfAcquireVcbShared ( 01417 // IN PIRP_CONTEXT IrpContext, 01418 // IN PVCB Vcb, 01419 // IN BOOLEAN IgnoreWait 01420 // ); 01421 // 01422 // VOID 01423 // UdfReleaseVcb ( 01424 // IN PIRP_CONTEXT IrpContext, 01425 // IN PVCB Vcb 01426 // ); 01427 // 01428 // VOID 01429 // UdfAcquireAllFiles ( 01430 // IN PIRP_CONTEXT, 01431 // IN PVCB Vcb 01432 // ); 01433 // 01434 // VOID 01435 // UdfReleaseAllFiles ( 01436 // IN PIRP_CONTEXT, 01437 // IN PVCB Vcb 01438 // ); 01439 // 01440 // VOID 01441 // UdfAcquireFileExclusive ( 01442 // IN PIRP_CONTEXT IrpContext, 01443 // IN PFCB Fcb, 01444 // ); 01445 // 01446 // VOID 01447 // UdfAcquireFileShared ( 01448 // IN PIRP_CONTEXT IrpContext, 01449 // IN PFCB Fcb 01450 // ); 01451 // 01452 // VOID 01453 // UdfReleaseFile ( 01454 // IN PIRP_CONTEXT IrpContext, 01455 // IN PFCB Fcb 01456 // ); 01457 // 01458 // BOOLEAN 01459 // UdfAcquireFcbExclusive ( 01460 // IN PIRP_CONTEXT IrpContext, 01461 // IN PFCB Fcb, 01462 // IN BOOLEAN IgnoreWait 01463 // ); 01464 // 01465 // BOOLEAN 01466 // UdfAcquireFcbShared ( 01467 // IN PIRP_CONTEXT IrpContext, 01468 // IN PFCB Fcb, 01469 // IN BOOLEAN IgnoreWait 01470 // ); 01471 // 01472 // BOOLEAN 01473 // UdfReleaseFcb ( 01474 // IN PIRP_CONTEXT IrpContext, 01475 // IN PFCB Fcb 01476 // ); 01477 // 01478 // VOID 01479 // UdfLockUdfData ( 01480 // ); 01481 // 01482 // VOID 01483 // UdfUnlockUdfData ( 01484 // ); 01485 // 01486 // VOID 01487 // UdfLockVcb ( 01488 // IN PIRP_CONTEXT IrpContext 01489 // ); 01490 // 01491 // VOID 01492 // UdfUnlockVcb ( 01493 // IN PIRP_CONTEXT IrpContext 01494 // ); 01495 // 01496 // VOID 01497 // UdfLockFcb ( 01498 // IN PIRP_CONTEXT IrpContext, 01499 // IN PFCB Fcb 01500 // ); 01501 // 01502 // VOID 01503 // UdfUnlockFcb ( 01504 // IN PIRP_CONTEXT IrpContext, 01505 // IN PFCB Fcb 01506 // ); 01507 // 01508 01509 #define UdfAcquireUdfData(IC) \ 01510 ExAcquireResourceExclusive( &UdfData.DataResource, TRUE ) 01511 01512 #define UdfReleaseUdfData(IC) \ 01513 ExReleaseResource( &UdfData.DataResource ) 01514 01515 #define UdfAcquireVcbExclusive(IC,V,I) \ 01516 UdfAcquireResource( (IC), &(V)->VcbResource, (I), AcquireExclusive ) 01517 01518 #define UdfAcquireVcbShared(IC,V,I) \ 01519 UdfAcquireResource( (IC), &(V)->VcbResource, (I), AcquireShared ) 01520 01521 #define UdfReleaseVcb(IC,V) \ 01522 ExReleaseResource( &(V)->VcbResource ) 01523 01524 #define UdfAcquireAllFiles(IC,V) \ 01525 UdfAcquireResource( (IC), &(V)->FileResource, FALSE, AcquireExclusive ) 01526 01527 #define UdfReleaseAllFiles(IC,V) \ 01528 ExReleaseResource( &(V)->FileResource ) 01529 01530 #define UdfAcquireFileExclusive(IC,F) \ 01531 UdfAcquireResource( (IC), (F)->Resource, FALSE, AcquireExclusive ) 01532 01533 #define UdfAcquireFileShared(IC,F) \ 01534 UdfAcquireResource( (IC), (F)->Resource, FALSE, AcquireShared ) 01535 01536 #define UdfAcquireFileSharedStarveExclusive(IC,F) \ 01537 UdfAcquireResource( (IC), (F)->Resource, FALSE, AcquireSharedStarveExclusive ) 01538 01539 #define UdfReleaseFile(IC,F) \ 01540 ExReleaseResource( (F)->Resource ) 01541 01542 #define UdfAcquireFcbExclusive(IC,F,I) \ 01543 UdfAcquireResource( (IC), &(F)->FcbNonpaged->FcbResource, (I), AcquireExclusive ) 01544 01545 #define UdfAcquireFcbShared(IC,F,I) \ 01546 UdfAcquireResource( (IC), &(F)->FcbNonpaged->FcbResource, (I), AcquireShared ) 01547 01548 #define UdfReleaseFcb(IC,F) \ 01549 ExReleaseResource( &(F)->FcbNonpaged->FcbResource ) 01550 01551 #define UdfLockUdfData() \ 01552 ExAcquireFastMutex( &UdfData.UdfDataMutex ); \ 01553 UdfData.UdfDataLockThread = PsGetCurrentThread() 01554 01555 #define UdfUnlockUdfData() \ 01556 UdfData.UdfDataLockThread = NULL; \ 01557 ExReleaseFastMutex( &UdfData.UdfDataMutex ) 01558 01559 #define UdfLockVcb(IC,V) \ 01560 ExAcquireFastMutex( &(V)->VcbMutex ); \ 01561 (V)->VcbLockThread = PsGetCurrentThread() 01562 01563 #define UdfUnlockVcb(IC,V) \ 01564 (V)->VcbLockThread = NULL; \ 01565 ExReleaseFastMutex( &(V)->VcbMutex ) 01566 01567 #define UdfLockFcb(IC,F) { \ 01568 PVOID _CurrentThread = PsGetCurrentThread(); \ 01569 if (_CurrentThread != (F)->FcbLockThread) { \ 01570 ExAcquireFastMutex( &(F)->FcbNonpaged->FcbMutex ); \ 01571 ASSERT( (F)->FcbLockCount == 0 ); \ 01572 (F)->FcbLockThread = _CurrentThread; \ 01573 } \ 01574 (F)->FcbLockCount += 1; \ 01575 } 01576 01577 #define UdfUnlockFcb(IC,F) { \ 01578 (F)->FcbLockCount -= 1; \ 01579 if ((F)->FcbLockCount == 0) { \ 01580 (F)->FcbLockThread = NULL; \ 01581 ExReleaseFastMutex( &(F)->FcbNonpaged->FcbMutex ); \ 01582 } \ 01583 } 01584 01585 BOOLEAN 01586 UdfNoopAcquire ( 01587 IN PVOID Fcb, 01588 IN BOOLEAN Wait 01589 ); 01590 01591 VOID 01592 UdfNoopRelease ( 01593 IN PVOID Fcb 01594 ); 01595 01596 BOOLEAN 01597 UdfAcquireForCache ( 01598 IN PFCB Fcb, 01599 IN BOOLEAN Wait 01600 ); 01601 01602 VOID 01603 UdfReleaseFromCache ( 01604 IN PFCB Fcb 01605 ); 01606 01607 VOID 01608 UdfAcquireForCreateSection ( 01609 IN PFILE_OBJECT FileObject 01610 ); 01611 01612 VOID 01613 UdfReleaseForCreateSection ( 01614 IN PFILE_OBJECT FileObject 01615 ); 01616 01617 01618 // 01619 // Structure support routines, implemented in StrucSup.c 01620 // 01621 // These routines perform in-memory structure manipulations. They do *not* operate 01622 // on disk structures. 01623 // 01624 01625 BOOLEAN 01626 UdfInitializeVcb ( 01627 IN PIRP_CONTEXT IrpContext, 01628 IN OUT PVCB Vcb, 01629 IN PDEVICE_OBJECT TargetDeviceObject, 01630 IN PVPB Vpb, 01631 IN PDISK_GEOMETRY DiskGeometry, 01632 IN ULONG MediaChangeCount 01633 ); 01634 01635 VOID 01636 UdfUpdateVcbPhase0 ( 01637 IN PIRP_CONTEXT IrpContext, 01638 IN OUT PVCB Vcb 01639 ); 01640 01641 VOID 01642 UdfUpdateVcbPhase1 ( 01643 IN PIRP_CONTEXT IrpContext, 01644 IN OUT PVCB Vcb, 01645 IN PNSR_FSD Fsd 01646 ); 01647 01648 VOID 01649 UdfDeleteVcb ( 01650 IN PIRP_CONTEXT IrpContext, 01651 IN OUT PVCB Vcb 01652 ); 01653 01654 PIRP_CONTEXT 01655 UdfCreateIrpContext ( 01656 IN PIRP Irp, 01657 IN BOOLEAN Wait 01658 ); 01659 01660 VOID 01661 UdfCleanupIrpContext ( 01662 IN PIRP_CONTEXT IrpContext, 01663 IN BOOLEAN Post 01664 ); 01665 01666 VOID 01667 UdfInitializeStackIrpContext ( 01668 OUT PIRP_CONTEXT IrpContext, 01669 IN PIRP_CONTEXT_LITE IrpContextLite 01670 ); 01671 01672 // 01673 // PIRP_CONTEXT_LITE 01674 // UdfCreateIrpContextLite ( 01675 // IN PIRP_CONTEXT IrpContext 01676 // ); 01677 // 01678 // VOID 01679 // UdfFreeIrpContextLite ( 01680 // IN PIRP_CONTEXT_LITE IrpContextLite 01681 // ); 01682 // 01683 01684 #define UdfCreateIrpContextLite(IC) \ 01685 ExAllocatePoolWithTag( UdfNonPagedPool, sizeof( IRP_CONTEXT_LITE ), TAG_IRP_CONTEXT_LITE ) 01686 01687 #define UdfFreeIrpContextLite(ICL) \ 01688 ExFreePool( ICL ) 01689 01690 // 01691 // PUDF_IO_CONTEXT 01692 // UdfAllocateIoContext ( 01693 // ); 01694 // 01695 // VOID 01696 // UdfFreeIoContext ( 01697 // PUDF_IO_CONTEXT IoContext 01698 // ); 01699 // 01700 01701 #define UdfAllocateIoContext() \ 01702 FsRtlAllocatePoolWithTag( UdfNonPagedPool, \ 01703 sizeof( UDF_IO_CONTEXT ), \ 01704 TAG_IO_CONTEXT ) 01705 01706 #define UdfFreeIoContext(IO) ExFreePool( IO ) 01707 01708 // 01709 // VOID 01710 // UdfIncrementCleanupCounts ( 01711 // IN PIRP_CONTEXT IrpContext, 01712 // IN PFCB Fcb 01713 // ); 01714 // 01715 // VOID 01716 // UdfDecrementCleanupCounts ( 01717 // IN PIRP_CONTEXT IrpContext, 01718 // IN PFCB Fcb 01719 // ); 01720 // 01721 // VOID 01722 // UdfIncrementReferenceCounts ( 01723 // IN PIRP_CONTEXT IrpContext, 01724 // IN PFCB Fcb, 01725 // IN ULONG ReferenceCount 01726 // IN ULONG UserReferenceCount 01727 // ); 01728 // 01729 // VOID 01730 // UdfDecrementReferenceCounts ( 01731 // IN PIRP_CONTEXT IrpContext, 01732 // IN PFCB Fcb, 01733 // IN ULONG ReferenceCount 01734 // IN ULONG UserReferenceCount 01735 // ); 01736 // 01737 // VOID 01738 // UdfIncrementFcbReference ( 01739 // IN PIRP_CONTEXT IrpContext, 01740 // IN PFCB Fcb 01741 // ); 01742 // 01743 // VOID 01744 // UdfDecrementFcbReference ( 01745 // IN PIRP_CONTEXT IrpContext, 01746 // IN PFCB Fcb 01747 // ); 01748 // 01749 01750 #define UdfIncrementCleanupCounts(IC,F) { \ 01751 ASSERT_LOCKED_VCB( (F)->Vcb ); \ 01752 (F)->FcbCleanup += 1; \ 01753 (F)->Vcb->VcbCleanup += 1; \ 01754 } 01755 01756 #define UdfDecrementCleanupCounts(IC,F) { \ 01757 ASSERT_LOCKED_VCB( (F)->Vcb ); \ 01758 (F)->FcbCleanup -= 1; \ 01759 (F)->Vcb->VcbCleanup -= 1; \ 01760 } 01761 01762 #define UdfIncrementReferenceCounts(IC,F,C,UC) { \ 01763 ASSERT_LOCKED_VCB( (F)->Vcb ); \ 01764 (F)->FcbReference += (C); \ 01765 (F)->FcbUserReference += (UC); \ 01766 (F)->Vcb->VcbReference += (C); \ 01767 (F)->Vcb->VcbUserReference += (UC); \ 01768 } 01769 01770 #define UdfDecrementReferenceCounts(IC,F,C,UC) { \ 01771 ASSERT_LOCKED_VCB( (F)->Vcb ); \ 01772 (F)->FcbReference -= (C); \ 01773 (F)->FcbUserReference -= (UC); \ 01774 (F)->Vcb->VcbReference -= (C); \ 01775 (F)->Vcb->VcbUserReference -= (UC); \ 01776 } 01777 01778 VOID 01779 UdfTeardownStructures ( 01780 IN PIRP_CONTEXT IrpContext, 01781 IN PFCB StartingFcb, 01782 IN BOOLEAN Recursive, 01783 OUT PBOOLEAN RemovedStartingFcb 01784 ); 01785 01786 PFCB 01787 UdfLookupFcbTable ( 01788 IN PIRP_CONTEXT IrpContext, 01789 IN PVCB Vcb, 01790 IN FILE_ID FileId 01791 ); 01792 01793 PFCB 01794 UdfGetNextFcb ( 01795 IN PIRP_CONTEXT IrpContext, 01796 IN PVCB Vcb, 01797 IN PVOID *RestartKey 01798 ); 01799 01800 PFCB 01801 UdfCreateFcb ( 01802 IN PIRP_CONTEXT IrpContext, 01803 IN FILE_ID FileId, 01804 IN NODE_TYPE_CODE NodeTypeCode, 01805 OUT PBOOLEAN FcbExisted OPTIONAL 01806 ); 01807 01808 VOID 01809 UdfDeleteFcb ( 01810 IN PIRP_CONTEXT IrpContext, 01811 IN PFCB Fcb 01812 ); 01813 01814 VOID 01815 UdfInitializeFcbFromIcbContext ( 01816 IN PIRP_CONTEXT IrpContext, 01817 IN PFCB Fcb, 01818 IN PICB_SEARCH_CONTEXT IcbContext 01819 ); 01820 01821 PCCB 01822 UdfCreateCcb ( 01823 IN PIRP_CONTEXT IrpContext, 01824 IN PFCB Fcb, 01825 IN PLCB Lcb OPTIONAL, 01826 IN ULONG Flags 01827 ); 01828 01829 VOID 01830 UdfDeleteCcb ( 01831 IN PIRP_CONTEXT IrpContext, 01832 IN PCCB Ccb 01833 ); 01834 01835 ULONG 01836 UdfFindInParseTable ( 01837 IN PPARSE_KEYVALUE ParseTable, 01838 IN PCHAR Id, 01839 IN ULONG MaxIdLen 01840 ); 01841 01842 BOOLEAN 01843 UdfVerifyDescriptor ( 01844 IN PIRP_CONTEXT IrpContext, 01845 IN PDESTAG Descriptor, 01846 IN USHORT Tag, 01847 IN ULONG Size, 01848 IN ULONG Lbn, 01849 IN BOOLEAN ReturnError 01850 ); 01851 01852 VOID 01853 UdfInitializeIcbContextFromFcb ( 01854 IN PIRP_CONTEXT IrpContext, 01855 IN PICB_SEARCH_CONTEXT IcbContext, 01856 IN PFCB Fcb 01857 ); 01858 01859 VOID 01860 UdfInitializeIcbContext ( 01861 IN PIRP_CONTEXT IrpContext, 01862 IN PICB_SEARCH_CONTEXT IcbContext, 01863 IN PVCB Vcb, 01864 IN USHORT IcbType, 01865 IN USHORT Partition, 01866 IN ULONG Lbn, 01867 IN ULONG Length 01868 ); 01869 01870 INLINE 01871 VOID 01872 UdfFastInitializeIcbContext ( 01873 IN PIRP_CONTEXT IrpContext, 01874 IN PICB_SEARCH_CONTEXT IcbContext 01875 ) 01876 { 01877 01878 RtlZeroMemory( IcbContext, sizeof( ICB_SEARCH_CONTEXT )); 01879 } 01880 01881 VOID 01882 UdfLookupActiveIcb ( 01883 IN PIRP_CONTEXT IrpContext, 01884 IN PICB_SEARCH_CONTEXT IcbContext 01885 ); 01886 01887 01888 VOID 01889 UdfCleanupIcbContext ( 01890 IN PIRP_CONTEXT IrpContext, 01891 IN PICB_SEARCH_CONTEXT IcbContext 01892 ); 01893 01894 VOID 01895 UdfInitializeAllocations ( 01896 IN PIRP_CONTEXT IrpContext, 01897 IN PFCB Fcb, 01898 IN PICB_SEARCH_CONTEXT IcbContext 01899 ); 01900 01901 VOID 01902 UdfUpdateTimestampsFromIcbContext ( 01903 IN PIRP_CONTEXT IrpContext, 01904 IN PICB_SEARCH_CONTEXT IcbContext, 01905 IN PTIMESTAMP_BUNDLE Timestamps 01906 ); 01907 01908 BOOLEAN 01909 UdfCreateFileLock ( 01910 IN PIRP_CONTEXT IrpContext OPTIONAL, 01911 IN PFCB Fcb, 01912 IN BOOLEAN RaiseOnError 01913 ); 01914 01915 // 01916 // The following macro converts from UDF time to NT time. 01917 // 01918 01919 INLINE 01920 VOID 01921 UdfConvertUdfTimeToNtTime ( 01922 IN PIRP_CONTEXT IrpContext, 01923 IN PTIMESTAMP UdfTime, 01924 OUT PLARGE_INTEGER NtTime 01925 ) 01926 { 01927 TIME_FIELDS TimeField; 01928 01929 TimeField.Year = UdfTime->Year; 01930 TimeField.Month = UdfTime->Month; 01931 TimeField.Day = UdfTime->Day; 01932 TimeField.Hour = UdfTime->Hour; 01933 TimeField.Minute = UdfTime->Minute; 01934 TimeField.Second = UdfTime->Second; 01935 01936 // 01937 // This is where it gets hairy. For some unholy reason, ISO 13346 timestamps 01938 // carve the right of the decimal point up into three fields of precision 01939 // 10-2, 10-4, and 10-6, each ranging from 0-99. Lawdy. 01940 // 01941 // To make it easier, since they cannot cause a wrap into the next second, 01942 // just save it all up and add it in after the conversion. 01943 // 01944 01945 TimeField.Milliseconds = 0; 01946 01947 if (UdfTime->Type <= 1 && 01948 ((UdfTime->Zone >= TIMESTAMP_Z_MIN && UdfTime->Zone <= TIMESTAMP_Z_MAX) || 01949 UdfTime->Zone == TIMESTAMP_Z_NONE) && 01950 RtlTimeFieldsToTime( &TimeField, NtTime )) { 01951 01952 // 01953 // Now fold in the remaining sub-second "precision". Read as coversions 01954 // through the 10-3 units, then into our 10-7 base. (centi->milli->micro, 01955 // etc). 01956 // 01957 01958 NtTime->QuadPart += ((UdfTime->CentiSecond * (10 * 1000)) + 01959 (UdfTime->Usec100 * 100) + 01960 UdfTime->Usec) * 10; 01961 01962 // 01963 // Perform TZ normalization if this is a local time with 01964 // specified timezone. 01965 // 01966 01967 if (UdfTime->Type == 1 && UdfTime->Zone != TIMESTAMP_Z_NONE) { 01968 01969 NtTime->QuadPart += Int32x32To64( -UdfTime->Zone, (60 * 10 * 1000 * 1000) ); 01970 } 01971 01972 } else { 01973 01974 // 01975 // Epoch. Malformed timestamp. 01976 // 01977 01978 NtTime->QuadPart = 0; 01979 } 01980 } 01981 01982 // 01983 // An equivalence test for Entity IDs. 01984 // 01985 01986 INLINE 01987 BOOLEAN 01988 UdfEqualEntityId ( 01989 IN PREGID RegID, 01990 IN PSTRING Id, 01991 IN OPTIONAL PSTRING Suffix 01992 ) 01993 { 01994 01995 return (UdfEqualCountedString( Id, RegID->Identifier ) && 01996 01997 #ifndef UDF_SUPPORT_NONSTANDARD_ENTITY_STRINGTERM 01998 01999 // 02000 // Allow disabling of the check that the identifier 02001 // seems to be padded with zero. 02002 // 02003 // Reason: a couple samples that are otherwise useful 02004 // padded some identifiers with junk. 02005 // 02006 02007 ((Id->Length == sizeof(RegID->Identifier) || 02008 RegID->Identifier[Id->Length] == '\0') || 02009 02010 !DebugTrace(( 0, Dbg, 02011 "UdfEqualEntityId, RegID seems to be terminated with junk!\n" ))) && 02012 #endif 02013 02014 ((Suffix == NULL) || UdfEqualCountedString( Suffix, RegID->Suffix ))); 02015 } 02016 02017 // 02018 // A Domain Identifier RegID is considered to be contained if the 02019 // text string identifier matches and the revision is less than or 02020 // equal. This is the convenient way to check that a Domain ID 02021 // indicates a set of structures will be intelligible to a given 02022 // implementation level. 02023 // 02024 02025 INLINE 02026 BOOLEAN 02027 UdfDomainIdentifierContained ( 02028 IN PREGID RegID, 02029 IN PSTRING Domain, 02030 IN USHORT RevisionMin, 02031 IN USHORT RevisionMax 02032 ) 02033 { 02034 PUDF_SUFFIX_DOMAIN DomainSuffix = (PUDF_SUFFIX_DOMAIN) RegID->Suffix; 02035 02036 #ifdef UDF_SUPPORT_NONSTANDARD_ALLSTOR 02037 02038 // 02039 // Disable checking of the UDF revision. 02040 // 02041 // Reason: first drop of Allstor media recorded the version number as 02042 // a decimal number, not hex (102 = 0x66) 02043 // 02044 02045 return (UdfEqualEntityId( RegID, Domain, NULL )); 02046 02047 #else 02048 02049 return ((DomainSuffix->UdfRevision <= RevisionMax && DomainSuffix->UdfRevision >= RevisionMin) && 02050 UdfEqualEntityId( RegID, Domain, NULL )); 02051 #endif 02052 } 02053 02054 // 02055 // In like fashion, we define containment for a UDF Identifier RegID. 02056 // 02057 02058 INLINE 02059 BOOLEAN 02060 UdfUdfIdentifierContained ( 02061 IN PREGID RegID, 02062 IN PSTRING Type, 02063 IN USHORT RevisionMin, 02064 IN USHORT RevisionMax, 02065 IN UCHAR OSClass, 02066 IN UCHAR OSIdentifier 02067 ) 02068 { 02069 PUDF_SUFFIX_UDF UdfSuffix = (PUDF_SUFFIX_UDF) RegID->Suffix; 02070 02071 return ((UdfSuffix->UdfRevision <= RevisionMax && UdfSuffix->UdfRevision >= RevisionMin) && 02072 (OSClass == OSCLASS_INVALID || UdfSuffix->OSClass == OSClass) && 02073 (OSIdentifier == OSIDENTIFIER_INVALID || UdfSuffix->OSIdentifier == OSIdentifier) && 02074 UdfEqualEntityId( RegID, Type, NULL )); 02075 } 02076 02077 02078 // 02079 // Verification support routines. Contained in verfysup.c 02080 // 02081 02082 BOOLEAN 02083 UdfCheckForDismount ( 02084 IN PIRP_CONTEXT IrpContext, 02085 IN PVCB Vcb, 02086 IN BOOLEAN Force 02087 ); 02088 02089 BOOLEAN 02090 UdfDismountVcb ( 02091 IN PIRP_CONTEXT IrpContext, 02092 IN PVCB Vcb 02093 ); 02094 02095 VOID 02096 UdfVerifyVcb ( 02097 IN PIRP_CONTEXT IrpContext, 02098 IN PVCB Vcb 02099 ); 02100 02101 BOOLEAN 02102 UdfVerifyFcbOperation ( 02103 IN PIRP_CONTEXT IrpContext OPTIONAL, 02104 IN PFCB Fcb 02105 ); 02106 02107 // 02108 // BOOLEAN 02109 // UdfIsRawDevice ( 02110 // IN PIRP_CONTEXT IrpContext, 02111 // IN NTSTATUS Status 02112 // ); 02113 // 02114 02115 #define UdfIsRawDevice(IC,S) ( \ 02116 ((S) == STATUS_DEVICE_NOT_READY) || \ 02117 ((S) == STATUS_NO_MEDIA_IN_DEVICE) \ 02118 ) 02119 02120 02121 // 02122 // Volume Mapped Control Blocks routines, implemented in VmcbSup.c 02123 // 02124 02125 VOID 02126 UdfInitializeVmcb ( 02127 IN PVMCB Vmcb, 02128 IN POOL_TYPE PoolType, 02129 IN ULONG MaximumLbn, 02130 IN ULONG LbSize 02131 ); 02132 02133 VOID 02134 UdfUninitializeVmcb ( 02135 IN PVMCB Vmcb 02136 ); 02137 02138 VOID 02139 UdfResetVmcb ( 02140 IN PVMCB Vmcb 02141 ); 02142 02143 VOID 02144 UdfSetMaximumLbnVmcb ( 02145 IN PVMCB Vmcb, 02146 IN ULONG MaximumLbn 02147 ); 02148 02149 BOOLEAN 02150 UdfVmcbVbnToLbn ( 02151 IN PVMCB Vmcb, 02152 IN VBN Vbn, 02153 OUT PLBN Lbn, 02154 OUT PULONG SectorCount OPTIONAL 02155 ); 02156 02157 BOOLEAN 02158 UdfVmcbLbnToVbn ( 02159 IN PVMCB Vmcb, 02160 IN LBN Lbn, 02161 OUT PVBN Vbn, 02162 OUT PULONG SectorCount OPTIONAL 02163 ); 02164 02165 BOOLEAN 02166 UdfAddVmcbMapping ( 02167 IN PVMCB Vmcb, 02168 IN LBN Lbn, 02169 IN ULONG SectorCount, 02170 IN BOOLEAN ExactEnd, 02171 OUT PVBN Vbn, 02172 OUT PULONG AlignedSectorCount 02173 ); 02174 02175 VOID 02176 UdfRemoveVmcbMapping ( 02177 IN PVMCB Vmcb, 02178 IN LBN Lbn, 02179 IN ULONG SectorCount 02180 ); 02181 02182 02183 // 02184 // Routines to verify the correspondance of the underlying media, implemented in 02185 // verfysup.c 02186 // 02187 02188 NTSTATUS 02189 UdfPerformVerify ( 02190 IN PIRP_CONTEXT IrpContext, 02191 IN PIRP Irp, 02192 IN PDEVICE_OBJECT DeviceToVerify 02193 ); 02194 02195 02196 // 02197 // Work queue routines for posting and retrieving an Irp, implemented in 02198 // workque.c 02199 // 02200 02201 NTSTATUS 02202 UdfFsdPostRequest( 02203 IN PIRP_CONTEXT IrpContext, 02204 IN PIRP Irp 02205 ); 02206 02207 VOID 02208 UdfPrePostIrp ( 02209 IN PIRP_CONTEXT IrpContext, 02210 IN PIRP Irp 02211 ); 02212 02213 VOID 02214 UdfOplockComplete ( 02215 IN PIRP_CONTEXT IrpContext, 02216 IN PIRP Irp 02217 ); 02218 02219 02220 // 02221 // Charspecs are small containers that specify a CS<N> type and a text 02222 // string specifying a version, etc. This is a convenient way of bottling 02223 // up equivalence checks of a charspec. 02224 // 02225 02226 INLINE 02227 BOOLEAN 02228 UdfEqualCharspec ( 02229 IN PCHARSPEC Charspec, 02230 IN PSTRING Identifier, 02231 IN UCHAR Type 02232 ) 02233 { 02234 return ((Charspec->Type == Type) && UdfEqualCountedString( Identifier, Charspec->Info)); 02235 } 02236 02237 02238 // 02239 // The FSP level dispatch/main routine. This is the routine that takes 02240 // IRP's off of the work queue and calls the appropriate FSP level 02241 // work routine. 02242 // 02243 02244 VOID 02245 UdfFspDispatch ( // implemented in FspDisp.c 02246 IN PIRP_CONTEXT IrpContext 02247 ); 02248 02249 VOID 02250 UdfFspClose ( // Implemented in Close.c 02251 IN PVCB Vcb OPTIONAL 02252 ); 02253 02254 // 02255 // The following routines are the entry points for the different operations 02256 // based on the IrpSp major functions. 02257 // 02258 02259 NTSTATUS 02260 UdfCommonCleanup ( // Implemented in Cleanup.c 02261 IN PIRP_CONTEXT IrpContext, 02262 IN PIRP Irp 02263 ); 02264 02265 NTSTATUS 02266 UdfCommonClose ( // Implemented in Close.c 02267 IN PIRP_CONTEXT IrpContext, 02268 IN PIRP Irp 02269 ); 02270 02271 NTSTATUS 02272 UdfCommonCreate ( // Implemented in Create.c 02273 IN PIRP_CONTEXT IrpContext, 02274 IN PIRP Irp 02275 ); 02276 02277 NTSTATUS // Implemented in DevCtrl.c 02278 UdfCommonDevControl ( 02279 IN PIRP_CONTEXT IrpContext, 02280 IN PIRP Irp 02281 ); 02282 02283 NTSTATUS // Implemented in DirCtrl.c 02284 UdfCommonDirControl ( 02285 IN PIRP_CONTEXT IrpContext, 02286 IN PIRP Irp 02287 ); 02288 02289 NTSTATUS 02290 UdfCommonFsControl ( // Implemented in FsCtrl.c 02291 IN PIRP_CONTEXT IrpContext, 02292 IN PIRP Irp 02293 ); 02294 02295 NTSTATUS // Implemented in LockCtrl.c 02296 UdfCommonLockControl ( 02297 IN PIRP_CONTEXT IrpContext, 02298 IN PIRP Irp 02299 ); 02300 02301 NTSTATUS // Implemented in Pnp.c 02302 UdfCommonPnp ( 02303 IN PIRP_CONTEXT IrpContext, 02304 IN PIRP Irp 02305 ); 02306 02307 NTSTATUS // Implemented in FileInfo.c 02308 UdfCommonQueryInfo ( 02309 IN PIRP_CONTEXT IrpContext, 02310 IN PIRP Irp 02311 ); 02312 02313 NTSTATUS // Implemented in VolInfo.c 02314 UdfCommonQueryVolInfo ( 02315 IN PIRP_CONTEXT IrpContext, 02316 IN PIRP Irp 02317 ); 02318 02319 NTSTATUS // Implemented in Read.c 02320 UdfCommonRead ( 02321 IN PIRP_CONTEXT IrpContext, 02322 IN PIRP Irp 02323 ); 02324 02325 NTSTATUS // Implemented in FileInfo.c 02326 UdfCommonSetInfo ( 02327 IN PIRP_CONTEXT IrpContext, 02328 IN PIRP Irp 02329 ); 02330 02331 02332 // 02333 // Clean up our internal-to-the-header definitions so they do not leak out. 02334 // 02335 02336 #undef BugCheckFileId 02337 #undef Dbg 02338 02339 02340 #endif // _UDFPROCS_

Generated on Sat May 15 19:42:10 2004 for test by doxygen 1.3.7