Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2691 lines
64 KiB

  1. /*++
  2. Copyright (c) 1989-2000 Microsoft Corporation
  3. Module Name:
  4. UdfProcs.h
  5. Abstract:
  6. This module defines all of the globally used procedures in the Udfs
  7. file system.
  8. // @@BEGIN_DDKSPLIT
  9. Author:
  10. Dan Lovinger [DanLo] 29-May-1996
  11. Revision History:
  12. Tom Jolly [TomJolly] 1-March-2000 UDF 2.01 support
  13. // @@END_DDKSPLIT
  14. --*/
  15. #ifndef _UDFPROCS_
  16. #define _UDFPROCS_
  17. #include <ntifs.h>
  18. #include <ntddscsi.h>
  19. #include <scsi.h>
  20. #include <ntddmmc.h>
  21. #include <ntddcdrm.h>
  22. #include <ntddcdvd.h>
  23. #include <ntdddisk.h>
  24. #include <ntddstor.h>
  25. #ifndef INLINE
  26. #define INLINE __inline
  27. #endif
  28. //
  29. // Compile in experimental code for mounting 'open' CD-R / DVD-R media.
  30. //
  31. // #define EXPERIMENTAL_MOUNT_OPEN_R_MEDIA
  32. //
  33. // Turn on the sanity checks if this is DBG or UDF_FREE_ASSERTS
  34. //
  35. #if DBG || UDF_FREE_ASSERTS
  36. #undef UDF_SANITY
  37. #define UDF_SANITY
  38. #ifdef _X86_
  39. #define UDF_CAPTURE_BACKTRACES
  40. #endif
  41. #endif
  42. #include "nodetype.h"
  43. #include "Udf.h"
  44. #include "UdfStruc.h"
  45. #include "UdfData.h"
  46. //
  47. // The Bug check file id for this module
  48. //
  49. #define BugCheckFileId (UDFS_BUG_CHECK_STRUCSUP)
  50. //
  51. // The local debug trace level
  52. //
  53. #define Dbg (UDFS_DEBUG_LEVEL_STRUCSUP)
  54. //
  55. // Miscellaneous support routines/macros
  56. //
  57. //
  58. // Yet another declaration of Min/Max
  59. //
  60. #ifndef Min
  61. #define Min(a, b) ((a) < (b) ? (a) : (b))
  62. #endif
  63. #ifndef Max
  64. #define Max(a, b) ((a) > (b) ? (a) : (b))
  65. #endif
  66. //
  67. // Yet another declaration of the basic bit fiddlers
  68. //
  69. #ifndef FlagMask
  70. #define FlagMask(F,SF) ( \
  71. ((F) & (SF)) \
  72. )
  73. #endif
  74. //#ifndef BooleanFlagOn
  75. //#define BooleanFlagOn(F,SF) ( \
  76. // (BOOLEAN)(FlagOn(F, SF) != 0) \
  77. //)
  78. //#endif
  79. #ifndef BooleanFlagOff
  80. #define BooleanFlagOff(F,SF) ( \
  81. (BOOLEAN)(FlagOn(F, SF)) == 0) \
  82. )
  83. #endif
  84. //#ifndef SetFlag
  85. //#define SetFlag(Flags,SingleFlag) ( \
  86. // (Flags) |= (SingleFlag) \
  87. //)
  88. //#endif
  89. //#ifndef ClearFlag
  90. //#define ClearFlag(Flags,SingleFlag) ( \
  91. // (Flags) &= ~(SingleFlag) \
  92. //)
  93. //#endif
  94. //
  95. // CAST
  96. // Add2Ptr (
  97. // IN PVOID Pointer,
  98. // IN ULONG Increment
  99. // IN (CAST)
  100. // );
  101. //
  102. // ULONG
  103. // PtrOffset (
  104. // IN PVOID BasePtr,
  105. // IN PVOID OffsetPtr
  106. // );
  107. //
  108. #define Add2Ptr(PTR,INC,CAST) ((CAST)((ULONG_PTR)(PTR) + (INC)))
  109. #define PtrOffset(BASE,OFFSET) ((ULONG)((ULONG)(OFFSET) - (ULONG)(BASE)))
  110. //
  111. // Generic truncation/align/offset/remainder macros for power-of-two units.
  112. //
  113. // The offset and remainder functions range from zero to (unit - 1). The
  114. // re-offset in the remainder performs this work.
  115. //
  116. #define GenericTruncate(B, U) ( \
  117. (B) & ~((U) - 1) \
  118. )
  119. #define GenericAlign(B, U) ( \
  120. GenericTruncate((B) + (U) - 1, U) \
  121. )
  122. #define GenericOffset(B, U) ( \
  123. (B) & ((U) - 1) \
  124. )
  125. #define GenericRemainder(B, U) ( \
  126. GenericOffset( (U) - GenericOffset((B), (U)), (U) ) \
  127. )
  128. #define GenericTruncatePtr(B, U) ( \
  129. (PVOID)(((ULONG_PTR)(B)) & ~((U) - 1)) \
  130. )
  131. #define GenericAlignPtr(B, U) ( \
  132. GenericTruncatePtr((B) + (U) - 1, (U)) \
  133. )
  134. #define GenericOffsetPtr(B, U) ( \
  135. (ULONG)(((ULONG_PTR)(B)) & ((U) - 1)) \
  136. )
  137. #define GenericRemainderPtr(B, U) ( \
  138. (ULONG)GenericOffset( (U) - GenericOffsetPtr((B), (U)), (U) ) \
  139. )
  140. //
  141. // Useful compositions of the defaults for common types.
  142. //
  143. #define WordAlign(B) GenericAlign((B), 2)
  144. #define LongAlign(B) GenericAlign((B), 4)
  145. #define QuadAlign(B) GenericAlign((B), 8)
  146. #define WordOffset(B) GenericOffset((B), 2)
  147. #define LongOffset(B) GenericOffset((B), 4)
  148. #define QuadOffset(B) GenericOffset((B), 8)
  149. #define WordAlignPtr(P) GenericAlignPtr((P), 2)
  150. #define LongAlignPtr(P) GenericAlignPtr((P), 4)
  151. #define QuadAlignPtr(P) GenericAlignPtr((P), 8)
  152. #define WordOffsetPtr(P) GenericOffsetPtr((P), 2)
  153. #define LongOffsetPtr(P) GenericOffsetPtr((P), 4)
  154. #define QuadOffsetPtr(P) GenericOffsetPtr((P), 8)
  155. //
  156. // Macros to round up and down on sector and logical block boundaries. Although
  157. // UDF 1.01 specifies that a physical sector is the logical block size we will
  158. // be general and treat sectors and logical blocks as distinct. Since UDF may
  159. // at some point relax the restriction, these definitions will be the only
  160. // acknowledgement outside of the mount path (which merely checks the volume's
  161. // conformance).
  162. //
  163. //
  164. // Use INLINEd functions here to catch misuse (ULONGLONG into ULONG etc).
  165. //
  166. //
  167. // Sector
  168. //
  169. INLINE
  170. ULONG
  171. SectorAlignN(
  172. ULONG SectorSize,
  173. ULONG Length
  174. ) {
  175. return (Length + (SectorSize - 1)) & ~(SectorSize - 1);
  176. }
  177. INLINE
  178. ULONG
  179. SectorAlign(
  180. PVCB Vcb,
  181. ULONG Length
  182. ) {
  183. return (Length + (Vcb->SectorSize - 1)) & ~(Vcb->SectorSize - 1);
  184. }
  185. INLINE
  186. ULONGLONG
  187. LlSectorAlign(
  188. PVCB Vcb,
  189. ULONGLONG Length
  190. ) {
  191. return (Length + (Vcb->SectorSize - 1)) & ~(ULONGLONG)(Vcb->SectorSize - 1);
  192. }
  193. INLINE
  194. ULONG
  195. SectorTruncate(
  196. PVCB Vcb,
  197. ULONG Length
  198. ) {
  199. return (Length & ~(Vcb->SectorSize - 1));
  200. }
  201. #define LlSectorTruncate(V, L) ( \
  202. ((LONGLONG)(L)) & ~(((LONGLONG)(V)->SectorSize) - 1) \
  203. )
  204. INLINE
  205. ULONG
  206. BytesFromSectors(
  207. PVCB Vcb,
  208. ULONG Sectors
  209. ) {
  210. //
  211. // Test for 32 bit overflow in the result
  212. //
  213. ASSERT( (Sectors & ~(0xffffffff >> Vcb->SectorShift)) == 0);
  214. return (ULONG)(Sectors << Vcb->SectorShift);
  215. }
  216. INLINE
  217. ULONG
  218. SectorsFromBytes(
  219. PVCB Vcb,
  220. ULONG Bytes
  221. ) {
  222. return (Bytes >> Vcb->SectorShift);
  223. }
  224. INLINE
  225. ULONG
  226. SectorsFromLlBytes(
  227. PVCB Vcb,
  228. ULONGLONG Bytes
  229. ) {
  230. return (ULONG)(Bytes >> Vcb->SectorShift);
  231. }
  232. #define LlBytesFromSectors(V, L) ( \
  233. Int64ShllMod32( (ULONGLONG)(L), ((V)->SectorShift) ) \
  234. )
  235. #define LlSectorsFromBytes(V, L) ( \
  236. Int64ShrlMod32( (ULONGLONG)(L), ((V)->SectorShift) ) \
  237. )
  238. #define SectorsFromBlocks(V, B) (B)
  239. #define SectorSize(V) ((V)->SectorSize)
  240. INLINE
  241. ULONG
  242. SectorOffset(
  243. IN PVCB Vcb,
  244. IN ULONGLONG Length
  245. )
  246. {
  247. return (ULONG)(Length & (Vcb->SectorSize - 1));
  248. }
  249. //
  250. // Logical Block
  251. //
  252. #define BlockAlignN(BLOCKSIZE, L) ( \
  253. SectorAlighN((BLOCKSIZE), (L)) \
  254. )
  255. #define BlockAlign(V, L) ( \
  256. SectorAlign((V), (L)) \
  257. )
  258. #define LlBlockAlign(V, L) ( \
  259. LlSectorAlign((V), (L)) \
  260. )
  261. #define BlockTruncate(V, L) ( \
  262. SectorTruncate((V), (L)) \
  263. )
  264. #define LlBlockTruncate(V, L) ( \
  265. LlSectorTruncate((V), (L)) \
  266. )
  267. #define BytesFromBlocks(V, L) ( \
  268. BytesFromSectors((V), (L)) \
  269. )
  270. #define BlocksFromBytes(V, L) ( \
  271. SectorsFromBytes((V), (L)) \
  272. )
  273. #define LlBytesFromBlocks(V, L) ( \
  274. LlBytesFromSectors((V), (L)) \
  275. )
  276. #define LlBlocksFromBytes(V, L) ( \
  277. LlSectorsFromBytes((V), (L)) \
  278. )
  279. #define BlocksFromSectors(V, S) (S)
  280. #define BlockSize(V) (SectorSize(V))
  281. #define BlockOffset(V, L) ( \
  282. SectorOffset((V), (L)) \
  283. )
  284. //
  285. // The following types and macros are used to help unpack the packed and
  286. // misaligned fields found in various structures.
  287. //
  288. typedef union _UCHAR1 {
  289. UCHAR Uchar[1];
  290. UCHAR ForceAlignment;
  291. } UCHAR1, *PUCHAR1;
  292. typedef union _UCHAR2 {
  293. UCHAR Uchar[2];
  294. USHORT ForceAlignment;
  295. } UCHAR2, *PUCHAR2;
  296. typedef union _UCHAR4 {
  297. UCHAR Uchar[4];
  298. ULONG ForceAlignment;
  299. } UCHAR4, *PUCHAR4;
  300. typedef union _USHORT2 {
  301. USHORT Ushort[2];
  302. ULONG ForceAlignment;
  303. } USHORT2, *PUSHORT2;
  304. //
  305. // This macro copies an unaligned src byte to an aligned dst byte
  306. //
  307. #define CopyUchar1(Dst,Src) { \
  308. *((UCHAR1 *)(Dst)) = *((UNALIGNED UCHAR1 *)(Src)); \
  309. }
  310. //
  311. // This macro copies an unaligned src word to an aligned dst word
  312. //
  313. #define CopyUchar2(Dst,Src) { \
  314. *((UCHAR2 *)(Dst)) = *((UNALIGNED UCHAR2 *)(Src)); \
  315. }
  316. //
  317. // This macro copies an unaligned src word to a dst word,
  318. // performing an little/big endian swap.
  319. //
  320. #define SwapCopyUchar2(Dst,Src) { \
  321. *((UNALIGNED UCHAR1 *)(Dst)) = *((UNALIGNED UCHAR1 *)(Src) + 1); \
  322. *((UNALIGNED UCHAR1 *)(Dst) + 1) = *((UNALIGNED UCHAR1 *)(Src)); \
  323. }
  324. //
  325. // This macro copies an unaligned src longword to an aligned dst longword
  326. //
  327. #define CopyUchar4(Dst,Src) { \
  328. *((UCHAR4 *)(Dst)) = *((UNALIGNED UCHAR4 *)(Src)); \
  329. }
  330. //
  331. // This macro copies an unaligned src longword to a dst longword,
  332. // performing an little/big endian swap.
  333. //
  334. #define SwapCopyUchar4(Dst,Src) { \
  335. *((UNALIGNED UCHAR1 *)(Dst)) = *((UNALIGNED UCHAR1 *)(Src) + 3); \
  336. *((UNALIGNED UCHAR1 *)(Dst) + 1) = *((UNALIGNED UCHAR1 *)(Src) + 2); \
  337. *((UNALIGNED UCHAR1 *)(Dst) + 2) = *((UNALIGNED UCHAR1 *)(Src) + 1); \
  338. *((UNALIGNED UCHAR1 *)(Dst) + 3) = *((UNALIGNED UCHAR1 *)(Src)); \
  339. }
  340. //
  341. // This macro copies an unaligned src longword to an aligned dsr longword
  342. // accessing the source on a word boundary.
  343. //
  344. #define CopyUshort2(Dst,Src) { \
  345. *((USHORT2 *)(Dst)) = *((UNALIGNED USHORT2 *)(Src));\
  346. }
  347. //
  348. // The following macro is used to determine if an FSD thread can block
  349. // for I/O or wait for a resource. It returns TRUE if the thread can
  350. // block and FALSE otherwise. This attribute can then be used to call
  351. // the FSD & FSP common work routine with the proper wait value.
  352. //
  353. #define CanFsdWait(I) IoIsOperationSynchronous(I)
  354. //
  355. // The following macro is used to set the fast i/o possible bits in the
  356. // FsRtl header.
  357. //
  358. // FastIoIsNotPossible - If the Fcb is bad or there are oplocks on the file.
  359. //
  360. // FastIoIsQuestionable - If there are file locks.
  361. //
  362. // FastIoIsPossible - In all other cases.
  363. //
  364. //
  365. #define UdfIsFastIoPossible(F) ((BOOLEAN) \
  366. ((((F)->Vcb->VcbCondition != VcbMounted ) || \
  367. !FsRtlOplockIsFastIoPossible( &(F)->Oplock )) ? \
  368. \
  369. FastIoIsNotPossible : \
  370. \
  371. ((((F)->FileLock != NULL) && FsRtlAreThereCurrentFileLocks( (F)->FileLock )) ? \
  372. \
  373. FastIoIsQuestionable : \
  374. \
  375. FastIoIsPossible)) \
  376. )
  377. //
  378. // The following macros encapsulate the common work of raising exceptions while storing
  379. // the exception in the IrpContext.
  380. //
  381. #ifdef UDF_SANITY
  382. DECLSPEC_NORETURN
  383. VOID
  384. UdfRaiseStatusEx (
  385. IN PIRP_CONTEXT IrpContext,
  386. IN NTSTATUS Status,
  387. IN BOOLEAN Normalize,
  388. IN ULONG FileId,
  389. IN ULONG Line
  390. );
  391. #else
  392. INLINE
  393. DECLSPEC_NORETURN
  394. VOID
  395. UdfRaiseStatusEx (
  396. IN PIRP_CONTEXT IrpContext,
  397. IN NTSTATUS Status,
  398. IN BOOLEAN Normalize,
  399. IN ULONG FileId,
  400. IN ULONG Line
  401. )
  402. {
  403. if (Normalize) {
  404. IrpContext->ExceptionStatus = FsRtlNormalizeNtstatus( Status, STATUS_UNEXPECTED_IO_ERROR);
  405. }
  406. else {
  407. IrpContext->ExceptionStatus = Status;
  408. }
  409. IrpContext->RaisedAtFileLine = (FileId << 16) | Line;
  410. ExRaiseStatus( IrpContext->ExceptionStatus );
  411. }
  412. #endif
  413. #define UdfRaiseStatus( IC, S) UdfRaiseStatusEx((IC),(S),FALSE,BugCheckFileId,__LINE__)
  414. #define UdfNormalizeAndRaiseStatus( IC, S) UdfRaiseStatusEx((IC),(S),TRUE,BugCheckFileId,__LINE__)
  415. //
  416. // The following is a convenience macro to execute a little code before making
  417. // a shortcircuit out of a surrounding try-finally clause. This is usually to
  418. // set a status value.
  419. //
  420. // Note that our compilers support the leave keyword now and we don't have to
  421. // use the old try_exit: labels and goto.
  422. //
  423. #define try_leave(S) { S; leave; }
  424. //
  425. // For debugging purposes we sometimes want to allocate our structures from nonpaged
  426. // pool so that in the kernel debugger we can walk all the structures.
  427. //
  428. #define UdfPagedPool PagedPool
  429. #define UdfNonPagedPool NonPagedPool
  430. #define UdfNonPagedPoolCacheAligned NonPagedPoolCacheAligned
  431. //
  432. // Encapsulate safe pool freeing
  433. //
  434. INLINE
  435. VOID
  436. UdfFreePool(
  437. IN PVOID *Pool
  438. )
  439. {
  440. if (*Pool != NULL) {
  441. ExFreePool(*Pool);
  442. *Pool = NULL;
  443. }
  444. }
  445. //
  446. // Encapsulate counted string compares with uncounted fields. Thanks to a
  447. // very smart compiler, we have to carefully tell it that no matter what it
  448. // thinks, it *cannot* do anything other than a bytewise compare.
  449. //
  450. INLINE
  451. BOOLEAN
  452. UdfEqualCountedString(
  453. IN PSTRING String,
  454. IN PCHAR Field
  455. )
  456. {
  457. return (RtlEqualMemory( (CHAR UNALIGNED *)String->Buffer,
  458. (CHAR UNALIGNED *)Field,
  459. String->Length ) != 0);
  460. }
  461. //
  462. // Type of opens. FilObSup.c depends on this order.
  463. //
  464. typedef enum _TYPE_OF_OPEN {
  465. UnopenedFileObject = 0,
  466. StreamFileOpen,
  467. UserVolumeOpen,
  468. UserDirectoryOpen,
  469. UserFileOpen,
  470. BeyondValidType
  471. } TYPE_OF_OPEN, *PTYPE_OF_OPEN;
  472. //
  473. // Following routines handle entry in and out of the filesystem. They are
  474. // contained in UdfData.c. We also get some very generic utility functions
  475. // here that aren't associated with any particular datastructure.
  476. //
  477. NTSTATUS
  478. UdfFsdDispatch (
  479. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  480. IN PIRP Irp
  481. );
  482. LONG
  483. UdfExceptionFilter (
  484. IN PIRP_CONTEXT IrpContext,
  485. IN PEXCEPTION_POINTERS ExceptionPointer
  486. );
  487. LONG
  488. UdfQueryDirExceptionFilter(
  489. IN PEXCEPTION_POINTERS ExceptionPointers
  490. );
  491. NTSTATUS
  492. UdfProcessException (
  493. IN PIRP_CONTEXT IrpContext OPTIONAL,
  494. IN PIRP Irp,
  495. IN NTSTATUS ExceptionCode
  496. );
  497. VOID
  498. UdfCompleteRequest (
  499. IN PIRP_CONTEXT IrpContext OPTIONAL,
  500. IN PIRP Irp OPTIONAL,
  501. IN NTSTATUS Status
  502. );
  503. //
  504. // Following are the routines to handle the top level thread logic.
  505. //
  506. VOID
  507. UdfSetThreadContext (
  508. IN PIRP_CONTEXT IrpContext,
  509. IN PTHREAD_CONTEXT ThreadContext
  510. );
  511. INLINE
  512. VOID
  513. UdfRestoreThreadContext (
  514. IN PIRP_CONTEXT IrpContext
  515. )
  516. {
  517. IrpContext->ThreadContext->Udfs = 0;
  518. IoSetTopLevelIrp( IrpContext->ThreadContext->SavedTopLevelIrp );
  519. IrpContext->ThreadContext = NULL;
  520. }
  521. //
  522. // Following are some generic utility functions we have to carry along for the ride
  523. //
  524. INLINE
  525. BOOLEAN
  526. UdfDeviceIsFsDo(
  527. IN PDEVICE_OBJECT Device
  528. )
  529. {
  530. #if (NUMBER_OF_FS_OBJECTS != 2)
  531. #error "Size of fsdo array changed - fixme!"
  532. #endif
  533. return (Device == UdfData.FileSystemDeviceObjects[0]) ||
  534. (Device == UdfData.FileSystemDeviceObjects[1]);
  535. }
  536. //
  537. // VOID
  538. // SafeZeroMemory (
  539. // IN PUCHAR At,
  540. // IN ULONG ByteCount
  541. // );
  542. //
  543. //
  544. // This macro just puts a nice little try-except around RtlZeroMemory
  545. //
  546. #define SafeZeroMemory(IC,AT,BYTE_COUNT) { \
  547. try { \
  548. RtlZeroMemory( (AT), (BYTE_COUNT) ); \
  549. } except( EXCEPTION_EXECUTE_HANDLER ) { \
  550. UdfRaiseStatus( IC, STATUS_INVALID_USER_BUFFER ); \
  551. } \
  552. }
  553. ULONG
  554. UdfSerial32 (
  555. IN PCHAR Buffer,
  556. IN ULONG ByteCount
  557. );
  558. VOID
  559. UdfInitializeCrc16 (
  560. ULONG Polynomial
  561. );
  562. USHORT
  563. UdfComputeCrc16 (
  564. IN PUCHAR Buffer,
  565. IN ULONG ByteCount
  566. );
  567. USHORT
  568. UdfComputeCrc16Uni (
  569. PWCHAR Buffer,
  570. ULONG CharCount
  571. );
  572. ULONG
  573. UdfHighBit (
  574. ULONG Word
  575. );
  576. //
  577. // Following are the fast entry points.
  578. //
  579. BOOLEAN
  580. UdfFastQueryBasicInfo (
  581. IN PFILE_OBJECT FileObject,
  582. IN BOOLEAN Wait,
  583. IN OUT PFILE_BASIC_INFORMATION Buffer,
  584. OUT PIO_STATUS_BLOCK IoStatus,
  585. IN PDEVICE_OBJECT DeviceObject
  586. );
  587. BOOLEAN
  588. UdfFastIoCheckIfPossible (
  589. IN PFILE_OBJECT FileObject,
  590. IN PLARGE_INTEGER FileOffset,
  591. IN ULONG Length,
  592. IN BOOLEAN Wait,
  593. IN ULONG LockKey,
  594. IN BOOLEAN CheckForReadOperation,
  595. OUT PIO_STATUS_BLOCK IoStatus,
  596. IN PDEVICE_OBJECT DeviceObject
  597. );
  598. BOOLEAN
  599. UdfFastLock (
  600. IN PFILE_OBJECT FileObject,
  601. IN PLARGE_INTEGER FileOffset,
  602. IN PLARGE_INTEGER Length,
  603. PEPROCESS ProcessId,
  604. ULONG Key,
  605. BOOLEAN FailImmediately,
  606. BOOLEAN ExclusiveLock,
  607. OUT PIO_STATUS_BLOCK IoStatus,
  608. IN PDEVICE_OBJECT DeviceObject
  609. );
  610. BOOLEAN
  611. UdfFastQueryNetworkInfo (
  612. IN PFILE_OBJECT FileObject,
  613. IN BOOLEAN Wait,
  614. OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
  615. OUT PIO_STATUS_BLOCK IoStatus,
  616. IN PDEVICE_OBJECT DeviceObject
  617. );
  618. BOOLEAN
  619. UdfFastQueryStdInfo (
  620. IN PFILE_OBJECT FileObject,
  621. IN BOOLEAN Wait,
  622. IN OUT PFILE_STANDARD_INFORMATION Buffer,
  623. OUT PIO_STATUS_BLOCK IoStatus,
  624. IN PDEVICE_OBJECT DeviceObject
  625. );
  626. BOOLEAN
  627. UdfFastUnlockSingle (
  628. IN PFILE_OBJECT FileObject,
  629. IN PLARGE_INTEGER FileOffset,
  630. IN PLARGE_INTEGER Length,
  631. PEPROCESS ProcessId,
  632. ULONG Key,
  633. OUT PIO_STATUS_BLOCK IoStatus,
  634. IN PDEVICE_OBJECT DeviceObject
  635. );
  636. BOOLEAN
  637. UdfFastUnlockAll (
  638. IN PFILE_OBJECT FileObject,
  639. PEPROCESS ProcessId,
  640. OUT PIO_STATUS_BLOCK IoStatus,
  641. IN PDEVICE_OBJECT DeviceObject
  642. );
  643. BOOLEAN
  644. UdfFastUnlockAllByKey (
  645. IN PFILE_OBJECT FileObject,
  646. PVOID ProcessId,
  647. ULONG Key,
  648. OUT PIO_STATUS_BLOCK IoStatus,
  649. IN PDEVICE_OBJECT DeviceObject
  650. );
  651. //
  652. // File access check routine, implemented in AcChkSup.c
  653. //
  654. INLINE
  655. BOOLEAN
  656. UdfIllegalFcbAccess (
  657. IN PIRP_CONTEXT IrpContext,
  658. IN TYPE_OF_OPEN TypeOfOpen,
  659. IN ACCESS_MASK DesiredAccess
  660. )
  661. /*++
  662. Routine Description:
  663. This routine simply asserts that the access is legal for a readonly filesystem.
  664. Arguments:
  665. TypeOfOpen - type of open for the Fcb in question.
  666. DesiredAccess - mask of access the caller is trying for.
  667. Return Value:
  668. BOOLEAN True if illegal access, false otherwise.
  669. --*/
  670. {
  671. return BooleanFlagOn( DesiredAccess,
  672. (TypeOfOpen != UserVolumeOpen ?
  673. (FILE_WRITE_ATTRIBUTES |
  674. FILE_WRITE_DATA |
  675. FILE_WRITE_EA |
  676. FILE_ADD_FILE |
  677. FILE_ADD_SUBDIRECTORY |
  678. FILE_APPEND_DATA) : 0) |
  679. FILE_DELETE_CHILD |
  680. DELETE |
  681. WRITE_DAC );
  682. }
  683. //
  684. // Sector lookup routines, implemented in AllocSup.c
  685. //
  686. BOOLEAN
  687. UdfLookupAllocation (
  688. IN PIRP_CONTEXT IrpContext,
  689. IN PFCB Fcb,
  690. IN PCCB Ccb,
  691. IN LONGLONG FileOffset,
  692. OUT PLONGLONG DiskOffset,
  693. OUT PULONG ByteCount
  694. );
  695. VOID
  696. UdfDeletePcb (
  697. IN PPCB Pcb
  698. );
  699. NTSTATUS
  700. UdfInitializePcb (
  701. IN PIRP_CONTEXT IrpContext,
  702. IN PVCB Vcb,
  703. IN OUT PPCB *Pcb,
  704. IN PNSR_LVOL LVD
  705. );
  706. VOID
  707. UdfAddToPcb (
  708. IN PPCB Pcb,
  709. IN PNSR_PART PartitionDescriptor
  710. );
  711. NTSTATUS
  712. UdfCompletePcb(
  713. IN PIRP_CONTEXT IrpContext,
  714. IN PVCB Vcb,
  715. IN PPCB Pcb );
  716. BOOLEAN
  717. UdfEquivalentPcb (
  718. IN PIRP_CONTEXT IrpContext,
  719. IN PPCB Pcb1,
  720. IN PPCB Pcb2
  721. );
  722. ULONG
  723. UdfLookupPsnOfExtent (
  724. IN PIRP_CONTEXT IrpContext,
  725. IN PVCB Vcb,
  726. IN USHORT Reference,
  727. IN ULONG Lbn,
  728. IN ULONG Len
  729. );
  730. ULONG
  731. UdfLookupMetaVsnOfExtent (
  732. IN PIRP_CONTEXT IrpContext,
  733. IN PVCB Vcb,
  734. IN USHORT Reference,
  735. IN ULONG Lbn,
  736. IN ULONG Len,
  737. IN BOOLEAN ExactEnd
  738. );
  739. //
  740. //
  741. // Buffer control routines for data caching, implemented in CacheSup.c
  742. //
  743. VOID
  744. UdfCreateInternalStream (
  745. IN PIRP_CONTEXT IrpContext,
  746. IN PVCB Vcb,
  747. IN PFCB Fcb
  748. );
  749. VOID
  750. UdfDeleteInternalStream (
  751. IN PIRP_CONTEXT IrpContext,
  752. IN PFCB Fcb
  753. );
  754. NTSTATUS
  755. UdfCompleteMdl (
  756. IN PIRP_CONTEXT IrpContext,
  757. IN PIRP Irp
  758. );
  759. typedef enum {
  760. METAMAPOP_INIT_VIEW_ONLY = 0,
  761. METAMAPOP_REMAP_VIEW,
  762. METAMAPOP_INIT_AND_MAP
  763. } MAPMETAOP;
  764. VOID
  765. UdfMapMetadataView (
  766. IN PIRP_CONTEXT IrpContext,
  767. IN PMAPPED_PVIEW View,
  768. IN PVCB Vcb,
  769. IN USHORT Partition,
  770. IN ULONG Lbn,
  771. IN ULONG Length,
  772. IN MAPMETAOP Operation
  773. );
  774. NTSTATUS
  775. UdfPurgeVolume (
  776. IN PIRP_CONTEXT IrpContext,
  777. IN PVCB Vcb,
  778. IN BOOLEAN DismountUnderway
  779. );
  780. // VOID
  781. // UdfUnpinView (
  782. // IN PIRP_CONTEXT IrpContext,
  783. // IN PMAPPED_VIEW View
  784. // );
  785. //
  786. //
  787. // Also releases the Vcb->VmcbMappingResource if the view was actually CcMapped.
  788. #define UdfUnpinView(IC,V) \
  789. if (((V)->Bcb) != NULL) { \
  790. CcUnpinData( ((V)->Bcb) ); \
  791. UdfReleaseVmcb( (IC), (IC)->Vcb); \
  792. ((V)->Bcb) = NULL; \
  793. ((V)->View) = NULL; \
  794. ((V)->Vsn) = UDF_INVALID_VSN; \
  795. }
  796. // VOID
  797. // UdfUnpinData (
  798. // IN PIRP_CONTEXT IrpContext,
  799. // IN OUT PBCB *Bcb
  800. // );
  801. //
  802. #define UdfUnpinData(IC,B) \
  803. if (*(B) != NULL) { CcUnpinData( *(B) ); *(B) = NULL; }
  804. //
  805. // Device I/O routines, implemented in DevIoSup.c
  806. //
  807. // These routines perform the actual device reads and other communcation.
  808. // They do not affect any data structures.
  809. //
  810. #ifdef EXPERIMENTAL_MOUNT_OPEN_R_MEDIA
  811. NTSTATUS
  812. UdfSendSptCdb(
  813. IN PDEVICE_OBJECT Device,
  814. IN PCDB Cdb,
  815. IN PUCHAR Buffer,
  816. IN OUT PULONG BufferSize,
  817. IN BOOLEAN InputOperation,
  818. IN ULONG TimeOut,
  819. IN OPTIONAL PVOID TempBuffer,
  820. IN OPTIONAL ULONG TempBufferSize,
  821. OUT PULONG SenseKeyCodeQualifier,
  822. OUT PUSHORT ProgressIndication
  823. );
  824. #endif
  825. NTSTATUS
  826. UdfPerformDevIoCtrl (
  827. IN PIRP_CONTEXT IrpContext,
  828. IN ULONG IoControlCode,
  829. IN PDEVICE_OBJECT Device,
  830. IN PVOID InputBuffer OPTIONAL,
  831. IN ULONG InputBufferLength,
  832. OUT PVOID OutputBuffer OPTIONAL,
  833. IN ULONG OutputBufferLength,
  834. IN BOOLEAN InternalDeviceIoControl,
  835. IN BOOLEAN OverrideVerify,
  836. OUT PIO_STATUS_BLOCK Iosb OPTIONAL
  837. );
  838. NTSTATUS
  839. UdfReadSectors (
  840. IN PIRP_CONTEXT IrpContext,
  841. IN LONGLONG StartingOffset,
  842. IN ULONG ByteCount,
  843. IN BOOLEAN ReturnError,
  844. IN OUT PVOID Buffer,
  845. IN PDEVICE_OBJECT TargetDeviceObject
  846. );
  847. NTSTATUS
  848. UdfNonCachedRead (
  849. IN PIRP_CONTEXT IrpContext,
  850. IN PFCB Fcb,
  851. IN PCCB Ccb,
  852. IN LONGLONG StartingOffset,
  853. IN ULONG ByteCount
  854. );
  855. NTSTATUS
  856. UdfCreateUserMdl (
  857. IN PIRP_CONTEXT IrpContext,
  858. IN ULONG BufferLength,
  859. IN BOOLEAN RaiseOnError,
  860. IN ULONG Operation
  861. );
  862. VOID
  863. UdfWaitSync (
  864. IN PIRP_CONTEXT IrpContext
  865. );
  866. VOID
  867. UdfSingleAsync (
  868. IN PIRP_CONTEXT IrpContext,
  869. IN LONGLONG ByteOffset,
  870. IN ULONG ByteCount
  871. );
  872. //
  873. // VOID
  874. // UdfMapUserBuffer (
  875. // IN PIRP_CONTEXT IrpContext,
  876. // OUT PVOID Buffer
  877. // );
  878. //
  879. // Will raise on failure.
  880. //
  881. // VOID
  882. // UdfLockUserBuffer (
  883. // IN PIRP_CONTEXT IrpContext,
  884. // IN ULONG BufferLength
  885. // );
  886. //
  887. #define UdfMapUserBuffer(IC,UB) { \
  888. *(UB) = ((PVOID) (((IC)->Irp->MdlAddress == NULL) ? \
  889. (IC)->Irp->UserBuffer : \
  890. MmGetSystemAddressForMdlSafe( (IC)->Irp->MdlAddress, NormalPagePriority ))); \
  891. if (NULL == *(UB)) { \
  892. UdfRaiseStatus( IrpContext, STATUS_INSUFFICIENT_RESOURCES); \
  893. } \
  894. }
  895. #define UdfLockUserBuffer(IC,BL,OP) { \
  896. if ((IC)->Irp->MdlAddress == NULL) { \
  897. (VOID) UdfCreateUserMdl( (IC), (BL), TRUE, (OP) ); \
  898. } \
  899. }
  900. //
  901. // Udf*RawBufferSize and Udf*RawReadSize calculate how big a buffer must be
  902. // to do a direct read of a given sector aligned structure (UdfReadSectors)
  903. // and how much data the read must recover. Reads must write into whole-page
  904. // sized buffers and be in whole-sector units.
  905. //
  906. // Note that although all descriptors are constrained to fit in one logical
  907. // block, it is not always going to be neccesary to read the entire logical
  908. // block to get the descriptor. The underlying restriction is the physical
  909. // sector.
  910. //
  911. INLINE
  912. ULONG
  913. UdfRawBufferSize (
  914. IN PVCB Vcb,
  915. IN ULONG StructureSize
  916. )
  917. {
  918. return (ULONG)ROUND_TO_PAGES( SectorAlign( Vcb, StructureSize ));
  919. }
  920. INLINE
  921. ULONG
  922. UdfRawReadSize (
  923. IN PVCB Vcb,
  924. IN ULONG StructureSize
  925. )
  926. {
  927. return SectorAlign( Vcb, StructureSize );
  928. }
  929. INLINE
  930. ULONG
  931. UdfRawBufferSizeN (
  932. IN ULONG SectorSize,
  933. IN ULONG StructureSize
  934. )
  935. {
  936. return (ULONG)ROUND_TO_PAGES( SectorAlignN( SectorSize, StructureSize ));
  937. }
  938. INLINE
  939. ULONG
  940. UdfRawReadSizeN (
  941. IN ULONG SectorSize,
  942. IN ULONG StructureSize
  943. )
  944. {
  945. return SectorAlignN( SectorSize, StructureSize );
  946. }
  947. //
  948. // The following routines are used to read on-disk directory structures, implemented
  949. // in DirSup.c
  950. //
  951. VOID
  952. UdfInitializeDirContext (
  953. IN PIRP_CONTEXT IrpContext,
  954. IN PDIR_ENUM_CONTEXT DirContext
  955. );
  956. VOID
  957. UdfCleanupDirContext (
  958. IN PIRP_CONTEXT IrpContext,
  959. IN PDIR_ENUM_CONTEXT DirContext
  960. );
  961. BOOLEAN
  962. UdfLookupInitialDirEntry (
  963. IN PIRP_CONTEXT IrpContext,
  964. IN PFCB Fcb,
  965. IN PDIR_ENUM_CONTEXT DirContext,
  966. IN PLONGLONG InitialOffset OPTIONAL
  967. );
  968. BOOLEAN
  969. UdfLookupNextDirEntry (
  970. IN PIRP_CONTEXT IrpContext,
  971. IN PFCB Fcb,
  972. IN PDIR_ENUM_CONTEXT DirContext
  973. );
  974. VOID
  975. UdfUpdateDirNames (
  976. IN PIRP_CONTEXT IrpContext,
  977. IN PDIR_ENUM_CONTEXT DirContext,
  978. IN BOOLEAN IgnoreCase
  979. );
  980. BOOLEAN
  981. UdfFindDirEntry (
  982. IN PIRP_CONTEXT IrpContext,
  983. IN PFCB Fcb,
  984. IN PUNICODE_STRING Name,
  985. IN BOOLEAN IgnoreCase,
  986. IN BOOLEAN ShortName,
  987. IN PDIR_ENUM_CONTEXT DirContext
  988. );
  989. //
  990. // The following routines are used to manipulate the fscontext fields
  991. // of the file object, implemented in FilObSup.c
  992. //
  993. VOID
  994. UdfSetFileObject (
  995. IN PIRP_CONTEXT IrpContext,
  996. IN PFILE_OBJECT FileObject,
  997. IN TYPE_OF_OPEN TypeOfOpen,
  998. IN PFCB Fcb OPTIONAL,
  999. IN PCCB Ccb OPTIONAL
  1000. );
  1001. TYPE_OF_OPEN
  1002. UdfDecodeFileObject (
  1003. IN PFILE_OBJECT FileObject,
  1004. OUT PFCB *Fcb,
  1005. OUT PCCB *Ccb
  1006. );
  1007. TYPE_OF_OPEN
  1008. UdfFastDecodeFileObject (
  1009. IN PFILE_OBJECT FileObject,
  1010. OUT PFCB *Fcb
  1011. );
  1012. //
  1013. // FSCTL request support routines. Contained in FsCtrl.c
  1014. //
  1015. VOID
  1016. UdfStoreVolumeDescriptorIfPrevailing (
  1017. IN OUT PNSR_VD_GENERIC *StoredVD,
  1018. IN OUT PNSR_VD_GENERIC NewVD
  1019. );
  1020. //
  1021. // Name mangling routines. Implemented in Namesup.c
  1022. //
  1023. VOID
  1024. UdfDissectName (
  1025. IN PIRP_CONTEXT IrpContext,
  1026. IN OUT PUNICODE_STRING RemainingName,
  1027. OUT PUNICODE_STRING FinalName
  1028. );
  1029. BOOLEAN
  1030. UdfIs8dot3Name (
  1031. IN PIRP_CONTEXT IrpContext,
  1032. IN UNICODE_STRING FileName
  1033. );
  1034. BOOLEAN
  1035. UdfCandidateShortName (
  1036. IN PIRP_CONTEXT IrpContext,
  1037. IN PUNICODE_STRING Name
  1038. );
  1039. VOID
  1040. UdfGenerate8dot3Name (
  1041. IN PIRP_CONTEXT IrpContext,
  1042. IN PUNICODE_STRING FileName,
  1043. OUT PUNICODE_STRING ShortFileName
  1044. );
  1045. VOID
  1046. UdfConvertCS0DstringToUnicode (
  1047. IN PIRP_CONTEXT IrpContext,
  1048. IN PUCHAR Dstring,
  1049. IN UCHAR Length OPTIONAL,
  1050. IN UCHAR FieldLength OPTIONAL,
  1051. IN OUT PUNICODE_STRING Name
  1052. );
  1053. BOOLEAN
  1054. UdfCheckLegalCS0Dstring (
  1055. PIRP_CONTEXT IrpContext,
  1056. PUCHAR Dstring,
  1057. UCHAR Length OPTIONAL,
  1058. UCHAR FieldLength OPTIONAL,
  1059. BOOLEAN ReturnOnError
  1060. );
  1061. VOID
  1062. UdfRenderNameToLegalUnicode (
  1063. IN PIRP_CONTEXT IrpContext,
  1064. IN PUNICODE_STRING Name,
  1065. IN PUNICODE_STRING RenderedName
  1066. );
  1067. BOOLEAN
  1068. UdfIsNameInExpression (
  1069. IN PIRP_CONTEXT IrpContext,
  1070. IN PUNICODE_STRING CurrentName,
  1071. IN PUNICODE_STRING SearchExpression,
  1072. IN BOOLEAN Wild
  1073. );
  1074. FSRTL_COMPARISON_RESULT
  1075. UdfFullCompareNames (
  1076. IN PIRP_CONTEXT IrpContext,
  1077. IN PUNICODE_STRING NameA,
  1078. IN PUNICODE_STRING NameB
  1079. );
  1080. INLINE
  1081. VOID
  1082. UdfUpcaseName (
  1083. IN PIRP_CONTEXT IrpContext,
  1084. IN PUNICODE_STRING Name,
  1085. IN OUT PUNICODE_STRING UpcaseName
  1086. )
  1087. /*++
  1088. Routine Description:
  1089. This routine upcases a name with an assertion of success.
  1090. Arguments:
  1091. Name - an name to upcase
  1092. Length - a place to put the upcased name (can be the same as Name)
  1093. Return Value:
  1094. None.
  1095. --*/
  1096. {
  1097. NTSTATUS Status;
  1098. //
  1099. // Upcase the string using the correct upcase routine.
  1100. //
  1101. Status = RtlUpcaseUnicodeString( UpcaseName,
  1102. Name,
  1103. FALSE );
  1104. //
  1105. // This should never fail.
  1106. //
  1107. ASSERT( Status == STATUS_SUCCESS );
  1108. return;
  1109. }
  1110. INLINE
  1111. USHORT
  1112. UdfCS0DstringUnicodeSize (
  1113. PIRP_CONTEXT IrpContext,
  1114. PCHAR Dstring,
  1115. UCHAR Length
  1116. )
  1117. /*++
  1118. Routine Description:
  1119. This routine computes the number of bytes required for the UNICODE representation
  1120. of a CS0 Dstring (1/7.2.12)
  1121. Arguments:
  1122. Dstring - a dstring
  1123. Length - length of the dstring
  1124. Return Value:
  1125. ULONG number of bytes.
  1126. --*/
  1127. {
  1128. return (16 / *Dstring) * (Length - 1);
  1129. }
  1130. INLINE
  1131. BOOLEAN
  1132. UdfIsCharacterLegal (
  1133. IN WCHAR Character
  1134. )
  1135. /*++
  1136. Routine Description:
  1137. This routine checks that a given UNICODE character is legal.
  1138. Arguments:
  1139. Character - a character to check
  1140. Return Value:
  1141. BOOLEAN True if a legal character, False otherwise.
  1142. --*/
  1143. {
  1144. if (Character < 0xff && !FsRtlIsAnsiCharacterLegalHpfs( Character, FALSE )) {
  1145. return FALSE;
  1146. }
  1147. return TRUE;
  1148. }
  1149. INLINE
  1150. BOOLEAN
  1151. UdfCS0DstringIsLegalFileName(
  1152. IN PCHAR Dstring,
  1153. IN ULONG Length
  1154. )
  1155. /*++
  1156. Routine Description:
  1157. This routine inspects a CS0 dstring for illegal characters, and illegal
  1158. trailing characters.
  1159. NOTE: The assumption is made that the string is legal CS0.
  1160. Arguments:
  1161. Name - a name to check
  1162. Length - length of dstring (i.e. incl. leading char set specifier byte) in *bytes*
  1163. Return Value:
  1164. BOOLEAN True if legal characters are found, False otherwise.
  1165. --*/
  1166. {
  1167. ULONG Step;
  1168. WCHAR Char;
  1169. PCHAR Bound = Dstring + Length;
  1170. ASSERT( Length > 1);
  1171. //
  1172. // Determine how big a step we take in the string according to the
  1173. // "compression" applied.
  1174. //
  1175. if (*Dstring == 16) {
  1176. Step = sizeof( WCHAR );
  1177. } else {
  1178. Step = sizeof( CHAR );
  1179. }
  1180. ASSERT( Length >= (1 + Step));
  1181. //
  1182. // Advance past the compression marker and loop over the string.
  1183. //
  1184. for (Dstring++; Dstring < Bound; Dstring += Step) {
  1185. if ( sizeof(WCHAR) == Step) {
  1186. //
  1187. // Perform the endianess swapcopy to convert from UDF bigendian CS0 to our
  1188. // little endian wide characters.
  1189. //
  1190. SwapCopyUchar2( &Char, Dstring );
  1191. }
  1192. else {
  1193. Char = *Dstring;
  1194. }
  1195. if (!UdfIsCharacterLegal( Char )) {
  1196. DebugTrace(( 0, Dbg, "UdfCS0DstringIsLegalFileName, Char %04x @ %08x\n", (WCHAR) Char, Dstring ));
  1197. return FALSE;
  1198. }
  1199. }
  1200. //
  1201. // Now check for illegal trailing characters (' ' or '.') We know that Char
  1202. // will be the last character in the string.
  1203. //
  1204. if ((PERIOD == Char) || (SPACE == Char)) {
  1205. DebugTrace(( 0, Dbg, "UdfCS0DstringIsLegalFileName, has trailing space or period\n"));
  1206. return FALSE;
  1207. }
  1208. return TRUE;
  1209. }
  1210. //
  1211. // Filesystem control operations. Implemented in Fsctrl.c
  1212. //
  1213. NTSTATUS
  1214. UdfLockVolumeInternal (
  1215. IN PIRP_CONTEXT IrpContext,
  1216. IN PVCB Vcb,
  1217. IN PFILE_OBJECT FileObject OPTIONAL
  1218. );
  1219. NTSTATUS
  1220. UdfUnlockVolumeInternal (
  1221. IN PIRP_CONTEXT IrpContext,
  1222. IN PVCB Vcb,
  1223. IN PFILE_OBJECT FileObject OPTIONAL
  1224. );
  1225. //
  1226. // Routines to handle the prefix trees attached to directories, used to quickly travel common
  1227. // bits of the hierarchy. Implemented in PrefxSup.c
  1228. //
  1229. PLCB
  1230. UdfFindPrefix (
  1231. IN PIRP_CONTEXT IrpContext,
  1232. IN OUT PFCB *CurrentFcb,
  1233. IN OUT PUNICODE_STRING RemainingName,
  1234. IN BOOLEAN IgnoreCase
  1235. );
  1236. VOID
  1237. UdfInitializeLcbFromDirContext (
  1238. IN PIRP_CONTEXT IrpContext,
  1239. IN PLCB Lcb,
  1240. IN PDIR_ENUM_CONTEXT DirContext
  1241. );
  1242. PLCB
  1243. UdfInsertPrefix (
  1244. IN PIRP_CONTEXT IrpContext,
  1245. IN PFCB Fcb,
  1246. IN PUNICODE_STRING Name,
  1247. IN BOOLEAN ShortNameMatch,
  1248. IN BOOLEAN IgnoreCase,
  1249. IN PFCB ParentFcb
  1250. );
  1251. VOID
  1252. UdfRemovePrefix (
  1253. IN PIRP_CONTEXT IrpContext,
  1254. IN PLCB Lcb
  1255. );
  1256. //
  1257. // Synchronization routines. Implemented in Resrcsup.c
  1258. //
  1259. // The following routines/macros are used to synchronize the in-memory structures.
  1260. //
  1261. // Routine/Macro Synchronizes Subsequent
  1262. //
  1263. // UdfAcquireUdfData Volume Mounts/Dismounts,Vcb Queue UdfReleaseUdfData
  1264. // UdfAcquireVcbExclusive Vcb for open/close UdfReleaseVcb
  1265. // UdfAcquireVcbShared Vcb for open/close UdfReleaseVcb
  1266. // UdfAcquireAllFiles Locks out operations to all files UdfReleaseAllFiles
  1267. // UdfAcquireFileExclusive Locks out file operations UdfReleaseFile
  1268. // UdfAcquireFileShared Files for file operations UdfReleaseFile
  1269. // UdfAcquireFcbExclusive Fcb for open/close UdfReleaseFcb
  1270. // UdfAcquireFcbShared Fcb for open/close UdfReleaseFcb
  1271. // UdfLockUdfData Fields in UdfData UdfUnlockUdfData
  1272. // UdfLockVcb Vcb fields, FcbReference, FcbTable UdfUnlockVcb
  1273. // UdfLockFcb Fcb fields, prefix table, Mcb UdfUnlockFcb
  1274. //
  1275. typedef enum _TYPE_OF_ACQUIRE {
  1276. AcquireExclusive,
  1277. AcquireShared,
  1278. AcquireSharedStarveExclusive
  1279. } TYPE_OF_ACQUIRE, *PTYPE_OF_ACQUIRE;
  1280. BOOLEAN
  1281. UdfAcquireResource (
  1282. IN PIRP_CONTEXT IrpContext,
  1283. IN PERESOURCE Resource,
  1284. IN BOOLEAN IgnoreWait,
  1285. IN TYPE_OF_ACQUIRE Type
  1286. );
  1287. //
  1288. // BOOLEAN
  1289. // UdfAcquireUdfData (
  1290. // IN PIRP_CONTEXT IrpContext
  1291. // );
  1292. //
  1293. // VOID
  1294. // UdfReleaseUdfData (
  1295. // IN PIRP_CONTEXT IrpContext
  1296. // );
  1297. //
  1298. // BOOLEAN
  1299. // UdfAcquireVcbExclusive (
  1300. // IN PIRP_CONTEXT IrpContext,
  1301. // IN PVCB Vcb,
  1302. // IN BOOLEAN IgnoreWait
  1303. // );
  1304. //
  1305. // BOOLEAN
  1306. // UdfAcquireVcbShared (
  1307. // IN PIRP_CONTEXT IrpContext,
  1308. // IN PVCB Vcb,
  1309. // IN BOOLEAN IgnoreWait
  1310. // );
  1311. //
  1312. // VOID
  1313. // UdfReleaseVcb (
  1314. // IN PIRP_CONTEXT IrpContext,
  1315. // IN PVCB Vcb
  1316. // );
  1317. //
  1318. // VOID
  1319. // UdfAcquireAllFiles (
  1320. // IN PIRP_CONTEXT,
  1321. // IN PVCB Vcb
  1322. // );
  1323. //
  1324. // VOID
  1325. // UdfReleaseAllFiles (
  1326. // IN PIRP_CONTEXT,
  1327. // IN PVCB Vcb
  1328. // );
  1329. //
  1330. // VOID
  1331. // UdfAcquireFileExclusive (
  1332. // IN PIRP_CONTEXT IrpContext,
  1333. // IN PFCB Fcb,
  1334. // );
  1335. //
  1336. // VOID
  1337. // UdfAcquireFileShared (
  1338. // IN PIRP_CONTEXT IrpContext,
  1339. // IN PFCB Fcb
  1340. // );
  1341. //
  1342. // VOID
  1343. // UdfReleaseFile (
  1344. // IN PIRP_CONTEXT IrpContext,
  1345. // IN PFCB Fcb
  1346. // );
  1347. //
  1348. // BOOLEAN
  1349. // UdfAcquireFcbExclusive (
  1350. // IN PIRP_CONTEXT IrpContext,
  1351. // IN PFCB Fcb,
  1352. // IN BOOLEAN IgnoreWait
  1353. // );
  1354. //
  1355. // BOOLEAN
  1356. // UdfAcquireFcbShared (
  1357. // IN PIRP_CONTEXT IrpContext,
  1358. // IN PFCB Fcb,
  1359. // IN BOOLEAN IgnoreWait
  1360. // );
  1361. //
  1362. // BOOLEAN
  1363. // UdfReleaseFcb (
  1364. // IN PIRP_CONTEXT IrpContext,
  1365. // IN PFCB Fcb
  1366. // );
  1367. //
  1368. // VOID
  1369. // UdfLockUdfData (
  1370. // );
  1371. //
  1372. // VOID
  1373. // UdfUnlockUdfData (
  1374. // );
  1375. //
  1376. // VOID
  1377. // UdfLockVcb (
  1378. // IN PIRP_CONTEXT IrpContext
  1379. // );
  1380. //
  1381. // VOID
  1382. // UdfUnlockVcb (
  1383. // IN PIRP_CONTEXT IrpContext
  1384. // );
  1385. //
  1386. // VOID
  1387. // UdfLockFcb (
  1388. // IN PIRP_CONTEXT IrpContext,
  1389. // IN PFCB Fcb
  1390. // );
  1391. //
  1392. // VOID
  1393. // UdfUnlockFcb (
  1394. // IN PIRP_CONTEXT IrpContext,
  1395. // IN PFCB Fcb
  1396. // );
  1397. //
  1398. #define UdfAcquireUdfData(IC) \
  1399. ExAcquireResourceExclusiveLite( &UdfData.DataResource, TRUE )
  1400. #define UdfReleaseUdfData(IC) \
  1401. ExReleaseResourceLite( &UdfData.DataResource )
  1402. #define UdfAcquireVcbExclusive(IC,V,I) \
  1403. UdfAcquireResource( (IC), &(V)->VcbResource, (I), AcquireExclusive )
  1404. #define UdfAcquireVcbShared(IC,V,I) \
  1405. UdfAcquireResource( (IC), &(V)->VcbResource, (I), AcquireShared )
  1406. #define UdfReleaseVcb(IC,V) \
  1407. ExReleaseResourceLite( &(V)->VcbResource )
  1408. #define UdfAcquireAllFiles(IC,V) \
  1409. UdfAcquireResource( (IC), &(V)->FileResource, FALSE, AcquireExclusive )
  1410. #define UdfReleaseAllFiles(IC,V) \
  1411. ExReleaseResourceLite( &(V)->FileResource )
  1412. #define UdfAcquireFileExclusive(IC,F) \
  1413. UdfAcquireResource( (IC), (F)->Resource, FALSE, AcquireExclusive )
  1414. #define UdfAcquireFileShared(IC,F) \
  1415. UdfAcquireResource( (IC), (F)->Resource, FALSE, AcquireShared )
  1416. #define UdfAcquireFileSharedStarveExclusive(IC,F) \
  1417. UdfAcquireResource( (IC), (F)->Resource, FALSE, AcquireSharedStarveExclusive )
  1418. #define UdfReleaseFile(IC,F) \
  1419. ExReleaseResourceLite( (F)->Resource )
  1420. #define UdfAcquireVmcbForCcMap(IC,V) \
  1421. UdfAcquireResource( (IC), &(V)->VmcbMappingResource, FALSE, AcquireShared)
  1422. #define UdfAcquireVmcbForCcPurge(IC,V) \
  1423. UdfAcquireResource( (IC), &(V)->VmcbMappingResource, FALSE, AcquireExclusive)
  1424. #define UdfReleaseVmcb( IC, V) \
  1425. ExReleaseResourceLite( &(V)->VmcbMappingResource)
  1426. #define UdfAcquireFcbExclusive(IC,F,I) \
  1427. UdfAcquireResource( (IC), &(F)->FcbNonpaged->FcbResource, (I), AcquireExclusive )
  1428. #define UdfAcquireFcbShared(IC,F,I) \
  1429. UdfAcquireResource( (IC), &(F)->FcbNonpaged->FcbResource, (I), AcquireShared )
  1430. #define UdfReleaseFcb(IC,F) \
  1431. ExReleaseResourceLite( &(F)->FcbNonpaged->FcbResource )
  1432. #define UdfLockUdfData() \
  1433. ExAcquireFastMutex( &UdfData.UdfDataMutex ); \
  1434. UdfData.UdfDataLockThread = PsGetCurrentThread()
  1435. #define UdfUnlockUdfData() \
  1436. UdfData.UdfDataLockThread = NULL; \
  1437. ExReleaseFastMutex( &UdfData.UdfDataMutex )
  1438. #define UdfLockVcb(IC,V) \
  1439. ASSERT(KeAreApcsDisabled()); \
  1440. ExAcquireFastMutexUnsafe( &(V)->VcbMutex ); \
  1441. (V)->VcbLockThread = PsGetCurrentThread()
  1442. #define UdfUnlockVcb(IC,V) \
  1443. (V)->VcbLockThread = NULL; \
  1444. ExReleaseFastMutexUnsafe( &(V)->VcbMutex )
  1445. #define UdfLockFcb(IC,F) { \
  1446. PVOID _CurrentThread = PsGetCurrentThread(); \
  1447. if (_CurrentThread != (F)->FcbLockThread) { \
  1448. ASSERT(KeAreApcsDisabled()); \
  1449. ExAcquireFastMutexUnsafe( &(F)->FcbNonpaged->FcbMutex ); \
  1450. ASSERT( (F)->FcbLockCount == 0 ); \
  1451. (F)->FcbLockThread = _CurrentThread; \
  1452. } \
  1453. (F)->FcbLockCount += 1; \
  1454. }
  1455. #define UdfUnlockFcb(IC,F) { \
  1456. ASSERT( PsGetCurrentThread() == (F)->FcbLockThread); \
  1457. (F)->FcbLockCount -= 1; \
  1458. if ((F)->FcbLockCount == 0) { \
  1459. (F)->FcbLockThread = NULL; \
  1460. ExReleaseFastMutexUnsafe( &(F)->FcbNonpaged->FcbMutex ); \
  1461. } \
  1462. }
  1463. BOOLEAN
  1464. UdfNoopAcquire (
  1465. IN PVOID Fcb,
  1466. IN BOOLEAN Wait
  1467. );
  1468. VOID
  1469. UdfNoopRelease (
  1470. IN PVOID Fcb
  1471. );
  1472. BOOLEAN
  1473. UdfAcquireForCache (
  1474. IN PFCB Fcb,
  1475. IN BOOLEAN Wait
  1476. );
  1477. VOID
  1478. UdfReleaseFromCache (
  1479. IN PFCB Fcb
  1480. );
  1481. VOID
  1482. UdfAcquireForCreateSection (
  1483. IN PFILE_OBJECT FileObject
  1484. );
  1485. VOID
  1486. UdfReleaseForCreateSection (
  1487. IN PFILE_OBJECT FileObject
  1488. );
  1489. //
  1490. // Structure support routines, implemented in StrucSup.c
  1491. //
  1492. // These routines perform in-memory structure manipulations. They do *not* operate
  1493. // on disk structures.
  1494. //
  1495. //
  1496. // Encapsulate manipulation of the Vcb condition for tracing purposes.
  1497. //
  1498. #ifndef UDF_SANITY
  1499. #define UdfSetVcbCondition( V, C) (V)->VcbCondition = (C)
  1500. #define UdfSetMediaChangeCount( V, C) (V)->MediaChangeCount = (C)
  1501. #else
  1502. #define UdfSetVcbCondition( V, C) { \
  1503. DebugTrace(( 0, UDFS_DEBUG_LEVEL_VERFYSUP, "VcbCondition %p transitioning %d -> %d (%s : %d)\n", \
  1504. (V), (V)->VcbCondition, (C), __FILE__, __LINE__)); \
  1505. (V)->VcbCondition = (C); \
  1506. }
  1507. #define UdfSetMediaChangeCount( V, C) { \
  1508. DebugTrace(( 0, UDFS_DEBUG_LEVEL_VERFYSUP, "Vcb MCT %p transitioning %d -> %d (%s : %d)\n", \
  1509. (V), (V)->MediaChangeCount, (C), __FILE__, __LINE__)); \
  1510. (V)->MediaChangeCount = (C); \
  1511. }
  1512. #endif
  1513. BOOLEAN
  1514. UdfInitializeVcb (
  1515. IN PIRP_CONTEXT IrpContext,
  1516. IN OUT PVCB Vcb,
  1517. IN PDEVICE_OBJECT TargetDeviceObject,
  1518. IN PVPB Vpb,
  1519. IN PDISK_GEOMETRY DiskGeometry,
  1520. IN ULONG MediaChangeCount
  1521. );
  1522. VOID
  1523. UdfUpdateVcbPhase0 (
  1524. IN PIRP_CONTEXT IrpContext,
  1525. IN OUT PVCB Vcb
  1526. );
  1527. VOID
  1528. UdfUpdateVcbPhase1 (
  1529. IN PIRP_CONTEXT IrpContext,
  1530. IN OUT PVCB Vcb,
  1531. IN PNSR_FSD Fsd
  1532. );
  1533. VOID
  1534. UdfDeleteVcb (
  1535. IN PIRP_CONTEXT IrpContext,
  1536. IN OUT PVCB Vcb
  1537. );
  1538. PIRP_CONTEXT
  1539. UdfCreateIrpContext (
  1540. IN PIRP Irp,
  1541. IN BOOLEAN Wait
  1542. );
  1543. VOID
  1544. UdfCleanupIrpContext (
  1545. IN PIRP_CONTEXT IrpContext,
  1546. IN BOOLEAN Post
  1547. );
  1548. VOID
  1549. UdfInitializeStackIrpContext (
  1550. OUT PIRP_CONTEXT IrpContext,
  1551. IN PIRP_CONTEXT_LITE IrpContextLite
  1552. );
  1553. //
  1554. // PIRP_CONTEXT_LITE
  1555. // UdfCreateIrpContextLite (
  1556. // IN PIRP_CONTEXT IrpContext
  1557. // );
  1558. //
  1559. // VOID
  1560. // UdfFreeIrpContextLite (
  1561. // IN PIRP_CONTEXT_LITE IrpContextLite
  1562. // );
  1563. //
  1564. #define UdfCreateIrpContextLite(IC) \
  1565. ExAllocatePoolWithTag( UdfNonPagedPool, sizeof( IRP_CONTEXT_LITE ), TAG_IRP_CONTEXT_LITE )
  1566. #define UdfFreeIrpContextLite(ICL) \
  1567. ExFreePool( ICL )
  1568. //
  1569. // PUDF_IO_CONTEXT
  1570. // UdfAllocateIoContext (
  1571. // );
  1572. //
  1573. // VOID
  1574. // UdfFreeIoContext (
  1575. // PUDF_IO_CONTEXT IoContext
  1576. // );
  1577. //
  1578. #define UdfAllocateIoContext() \
  1579. FsRtlAllocatePoolWithTag( UdfNonPagedPool, \
  1580. sizeof( UDF_IO_CONTEXT ), \
  1581. TAG_IO_CONTEXT )
  1582. #define UdfFreeIoContext(IO) ExFreePool( IO )
  1583. //
  1584. // VOID
  1585. // UdfIncrementCleanupCounts (
  1586. // IN PIRP_CONTEXT IrpContext,
  1587. // IN PFCB Fcb
  1588. // );
  1589. //
  1590. // VOID
  1591. // UdfDecrementCleanupCounts (
  1592. // IN PIRP_CONTEXT IrpContext,
  1593. // IN PFCB Fcb
  1594. // );
  1595. //
  1596. // VOID
  1597. // UdfIncrementReferenceCounts (
  1598. // IN PIRP_CONTEXT IrpContext,
  1599. // IN PFCB Fcb,
  1600. // IN ULONG ReferenceCount
  1601. // IN ULONG UserReferenceCount
  1602. // );
  1603. //
  1604. // VOID
  1605. // UdfDecrementReferenceCounts (
  1606. // IN PIRP_CONTEXT IrpContext,
  1607. // IN PFCB Fcb,
  1608. // IN ULONG ReferenceCount
  1609. // IN ULONG UserReferenceCount
  1610. // );
  1611. //
  1612. // VOID
  1613. // UdfIncrementFcbReference (
  1614. // IN PIRP_CONTEXT IrpContext,
  1615. // IN PFCB Fcb
  1616. // );
  1617. //
  1618. // VOID
  1619. // UdfDecrementFcbReference (
  1620. // IN PIRP_CONTEXT IrpContext,
  1621. // IN PFCB Fcb
  1622. // );
  1623. //
  1624. #define UdfIncrementCleanupCounts(IC,F) { \
  1625. ASSERT_LOCKED_VCB( (F)->Vcb ); \
  1626. (F)->FcbCleanup += 1; \
  1627. (F)->Vcb->VcbCleanup += 1; \
  1628. }
  1629. #define UdfDecrementCleanupCounts(IC,F) { \
  1630. ASSERT_LOCKED_VCB( (F)->Vcb ); \
  1631. (F)->FcbCleanup -= 1; \
  1632. (F)->Vcb->VcbCleanup -= 1; \
  1633. }
  1634. #define UdfIncrementReferenceCounts(IC,F,C,UC) { \
  1635. ASSERT_LOCKED_VCB( (F)->Vcb ); \
  1636. (F)->FcbReference += (C); \
  1637. (F)->FcbUserReference += (UC); \
  1638. (F)->Vcb->VcbReference += (C); \
  1639. (F)->Vcb->VcbUserReference += (UC); \
  1640. }
  1641. #define UdfDecrementReferenceCounts(IC,F,C,UC) { \
  1642. ASSERT_LOCKED_VCB( (F)->Vcb ); \
  1643. (F)->FcbReference -= (C); \
  1644. (F)->FcbUserReference -= (UC); \
  1645. (F)->Vcb->VcbReference -= (C); \
  1646. (F)->Vcb->VcbUserReference -= (UC); \
  1647. }
  1648. VOID
  1649. UdfTeardownStructures (
  1650. IN PIRP_CONTEXT IrpContext,
  1651. IN PFCB StartingFcb,
  1652. IN BOOLEAN Recursive,
  1653. OUT PBOOLEAN RemovedStartingFcb
  1654. );
  1655. PFCB
  1656. UdfLookupFcbTable (
  1657. IN PIRP_CONTEXT IrpContext,
  1658. IN PVCB Vcb,
  1659. IN FILE_ID FileId
  1660. );
  1661. PFCB
  1662. UdfGetNextFcb (
  1663. IN PIRP_CONTEXT IrpContext,
  1664. IN PVCB Vcb,
  1665. IN PVOID *RestartKey
  1666. );
  1667. PFCB
  1668. UdfCreateFcb (
  1669. IN PIRP_CONTEXT IrpContext,
  1670. IN FILE_ID FileId,
  1671. IN NODE_TYPE_CODE NodeTypeCode,
  1672. OUT PBOOLEAN FcbExisted OPTIONAL
  1673. );
  1674. VOID
  1675. UdfDeleteFcb (
  1676. IN PIRP_CONTEXT IrpContext,
  1677. IN PFCB Fcb
  1678. );
  1679. VOID
  1680. UdfInitializeFcbFromIcbContext (
  1681. IN PIRP_CONTEXT IrpContext,
  1682. IN PFCB Fcb,
  1683. IN PICB_SEARCH_CONTEXT IcbContext,
  1684. IN PFCB ParentFcb OPTIONAL
  1685. );
  1686. PCCB
  1687. UdfCreateCcb (
  1688. IN PIRP_CONTEXT IrpContext,
  1689. IN PFCB Fcb,
  1690. IN PLCB Lcb OPTIONAL,
  1691. IN ULONG Flags
  1692. );
  1693. VOID
  1694. UdfDeleteCcb (
  1695. IN PIRP_CONTEXT IrpContext,
  1696. IN PCCB Ccb
  1697. );
  1698. ULONG
  1699. UdfFindInParseTable (
  1700. IN PPARSE_KEYVALUE ParseTable,
  1701. IN PCHAR Id,
  1702. IN ULONG MaxIdLen
  1703. );
  1704. BOOLEAN
  1705. UdfVerifyDescriptor (
  1706. IN PIRP_CONTEXT IrpContext,
  1707. IN PDESTAG Descriptor,
  1708. IN USHORT Tag,
  1709. IN ULONG Size,
  1710. IN ULONG Lbn,
  1711. IN BOOLEAN ReturnError
  1712. );
  1713. VOID
  1714. UdfInitializeIcbContextFromFcb (
  1715. IN PIRP_CONTEXT IrpContext,
  1716. IN PICB_SEARCH_CONTEXT IcbContext,
  1717. IN PFCB Fcb
  1718. );
  1719. VOID
  1720. UdfInitializeIcbContext (
  1721. IN PIRP_CONTEXT IrpContext,
  1722. IN PICB_SEARCH_CONTEXT IcbContext,
  1723. IN PVCB Vcb,
  1724. IN USHORT IcbType,
  1725. IN USHORT Partition,
  1726. IN ULONG Lbn,
  1727. IN ULONG Length
  1728. );
  1729. INLINE
  1730. VOID
  1731. UdfFastInitializeIcbContext (
  1732. IN PIRP_CONTEXT IrpContext,
  1733. IN PICB_SEARCH_CONTEXT IcbContext
  1734. )
  1735. {
  1736. RtlZeroMemory( IcbContext, sizeof( ICB_SEARCH_CONTEXT ));
  1737. }
  1738. VOID
  1739. UdfLookupActiveIcb (
  1740. IN PIRP_CONTEXT IrpContext,
  1741. IN PICB_SEARCH_CONTEXT IcbContext,
  1742. IN ULONG IcbExtentLength
  1743. );
  1744. VOID
  1745. UdfCleanupIcbContext (
  1746. IN PIRP_CONTEXT IrpContext,
  1747. IN PICB_SEARCH_CONTEXT IcbContext
  1748. );
  1749. VOID
  1750. UdfInitializeAllocations (
  1751. IN PIRP_CONTEXT IrpContext,
  1752. IN PFCB Fcb,
  1753. IN PICB_SEARCH_CONTEXT IcbContext,
  1754. IN BOOLEAN AllowOneGigWorkaround
  1755. );
  1756. VOID
  1757. UdfUpdateTimestampsFromIcbContext (
  1758. IN PIRP_CONTEXT IrpContext,
  1759. IN PICB_SEARCH_CONTEXT IcbContext,
  1760. IN PTIMESTAMP_BUNDLE Timestamps
  1761. );
  1762. BOOLEAN
  1763. UdfCreateFileLock (
  1764. IN PIRP_CONTEXT IrpContext OPTIONAL,
  1765. IN PFCB Fcb,
  1766. IN BOOLEAN RaiseOnError
  1767. );
  1768. //
  1769. // The following macro converts from UDF time to NT time.
  1770. //
  1771. INLINE
  1772. VOID
  1773. UdfConvertUdfTimeToNtTime (
  1774. IN PIRP_CONTEXT IrpContext,
  1775. IN PTIMESTAMP UdfTime,
  1776. OUT PLARGE_INTEGER NtTime
  1777. )
  1778. {
  1779. TIME_FIELDS TimeField;
  1780. TimeField.Year = UdfTime->Year;
  1781. TimeField.Month = UdfTime->Month;
  1782. TimeField.Day = UdfTime->Day;
  1783. TimeField.Hour = UdfTime->Hour;
  1784. TimeField.Minute = UdfTime->Minute;
  1785. TimeField.Second = UdfTime->Second;
  1786. //
  1787. // This is where it gets hairy. For some unholy reason, ISO 13346 timestamps
  1788. // carve the right of the decimal point up into three fields of precision
  1789. // 10-2, 10-4, and 10-6, each ranging from 0-99. Lawdy.
  1790. //
  1791. // To make it easier, since they cannot cause a wrap into the next second,
  1792. // just save it all up and add it in after the conversion.
  1793. //
  1794. TimeField.Milliseconds = 0;
  1795. if (UdfTime->Type <= 1 &&
  1796. ((UdfTime->Zone >= TIMESTAMP_Z_MIN && UdfTime->Zone <= TIMESTAMP_Z_MAX) ||
  1797. UdfTime->Zone == TIMESTAMP_Z_NONE) &&
  1798. RtlTimeFieldsToTime( &TimeField, NtTime )) {
  1799. //
  1800. // Now fold in the remaining sub-second "precision". Read as coversions
  1801. // through the 10-3 units, then into our 10-7 base. (centi->milli->micro,
  1802. // etc).
  1803. //
  1804. NtTime->QuadPart += ((UdfTime->CentiSecond * (10 * 1000)) +
  1805. (UdfTime->Usec100 * 100) +
  1806. UdfTime->Usec) * 10;
  1807. //
  1808. // Perform TZ normalization if this is a local time with
  1809. // specified timezone.
  1810. //
  1811. if (UdfTime->Type == 1 && UdfTime->Zone != TIMESTAMP_Z_NONE) {
  1812. NtTime->QuadPart += Int32x32To64( -UdfTime->Zone, (60 * 10 * 1000 * 1000) );
  1813. }
  1814. } else {
  1815. //
  1816. // Epoch. Malformed timestamp.
  1817. //
  1818. NtTime->QuadPart = 0;
  1819. }
  1820. }
  1821. //
  1822. // An equivalence test for Entity IDs.
  1823. //
  1824. INLINE
  1825. BOOLEAN
  1826. UdfEqualEntityId (
  1827. IN PREGID RegID,
  1828. IN PSTRING Id,
  1829. IN OPTIONAL PSTRING Suffix
  1830. )
  1831. {
  1832. return (UdfEqualCountedString( Id, RegID->Identifier ) &&
  1833. #ifndef UDF_SUPPORT_NONSTANDARD_ENTITY_STRINGTERM
  1834. //
  1835. // Allow disabling of the check that the identifier
  1836. // seems to be padded with zero.
  1837. //
  1838. // Reason: a couple samples that are otherwise useful
  1839. // padded some identifiers with junk.
  1840. //
  1841. ((Id->Length == sizeof(RegID->Identifier) ||
  1842. RegID->Identifier[Id->Length] == '\0') ||
  1843. !DebugTrace(( 0, Dbg,
  1844. "UdfEqualEntityId, RegID seems to be terminated with junk!\n" ))) &&
  1845. #endif
  1846. ((Suffix == NULL) || UdfEqualCountedString( Suffix, RegID->Suffix )));
  1847. }
  1848. BOOLEAN
  1849. UdfDomainIdentifierContained (
  1850. IN PREGID RegID,
  1851. IN PSTRING Domain,
  1852. IN USHORT RevisionMin,
  1853. IN USHORT RevisionMax
  1854. );
  1855. //
  1856. // In like fashion, we define containment for a UDF Identifier RegID.
  1857. //
  1858. INLINE
  1859. BOOLEAN
  1860. UdfUdfIdentifierContained (
  1861. IN PREGID RegID,
  1862. IN PSTRING Type,
  1863. IN USHORT RevisionMin,
  1864. IN USHORT RevisionMax,
  1865. IN UCHAR OSClass,
  1866. IN UCHAR OSIdentifier
  1867. )
  1868. {
  1869. PUDF_SUFFIX_UDF UdfSuffix = (PUDF_SUFFIX_UDF) RegID->Suffix;
  1870. return ((UdfSuffix->UdfRevision <= RevisionMax && UdfSuffix->UdfRevision >= RevisionMin) &&
  1871. (OSClass == OSCLASS_INVALID || UdfSuffix->OSClass == OSClass) &&
  1872. (OSIdentifier == OSIDENTIFIER_INVALID || UdfSuffix->OSIdentifier == OSIdentifier) &&
  1873. UdfEqualEntityId( RegID, Type, NULL ));
  1874. }
  1875. //
  1876. // Verification support routines. Contained in verfysup.c
  1877. //
  1878. BOOLEAN
  1879. UdfCheckForDismount (
  1880. IN PIRP_CONTEXT IrpContext,
  1881. IN PVCB Vcb,
  1882. IN BOOLEAN Force
  1883. );
  1884. BOOLEAN
  1885. UdfDismountVcb (
  1886. IN PIRP_CONTEXT IrpContext,
  1887. IN PVCB Vcb
  1888. );
  1889. VOID
  1890. UdfVerifyVcb (
  1891. IN PIRP_CONTEXT IrpContext,
  1892. IN PVCB Vcb
  1893. );
  1894. BOOLEAN
  1895. UdfVerifyFcbOperation (
  1896. IN PIRP_CONTEXT IrpContext OPTIONAL,
  1897. IN PFCB Fcb
  1898. );
  1899. //
  1900. // BOOLEAN
  1901. // UdfIsRawDevice (
  1902. // IN PIRP_CONTEXT IrpContext,
  1903. // IN NTSTATUS Status
  1904. // );
  1905. //
  1906. #define UdfIsRawDevice(IC,S) ( \
  1907. ((S) == STATUS_DEVICE_NOT_READY) || \
  1908. ((S) == STATUS_NO_MEDIA_IN_DEVICE) \
  1909. )
  1910. //
  1911. // Volume Mapped Control Blocks routines, implemented in VmcbSup.c
  1912. //
  1913. VOID
  1914. UdfInitializeVmcb (
  1915. IN PVMCB Vmcb,
  1916. IN POOL_TYPE PoolType,
  1917. IN ULONG MaximumLbn,
  1918. IN ULONG LbSize
  1919. );
  1920. VOID
  1921. UdfUninitializeVmcb (
  1922. IN PVMCB Vmcb
  1923. );
  1924. VOID
  1925. UdfResetVmcb (
  1926. IN PVMCB Vmcb
  1927. );
  1928. VOID
  1929. UdfSetMaximumLbnVmcb (
  1930. IN PVMCB Vmcb,
  1931. IN ULONG MaximumLbn
  1932. );
  1933. BOOLEAN
  1934. UdfVmcbVbnToLbn (
  1935. IN PVMCB Vmcb,
  1936. IN VBN Vbn,
  1937. OUT PLBN Lbn,
  1938. OUT PULONG SectorCount OPTIONAL
  1939. );
  1940. BOOLEAN
  1941. UdfVmcbLbnToVbn (
  1942. IN PVMCB Vmcb,
  1943. IN LBN Lbn,
  1944. OUT PVBN Vbn,
  1945. OUT PULONG SectorCount OPTIONAL
  1946. );
  1947. BOOLEAN
  1948. UdfAddVmcbMapping (
  1949. IN PIRP_CONTEXT IrpContext,
  1950. IN PVMCB Vmcb,
  1951. IN LBN Lbn,
  1952. IN ULONG SectorCount,
  1953. IN BOOLEAN ExactEnd,
  1954. OUT PVBN Vbn,
  1955. OUT PULONG AlignedSectorCount
  1956. );
  1957. VOID
  1958. UdfRemoveVmcbMapping (
  1959. IN PVMCB Vmcb,
  1960. IN LBN Lbn,
  1961. IN ULONG SectorCount
  1962. );
  1963. //
  1964. // Routines to verify the correspondance of the underlying media, implemented in
  1965. // verfysup.c
  1966. //
  1967. NTSTATUS
  1968. UdfPerformVerify (
  1969. IN PIRP_CONTEXT IrpContext,
  1970. IN PIRP Irp,
  1971. IN PDEVICE_OBJECT DeviceToVerify
  1972. );
  1973. INLINE
  1974. BOOLEAN
  1975. UdfOperationIsDasdOpen(
  1976. IN PIRP_CONTEXT IrpContext
  1977. )
  1978. //
  1979. // Return TRUE if this is a DASD open request.
  1980. //
  1981. {
  1982. PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( IrpContext->Irp);
  1983. return ((IrpContext->MajorFunction == IRP_MJ_CREATE) &&
  1984. (IrpSp->FileObject->FileName.Length == 0) &&
  1985. (IrpSp->FileObject->RelatedFileObject == NULL));
  1986. }
  1987. //
  1988. // Some macros for hiding/tracing the device object verify flag.
  1989. //
  1990. #ifndef UDF_SANITY
  1991. #define UdfMarkRealDevForVerify( DO) SetFlag( (DO)->Flags, DO_VERIFY_VOLUME)
  1992. #define UdfMarkRealDevVerifyOk( DO) ClearFlag( (DO)->Flags, DO_VERIFY_VOLUME)
  1993. #else
  1994. #define UdfMarkRealDevForVerify( DO) { \
  1995. DebugTrace((0,UDFS_DEBUG_LEVEL_VERFYSUP,"Mark for verify %p (at %s %d)\n", \
  1996. (DO), __FILE__, __LINE__)); \
  1997. SetFlag( (DO)->Flags, DO_VERIFY_VOLUME); \
  1998. }
  1999. #define UdfMarkRealDevVerifyOk( DO) { \
  2000. DebugTrace((0,UDFS_DEBUG_LEVEL_VERFYSUP,"Clear verify %p (at %s %d)\n", \
  2001. (DO), __FILE__, __LINE__)); \
  2002. ClearFlag( (DO)->Flags, DO_VERIFY_VOLUME); \
  2003. }
  2004. #endif
  2005. #define UdfRealDevNeedsVerify( DO) BooleanFlagOn( (DO)->Flags, DO_VERIFY_VOLUME)
  2006. //
  2007. // Work queue routines for posting and retrieving an Irp, implemented in
  2008. // workque.c
  2009. //
  2010. NTSTATUS
  2011. UdfFsdPostRequest(
  2012. IN PIRP_CONTEXT IrpContext,
  2013. IN PIRP Irp
  2014. );
  2015. VOID
  2016. UdfPrePostIrp (
  2017. IN PIRP_CONTEXT IrpContext,
  2018. IN PIRP Irp
  2019. );
  2020. VOID
  2021. UdfOplockComplete (
  2022. IN PIRP_CONTEXT IrpContext,
  2023. IN PIRP Irp
  2024. );
  2025. //
  2026. // Charspecs are small containers that specify a CS<N> type and a text
  2027. // string specifying a version, etc. This is a convenient way of bottling
  2028. // up equivalence checks of a charspec.
  2029. //
  2030. INLINE
  2031. BOOLEAN
  2032. UdfEqualCharspec (
  2033. IN PCHARSPEC Charspec,
  2034. IN PSTRING Identifier,
  2035. IN UCHAR Type
  2036. )
  2037. {
  2038. return ((Charspec->Type == Type) && UdfEqualCountedString( Identifier, Charspec->Info));
  2039. }
  2040. //
  2041. // The FSP level dispatch/main routine. This is the routine that takes
  2042. // IRP's off of the work queue and calls the appropriate FSP level
  2043. // work routine.
  2044. //
  2045. VOID
  2046. UdfFspDispatch ( // implemented in FspDisp.c
  2047. IN PIRP_CONTEXT IrpContext
  2048. );
  2049. VOID
  2050. UdfFspClose ( // Implemented in Close.c
  2051. IN PVCB Vcb OPTIONAL
  2052. );
  2053. //
  2054. // The following routines are the entry points for the different operations
  2055. // based on the IrpSp major functions.
  2056. //
  2057. NTSTATUS
  2058. UdfCommonCleanup ( // Implemented in Cleanup.c
  2059. IN PIRP_CONTEXT IrpContext,
  2060. IN PIRP Irp
  2061. );
  2062. NTSTATUS
  2063. UdfCommonClose ( // Implemented in Close.c
  2064. IN PIRP_CONTEXT IrpContext,
  2065. IN PIRP Irp
  2066. );
  2067. NTSTATUS
  2068. UdfCommonCreate ( // Implemented in Create.c
  2069. IN PIRP_CONTEXT IrpContext,
  2070. IN PIRP Irp
  2071. );
  2072. NTSTATUS // Implemented in DevCtrl.c
  2073. UdfCommonDevControl (
  2074. IN PIRP_CONTEXT IrpContext,
  2075. IN PIRP Irp
  2076. );
  2077. NTSTATUS // Implemented in DirCtrl.c
  2078. UdfCommonDirControl (
  2079. IN PIRP_CONTEXT IrpContext,
  2080. IN PIRP Irp
  2081. );
  2082. NTSTATUS
  2083. UdfCommonFsControl ( // Implemented in FsCtrl.c
  2084. IN PIRP_CONTEXT IrpContext,
  2085. IN PIRP Irp
  2086. );
  2087. NTSTATUS // Implemented in LockCtrl.c
  2088. UdfCommonLockControl (
  2089. IN PIRP_CONTEXT IrpContext,
  2090. IN PIRP Irp
  2091. );
  2092. NTSTATUS // Implemented in Pnp.c
  2093. UdfCommonPnp (
  2094. IN PIRP_CONTEXT IrpContext,
  2095. IN PIRP Irp
  2096. );
  2097. NTSTATUS // Implemented in FileInfo.c
  2098. UdfCommonQueryInfo (
  2099. IN PIRP_CONTEXT IrpContext,
  2100. IN PIRP Irp
  2101. );
  2102. NTSTATUS // Implemented in VolInfo.c
  2103. UdfCommonQueryVolInfo (
  2104. IN PIRP_CONTEXT IrpContext,
  2105. IN PIRP Irp
  2106. );
  2107. NTSTATUS // Implemented in Read.c
  2108. UdfCommonRead (
  2109. IN PIRP_CONTEXT IrpContext,
  2110. IN PIRP Irp
  2111. );
  2112. NTSTATUS
  2113. UdfCommonWrite (
  2114. IN PIRP_CONTEXT IrpContext, // write.c
  2115. IN PIRP Irp
  2116. );
  2117. NTSTATUS // Implemented in FileInfo.c
  2118. UdfCommonSetInfo (
  2119. IN PIRP_CONTEXT IrpContext,
  2120. IN PIRP Irp
  2121. );
  2122. NTSTATUS
  2123. UdfHijackIrpAndFlushDevice ( // flush.c
  2124. IN PIRP_CONTEXT IrpContext,
  2125. IN PIRP Irp,
  2126. IN PDEVICE_OBJECT TargetDeviceObject
  2127. );
  2128. // BOOLEAN
  2129. // UdfExtendedFEAllowed(
  2130. // PVCB Vcb
  2131. // )
  2132. //
  2133. // Decides, based on the NSR revision encountered on the volume, whether or not the
  2134. // extended FE is legal and expected on this volume
  2135. #define UdfExtendedFEAllowed( V) (VsdIdentNSR03 == (V)->NsrVersion)
  2136. // BOOLEAN
  2137. // UdfMinLegalVATSize(
  2138. // PVCB Vcb
  2139. // )
  2140. //
  2141. // Decides based on the NSR revision encountered on the volume
  2142. #define UdfMinLegalVATSize( V) ((VsdIdentNSR03 == (V)->NsrVersion) ? UDF_CDUDF_MINIMUM_20x_VAT_SIZE : UDF_CDUDF_MINIMUM_150_VAT_SIZE)
  2143. // BOOLEAN
  2144. // UdfVATIcbFileTypeExpected(
  2145. // PVCB Vcb
  2146. // )
  2147. //
  2148. // Decides, based on the NSR revision encountered on the volume, what value we
  2149. // expect the FileType field in the VAT Icb to have
  2150. #define UdfVATIcbFileTypeExpected( V) ((VsdIdentNSR03 == (V)->NsrVersion) ? ICBTAG_FILE_T_VAT : ICBTAG_FILE_T_NOTSPEC)
  2151. // BOOLEAN
  2152. // UdfVATHasHeaderRecord(
  2153. // PVCB Vcb
  2154. // )
  2155. //
  2156. // Decides, based on the NSR revision encountered on the volume, if the VAT should have
  2157. // the header (2.00) record, or the 1.5 style trailing regid.
  2158. #define UdfVATHasHeaderRecord( V) (VsdIdentNSR03 == (V)->NsrVersion)
  2159. //
  2160. // Clean up our internal-to-the-header definitions so they do not leak out.
  2161. //
  2162. #undef BugCheckFileId
  2163. #undef Dbg
  2164. #endif // _UDFPROCS_