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.

1822 lines
45 KiB

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