Source code of Windows XP (NT5)
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.

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