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.

1593 lines
39 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // Copyright (C) 1992, Microsoft Corporation
  4. //
  5. // File: fastio.c
  6. //
  7. // Contents: Routines to implement Fast IO
  8. //
  9. // Classes:
  10. //
  11. // Functions:
  12. //
  13. // History: 8/11/93 Milans created
  14. //
  15. //-----------------------------------------------------------------------------
  16. #include "dfsprocs.h"
  17. #include "fsctrl.h"
  18. #include "fastio.h"
  19. #include "attach.h"
  20. #include "srv.h"
  21. #define Dbg (DEBUG_TRACE_FASTIO)
  22. BOOLEAN
  23. DfsFastIoCheckIfPossible (
  24. FILE_OBJECT *pFileObject,
  25. LARGE_INTEGER *pOffset,
  26. ULONG Length,
  27. BOOLEAN fWait,
  28. ULONG LockKey,
  29. BOOLEAN fCheckForRead,
  30. IO_STATUS_BLOCK *pIoStatusBlock,
  31. DEVICE_OBJECT *DeviceObject
  32. );
  33. BOOLEAN
  34. DfsFastIoRead(
  35. IN struct _FILE_OBJECT *FileObject,
  36. IN PLARGE_INTEGER FileOffset,
  37. IN ULONG Length,
  38. IN BOOLEAN Wait,
  39. IN ULONG LockKey,
  40. OUT PVOID Buffer,
  41. OUT PIO_STATUS_BLOCK IoStatus,
  42. DEVICE_OBJECT *DeviceObject
  43. );
  44. BOOLEAN
  45. DfsFastIoWrite(
  46. IN struct _FILE_OBJECT *FileObject,
  47. IN PLARGE_INTEGER FileOffset,
  48. IN ULONG Length,
  49. IN BOOLEAN Wait,
  50. IN ULONG LockKey,
  51. IN PVOID Buffer,
  52. OUT PIO_STATUS_BLOCK IoStatus,
  53. DEVICE_OBJECT *DeviceObject
  54. );
  55. BOOLEAN
  56. DfsFastIoQueryBasicInfo(
  57. IN struct _FILE_OBJECT *FileObject,
  58. IN BOOLEAN Wait,
  59. OUT PFILE_BASIC_INFORMATION Buffer,
  60. OUT PIO_STATUS_BLOCK IoStatus,
  61. DEVICE_OBJECT *DeviceObject
  62. );
  63. BOOLEAN
  64. DfsFastIoQueryStandardInfo(
  65. IN struct _FILE_OBJECT *FileObject,
  66. IN BOOLEAN Wait,
  67. OUT PFILE_STANDARD_INFORMATION Buffer,
  68. OUT PIO_STATUS_BLOCK IoStatus,
  69. DEVICE_OBJECT *DeviceObject
  70. );
  71. BOOLEAN
  72. DfsFastIoLock(
  73. IN struct _FILE_OBJECT *FileObject,
  74. IN PLARGE_INTEGER FileOffset,
  75. IN PLARGE_INTEGER Length,
  76. PEPROCESS ProcessId,
  77. ULONG Key,
  78. BOOLEAN FailImmediately,
  79. BOOLEAN ExclusiveLock,
  80. OUT PIO_STATUS_BLOCK IoStatus,
  81. DEVICE_OBJECT *DeviceObject
  82. );
  83. BOOLEAN
  84. DfsFastIoUnlockSingle(
  85. IN struct _FILE_OBJECT *FileObject,
  86. IN PLARGE_INTEGER FileOffset,
  87. IN PLARGE_INTEGER Length,
  88. PEPROCESS ProcessId,
  89. ULONG Key,
  90. OUT PIO_STATUS_BLOCK IoStatus,
  91. DEVICE_OBJECT *DeviceObject
  92. );
  93. BOOLEAN
  94. DfsFastIoUnlockAll(
  95. IN struct _FILE_OBJECT *FileObject,
  96. PEPROCESS ProcessId,
  97. OUT PIO_STATUS_BLOCK IoStatus,
  98. DEVICE_OBJECT *DeviceObject
  99. );
  100. BOOLEAN
  101. DfsFastIoUnlockAllByKey(
  102. IN struct _FILE_OBJECT *FileObject,
  103. PVOID ProcessId,
  104. ULONG Key,
  105. OUT PIO_STATUS_BLOCK IoStatus,
  106. DEVICE_OBJECT *DeviceObject
  107. );
  108. BOOLEAN
  109. DfsFastIoDeviceControl(
  110. IN struct _FILE_OBJECT *FileObject,
  111. IN BOOLEAN Wait,
  112. IN PVOID InputBuffer OPTIONAL,
  113. IN ULONG InputBufferLength,
  114. OUT PVOID OutputBuffer OPTIONAL,
  115. IN ULONG OutputBufferLength,
  116. IN ULONG IoControlCode,
  117. OUT PIO_STATUS_BLOCK IoStatus,
  118. DEVICE_OBJECT *DeviceObject);
  119. VOID
  120. DfsFastIoAcquireFile(
  121. IN PFILE_OBJECT FileObject);
  122. VOID
  123. DfsFastIoReleaseFile(
  124. IN PFILE_OBJECT FileObject);
  125. VOID
  126. DfsFastIoDetachDevice(
  127. IN PDEVICE_OBJECT SourceDevice,
  128. IN PDEVICE_OBJECT TargetDevice);
  129. BOOLEAN
  130. DfsFastIoQueryNetworkOpenInfo(
  131. IN PFILE_OBJECT FileObject,
  132. IN BOOLEAN Wait,
  133. OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
  134. OUT PIO_STATUS_BLOCK IoStatus,
  135. IN PDEVICE_OBJECT DeviceObject);
  136. BOOLEAN
  137. DfsFastIoMdlRead(
  138. IN PFILE_OBJECT FileObject,
  139. IN PLARGE_INTEGER FileOffset,
  140. IN ULONG Length,
  141. IN ULONG LockKey,
  142. OUT PMDL *MdlChain,
  143. OUT PIO_STATUS_BLOCK IoStatus,
  144. IN PDEVICE_OBJECT DeviceObject);
  145. BOOLEAN
  146. DfsFastIoMdlReadComplete(
  147. IN PFILE_OBJECT FileObject,
  148. IN PMDL MdlChain,
  149. IN PDEVICE_OBJECT DeviceObject
  150. );
  151. BOOLEAN
  152. DfsFastIoPrepareMdlWrite(
  153. IN PFILE_OBJECT FileObject,
  154. IN PLARGE_INTEGER FileOffset,
  155. IN ULONG Length,
  156. IN ULONG LockKey,
  157. OUT PMDL *MdlChain,
  158. OUT PIO_STATUS_BLOCK IoStatus,
  159. IN PDEVICE_OBJECT DeviceObject
  160. );
  161. BOOLEAN
  162. DfsFastIoMdlWriteComplete(
  163. IN PFILE_OBJECT FileObject,
  164. IN PLARGE_INTEGER FileOffset,
  165. IN PMDL MdlChain,
  166. IN PDEVICE_OBJECT DeviceObject
  167. );
  168. //
  169. // If this routine is present, it will be called by FsRtl
  170. // to acquire the file for the mapped page writer.
  171. //
  172. NTSTATUS
  173. DfsFastIoAcquireForModWrite(
  174. IN PFILE_OBJECT FileObject,
  175. IN PLARGE_INTEGER EndingOffset,
  176. OUT PERESOURCE *ResourceToRelease,
  177. IN PDEVICE_OBJECT DeviceObject);
  178. BOOLEAN
  179. DfsFastIoReadCompressed(
  180. IN PFILE_OBJECT FileObject,
  181. IN PLARGE_INTEGER FileOffset,
  182. IN ULONG Length,
  183. IN ULONG LockKey,
  184. OUT PVOID Buffer,
  185. OUT PMDL *MdlChain,
  186. OUT PIO_STATUS_BLOCK IoStatus,
  187. OUT PCOMPRESSED_DATA_INFO CompressedDataInfo,
  188. IN ULONG CompressedDataInfoLength,
  189. IN PDEVICE_OBJECT DeviceObject
  190. );
  191. BOOLEAN
  192. DfsFastIoWriteCompressed(
  193. IN PFILE_OBJECT FileObject,
  194. IN PLARGE_INTEGER FileOffset,
  195. IN ULONG Length,
  196. IN ULONG LockKey,
  197. IN PVOID Buffer,
  198. OUT PMDL *MdlChain,
  199. OUT PIO_STATUS_BLOCK IoStatus,
  200. IN PCOMPRESSED_DATA_INFO CompressedDataInfo,
  201. IN ULONG CompressedDataInfoLength,
  202. IN PDEVICE_OBJECT DeviceObject);
  203. BOOLEAN
  204. DfsFastIoMdlReadCompleteCompressed(
  205. IN PFILE_OBJECT FileObject,
  206. IN PMDL MdlChain,
  207. IN PDEVICE_OBJECT DeviceObject);
  208. BOOLEAN
  209. DfsFastIoMdlWriteCompleteCompressed(
  210. IN PFILE_OBJECT FileObject,
  211. IN PLARGE_INTEGER FileOffset,
  212. IN PMDL MdlChain,
  213. IN PDEVICE_OBJECT DeviceObject);
  214. PFAST_IO_DISPATCH
  215. DfsFastIoLookup(
  216. IN FILE_OBJECT *pFileObject,
  217. IN DEVICE_OBJECT *DeviceObject,
  218. IN PDEVICE_OBJECT *targetVdo);
  219. #ifdef ALLOC_PRAGMA
  220. #pragma alloc_text( PAGE, DfsFastIoCheckIfPossible )
  221. #pragma alloc_text( PAGE, DfsFastIoRead )
  222. #pragma alloc_text( PAGE, DfsFastIoWrite )
  223. #pragma alloc_text( PAGE, DfsFastIoQueryBasicInfo )
  224. #pragma alloc_text( PAGE, DfsFastIoQueryStandardInfo )
  225. #pragma alloc_text( PAGE, DfsFastIoLock )
  226. #pragma alloc_text( PAGE, DfsFastIoUnlockSingle )
  227. #pragma alloc_text( PAGE, DfsFastIoUnlockAll )
  228. #pragma alloc_text( PAGE, DfsFastIoUnlockAllByKey )
  229. #pragma alloc_text( PAGE, DfsFastIoDeviceControl )
  230. #pragma alloc_text( PAGE, DfsFastIoDetachDevice )
  231. #endif // ALLOC_PRAGMA
  232. FAST_IO_DISPATCH FastIoDispatch =
  233. {
  234. sizeof(FAST_IO_DISPATCH),
  235. DfsFastIoCheckIfPossible, // CheckForFastIo
  236. DfsFastIoRead, // FastIoRead
  237. DfsFastIoWrite, // FastIoWrite
  238. DfsFastIoQueryBasicInfo, // FastIoQueryBasicInfo
  239. DfsFastIoQueryStandardInfo, // FastIoQueryStandardInfo
  240. DfsFastIoLock, // FastIoLock
  241. DfsFastIoUnlockSingle, // FastIoUnlockSingle
  242. DfsFastIoUnlockAll, // FastIoUnlockAll
  243. DfsFastIoUnlockAllByKey, // FastIoUnlockAllByKey
  244. DfsFastIoDeviceControl, // FastIoDeviceControl
  245. DfsFastIoAcquireFile, // AcquireFileForNtCreateSection
  246. DfsFastIoReleaseFile, // ReleaseFileForNtCreateSection
  247. DfsFastIoDetachDevice, // FastIoDetachDevice
  248. DfsFastIoQueryNetworkOpenInfo, // FastIoQueryNetworkOpenInfo
  249. DfsFastIoAcquireForModWrite, // AcquireForModWrite
  250. DfsFastIoMdlRead, // MdlRead
  251. DfsFastIoMdlReadComplete, // MdlReadComplete
  252. DfsFastIoPrepareMdlWrite, // PrepareMdlWrite
  253. DfsFastIoMdlWriteComplete, // MdlWriteComplete
  254. DfsFastIoReadCompressed, // FastIoReadCompressed
  255. DfsFastIoWriteCompressed, // FastIoWriteCompressed
  256. DfsFastIoMdlReadCompleteCompressed, // MdlReadCompleteCompressed
  257. DfsFastIoMdlWriteCompleteCompressed // MdlWriteCompleteCompressed
  258. };
  259. //
  260. // Macro to see if a PFAST_IO_DISPATCH has a particular field
  261. //
  262. #define IS_VALID_INDEX(pfio, e) \
  263. ((pfio != NULL) && \
  264. (pfio->SizeOfFastIoDispatch >= \
  265. (offsetof(FAST_IO_DISPATCH, e) + sizeof(PVOID))) && \
  266. (pfio->e != NULL) \
  267. )
  268. //+----------------------------------------------------------------------------
  269. //
  270. // Function: DfsFastIoLookup
  271. //
  272. // Synopsis: Given a file object, this routine will locate the fast IO
  273. // dispatch table for the underlying provider
  274. //
  275. // Arguments:
  276. //
  277. // Returns:
  278. //
  279. //-----------------------------------------------------------------------------
  280. PFAST_IO_DISPATCH
  281. DfsFastIoLookup(
  282. IN FILE_OBJECT *pFileObject,
  283. IN DEVICE_OBJECT *DeviceObject,
  284. OUT PDEVICE_OBJECT *targetVdo)
  285. {
  286. PFAST_IO_DISPATCH pFastIoTable;
  287. *targetVdo = NULL;
  288. DebugTrace(+1, Dbg, "DfsFastIoLookup: Entered\n", 0);
  289. if (DeviceObject->DeviceType == FILE_DEVICE_DFS_VOLUME) {
  290. //
  291. // In this case we have a direct pointer to the next device to which
  292. // we need to pass on (This is attached device case).
  293. //
  294. *targetVdo = ((PDFS_VOLUME_OBJECT) DeviceObject)->Provider.DeviceObject;
  295. pFastIoTable = (*targetVdo)->DriverObject->FastIoDispatch;
  296. DebugTrace(0,Dbg, "DfsFastIoLookup: DevObj: %08lx\n", DeviceObject);
  297. DebugTrace(0, Dbg, "DfsFastIoLookup: TargetVdo %08lx\n", *targetVdo);
  298. DebugTrace(-1,Dbg, "DfsFastIoLookup: Exit -> %08lx\n", pFastIoTable );
  299. return(pFastIoTable);
  300. } else if (DeviceObject->DeviceType == FILE_DEVICE_DISK_FILE_SYSTEM ) {
  301. //
  302. // An operation intended for a disk file system we are attached to.
  303. //
  304. *targetVdo = ((PDFS_ATTACH_FILE_SYSTEM_OBJECT) DeviceObject)->TargetDevice;
  305. pFastIoTable = (*targetVdo)->DriverObject->FastIoDispatch;
  306. DebugTrace(0,Dbg, "DfsFastIoLookup: DevObj: %08lx ", DeviceObject);
  307. DebugTrace(0, Dbg, "TargetVdo %08lx\n", *targetVdo);
  308. DebugTrace(-1,Dbg, "DfsFastIoLookup: Exit -> %08lx\n", pFastIoTable );
  309. return( pFastIoTable );
  310. } else {
  311. //
  312. // This is an unknown device object type and we dont know what to do
  313. //
  314. DebugTrace(0, 0,
  315. "DfsFastIoLookup: Unexpected DeviceObject Type %08x\n",
  316. DeviceObject);
  317. ASSERT(FALSE && "Unknown DeviceObject");
  318. DebugTrace(-1,Dbg, "DfsFastIoLookup: Exit -> %08lx\n", NULL );
  319. return(NULL);
  320. }
  321. }
  322. //+----------------------------------------------------------------------------
  323. //
  324. // Function: DfsFastIoCheckIfPossible
  325. //
  326. // Synopsis:
  327. //
  328. // Arguments:
  329. //
  330. // Returns:
  331. //
  332. //-----------------------------------------------------------------------------
  333. BOOLEAN
  334. DfsFastIoCheckIfPossible (
  335. FILE_OBJECT *pFileObject,
  336. LARGE_INTEGER *pOffset,
  337. ULONG Length,
  338. BOOLEAN fWait,
  339. ULONG LockKey,
  340. BOOLEAN fCheckForRead,
  341. IO_STATUS_BLOCK *pIoStatusBlock,
  342. PDEVICE_OBJECT DeviceObject)
  343. {
  344. PFAST_IO_DISPATCH pFastIoTable;
  345. PDEVICE_OBJECT targetVdo;
  346. BOOLEAN fPossible;
  347. DebugTrace(+1, Dbg, "DfsFastIoCheckIfPossible Enter \n", 0);
  348. pFastIoTable = DfsFastIoLookup(pFileObject, DeviceObject, &targetVdo);
  349. if ( IS_VALID_INDEX(pFastIoTable, FastIoCheckIfPossible) ) {
  350. fPossible = pFastIoTable->FastIoCheckIfPossible(
  351. pFileObject,
  352. pOffset,
  353. Length,
  354. fWait,
  355. LockKey,
  356. fCheckForRead,
  357. pIoStatusBlock,
  358. targetVdo);
  359. } else {
  360. fPossible = FALSE;
  361. }
  362. DebugTrace(-1, Dbg, "DfsFastIoCheckIfPossible Exit \n", 0);
  363. return(fPossible);
  364. }
  365. //+----------------------------------------------------------------------------
  366. //
  367. // Function: DfsFastIoRead
  368. //
  369. // Synopsis:
  370. //
  371. // Arguments:
  372. //
  373. // Returns:
  374. //
  375. //-----------------------------------------------------------------------------
  376. BOOLEAN
  377. DfsFastIoRead(
  378. IN PFILE_OBJECT FileObject,
  379. IN PLARGE_INTEGER FileOffset,
  380. IN ULONG Length,
  381. IN BOOLEAN Wait,
  382. IN ULONG LockKey,
  383. OUT PVOID Buffer,
  384. OUT PIO_STATUS_BLOCK IoStatus,
  385. PDEVICE_OBJECT DeviceObject
  386. )
  387. {
  388. PFAST_IO_DISPATCH pFastIoTable;
  389. PDEVICE_OBJECT targetVdo;
  390. BOOLEAN fPossible;
  391. DebugTrace(+1, Dbg, "DfsFastIoRead Enter \n", 0);
  392. pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
  393. if ( IS_VALID_INDEX(pFastIoTable, FastIoRead) ) {
  394. fPossible = pFastIoTable->FastIoRead(
  395. FileObject,
  396. FileOffset,
  397. Length,
  398. Wait,
  399. LockKey,
  400. Buffer,
  401. IoStatus,
  402. targetVdo);
  403. } else {
  404. fPossible = FALSE;
  405. }
  406. DebugTrace(-1, Dbg, "DfsFastIoRead Exit \n", 0);
  407. return(fPossible);
  408. }
  409. //+----------------------------------------------------------------------------
  410. //
  411. // Function: DfsFastIoWrite
  412. //
  413. // Synopsis:
  414. //
  415. // Arguments:
  416. //
  417. // Returns:
  418. //
  419. //-----------------------------------------------------------------------------
  420. BOOLEAN
  421. DfsFastIoWrite(
  422. IN PFILE_OBJECT FileObject,
  423. IN PLARGE_INTEGER FileOffset,
  424. IN ULONG Length,
  425. IN BOOLEAN Wait,
  426. IN ULONG LockKey,
  427. IN PVOID Buffer,
  428. OUT PIO_STATUS_BLOCK IoStatus,
  429. PDEVICE_OBJECT DeviceObject
  430. )
  431. {
  432. PFAST_IO_DISPATCH pFastIoTable;
  433. PDEVICE_OBJECT targetVdo;
  434. BOOLEAN fPossible;
  435. DebugTrace(+1, Dbg, "DfsFastIoWrite Enter \n", 0);
  436. pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
  437. if ( IS_VALID_INDEX(pFastIoTable, FastIoWrite) ) {
  438. fPossible = pFastIoTable->FastIoWrite(
  439. FileObject,
  440. FileOffset,
  441. Length,
  442. Wait,
  443. LockKey,
  444. Buffer,
  445. IoStatus,
  446. targetVdo);
  447. } else {
  448. fPossible = FALSE;
  449. }
  450. DebugTrace(-1, Dbg, "DfsFastIoWrite Exit \n", 0);
  451. return(fPossible);
  452. }
  453. //+----------------------------------------------------------------------------
  454. //
  455. // Function: DfsFastIoQueryBasicInfo
  456. //
  457. // Synopsis:
  458. //
  459. // Arguments:
  460. //
  461. // Returns:
  462. //
  463. //-----------------------------------------------------------------------------
  464. BOOLEAN
  465. DfsFastIoQueryBasicInfo(
  466. IN PFILE_OBJECT FileObject,
  467. IN BOOLEAN Wait,
  468. OUT PFILE_BASIC_INFORMATION Buffer,
  469. OUT PIO_STATUS_BLOCK IoStatus,
  470. PDEVICE_OBJECT DeviceObject)
  471. {
  472. PFAST_IO_DISPATCH pFastIoTable;
  473. PDEVICE_OBJECT targetVdo;
  474. BOOLEAN fPossible;
  475. DebugTrace(+1, Dbg, "DfsFastIoQueryBasicInfo Enter \n", 0);
  476. pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
  477. if ( IS_VALID_INDEX(pFastIoTable, FastIoQueryBasicInfo) ) {
  478. fPossible = pFastIoTable->FastIoQueryBasicInfo(
  479. FileObject,
  480. Wait,
  481. Buffer,
  482. IoStatus,
  483. targetVdo);
  484. } else {
  485. fPossible = FALSE;
  486. }
  487. DebugTrace(-1, Dbg, "DfsFastIoQueryBasicInfo Exit \n", 0);
  488. return(fPossible);
  489. }
  490. //+----------------------------------------------------------------------------
  491. //
  492. // Function: DfsFastIoQueryStandardInfo
  493. //
  494. // Synopsis:
  495. //
  496. // Arguments:
  497. //
  498. // Returns:
  499. //
  500. //-----------------------------------------------------------------------------
  501. BOOLEAN
  502. DfsFastIoQueryStandardInfo(
  503. IN PFILE_OBJECT FileObject,
  504. IN BOOLEAN Wait,
  505. OUT PFILE_STANDARD_INFORMATION Buffer,
  506. OUT PIO_STATUS_BLOCK IoStatus,
  507. PDEVICE_OBJECT DeviceObject)
  508. {
  509. PFAST_IO_DISPATCH pFastIoTable;
  510. PDEVICE_OBJECT targetVdo;
  511. BOOLEAN fPossible;
  512. DebugTrace(+1, Dbg, "DfsFastIoQueryStandardInfo Enter \n", 0);
  513. pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
  514. if ( IS_VALID_INDEX(pFastIoTable, FastIoQueryStandardInfo) ) {
  515. fPossible = pFastIoTable->FastIoQueryStandardInfo(
  516. FileObject,
  517. Wait,
  518. Buffer,
  519. IoStatus,
  520. targetVdo);
  521. } else {
  522. fPossible = FALSE;
  523. }
  524. DebugTrace(-1, Dbg, "DfsFastIoQueryStandardInfo Exit \n", 0);
  525. return(fPossible);
  526. }
  527. //+----------------------------------------------------------------------------
  528. //
  529. // Function: DfsFastIoLock
  530. //
  531. // Synopsis:
  532. //
  533. // Arguments:
  534. //
  535. // Returns:
  536. //
  537. //-----------------------------------------------------------------------------
  538. BOOLEAN
  539. DfsFastIoLock(
  540. IN PFILE_OBJECT FileObject,
  541. IN PLARGE_INTEGER FileOffset,
  542. IN PLARGE_INTEGER Length,
  543. PEPROCESS ProcessId,
  544. ULONG Key,
  545. BOOLEAN FailImmediately,
  546. BOOLEAN ExclusiveLock,
  547. OUT PIO_STATUS_BLOCK IoStatus,
  548. PDEVICE_OBJECT DeviceObject
  549. )
  550. {
  551. PFAST_IO_DISPATCH pFastIoTable;
  552. PDEVICE_OBJECT targetVdo;
  553. BOOLEAN fPossible;
  554. DebugTrace(+1, Dbg, "DfsFastIoLock Enter \n", 0);
  555. pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
  556. if ( IS_VALID_INDEX(pFastIoTable, FastIoLock) ) {
  557. fPossible = pFastIoTable->FastIoLock(
  558. FileObject,
  559. FileOffset,
  560. Length,
  561. ProcessId,
  562. Key,
  563. FailImmediately,
  564. ExclusiveLock,
  565. IoStatus,
  566. targetVdo);
  567. } else {
  568. fPossible = FALSE;
  569. }
  570. DebugTrace(-1, Dbg, "DfsFastIoLock Exit \n", 0);
  571. return(fPossible);
  572. }
  573. //+----------------------------------------------------------------------------
  574. //
  575. // Function: DfsFastIoUnlockSingle
  576. //
  577. // Synopsis:
  578. //
  579. // Arguments:
  580. //
  581. // Returns:
  582. //
  583. //-----------------------------------------------------------------------------
  584. BOOLEAN
  585. DfsFastIoUnlockSingle(
  586. IN PFILE_OBJECT FileObject,
  587. IN PLARGE_INTEGER FileOffset,
  588. IN PLARGE_INTEGER Length,
  589. PEPROCESS ProcessId,
  590. ULONG Key,
  591. OUT PIO_STATUS_BLOCK IoStatus,
  592. PDEVICE_OBJECT DeviceObject)
  593. {
  594. PFAST_IO_DISPATCH pFastIoTable;
  595. PDEVICE_OBJECT targetVdo;
  596. BOOLEAN fPossible;
  597. DebugTrace(+1, Dbg, "DfsFastIoUnlockSingle Enter \n", 0);
  598. pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
  599. if ( IS_VALID_INDEX(pFastIoTable, FastIoUnlockSingle) ) {
  600. fPossible = pFastIoTable->FastIoUnlockSingle(
  601. FileObject,
  602. FileOffset,
  603. Length,
  604. ProcessId,
  605. Key,
  606. IoStatus,
  607. targetVdo);
  608. } else {
  609. fPossible = FALSE;
  610. }
  611. DebugTrace(-1, Dbg, "DfsFastIoUnlockSingle Exit \n", 0);
  612. return(fPossible);
  613. }
  614. //+----------------------------------------------------------------------------
  615. //
  616. // Function: DfsFastIoUnlockAll
  617. //
  618. // Synopsis:
  619. //
  620. // Arguments:
  621. //
  622. // Returns:
  623. //
  624. //-----------------------------------------------------------------------------
  625. BOOLEAN
  626. DfsFastIoUnlockAll(
  627. IN PFILE_OBJECT FileObject,
  628. PEPROCESS ProcessId,
  629. OUT PIO_STATUS_BLOCK IoStatus,
  630. PDEVICE_OBJECT DeviceObject
  631. )
  632. {
  633. PFAST_IO_DISPATCH pFastIoTable;
  634. PDEVICE_OBJECT targetVdo;
  635. BOOLEAN fPossible;
  636. DebugTrace(+1, Dbg, "DfsFastIoUnlockAll Enter \n", 0);
  637. pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
  638. if ( IS_VALID_INDEX(pFastIoTable, FastIoUnlockAll) ) {
  639. fPossible = pFastIoTable->FastIoUnlockAll(
  640. FileObject,
  641. ProcessId,
  642. IoStatus,
  643. targetVdo);
  644. } else {
  645. fPossible = FALSE;
  646. }
  647. DebugTrace(-1, Dbg, "DfsFastIoUnlockAll Exit \n", 0);
  648. return(fPossible);
  649. }
  650. //+----------------------------------------------------------------------------
  651. //
  652. // Function: FastIoUnlockAllByKey
  653. //
  654. // Synopsis:
  655. //
  656. // Arguments:
  657. //
  658. // Returns:
  659. //
  660. //-----------------------------------------------------------------------------
  661. BOOLEAN
  662. DfsFastIoUnlockAllByKey(
  663. IN PFILE_OBJECT FileObject,
  664. PVOID ProcessId,
  665. ULONG Key,
  666. OUT PIO_STATUS_BLOCK IoStatus,
  667. PDEVICE_OBJECT DeviceObject
  668. )
  669. {
  670. PFAST_IO_DISPATCH pFastIoTable;
  671. PDEVICE_OBJECT targetVdo;
  672. BOOLEAN fPossible;
  673. DebugTrace(+1, Dbg, "DfsFastIoUnlockAllByKey Enter \n", 0);
  674. pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
  675. if ( IS_VALID_INDEX(pFastIoTable, FastIoUnlockAllByKey) ) {
  676. fPossible = pFastIoTable->FastIoUnlockAllByKey(
  677. FileObject,
  678. ProcessId,
  679. Key,
  680. IoStatus,
  681. targetVdo);
  682. } else {
  683. fPossible = FALSE;
  684. }
  685. DebugTrace(-1, Dbg, "DfsFastIoUnlockAllByKey Exit \n", 0);
  686. return(fPossible);
  687. }
  688. //+----------------------------------------------------------------------------
  689. //
  690. // Function: DfsFastIoDeviceControl
  691. //
  692. // Synopsis:
  693. //
  694. // Arguments:
  695. //
  696. // Returns:
  697. //
  698. //-----------------------------------------------------------------------------
  699. BOOLEAN
  700. DfsFastIoDeviceControl(
  701. IN PFILE_OBJECT FileObject,
  702. IN BOOLEAN Wait,
  703. IN PVOID InputBuffer OPTIONAL,
  704. IN ULONG InputBufferLength,
  705. OUT PVOID OutputBuffer OPTIONAL,
  706. IN ULONG OutputBufferLength,
  707. IN ULONG IoControlCode,
  708. OUT PIO_STATUS_BLOCK IoStatus,
  709. PDEVICE_OBJECT DeviceObject
  710. )
  711. {
  712. PFAST_IO_DISPATCH pFastIoTable;
  713. PDEVICE_OBJECT targetVdo;
  714. BOOLEAN fPossible;
  715. DebugTrace(+1, Dbg, "DfsFastIoDeviceControl Enter \n", 0);
  716. //
  717. // See if this is the server making fsctl calls to us...
  718. //
  719. if (DeviceObject->DeviceType == FILE_DEVICE_DFS_FILE_SYSTEM) {
  720. if (FileObject->FsContext == UIntToPtr( DFS_OPEN_CONTEXT )) {
  721. DfsSrvFsctrl(
  722. IoControlCode,
  723. InputBuffer,
  724. InputBufferLength,
  725. OutputBuffer,
  726. OutputBufferLength,
  727. IoStatus);
  728. fPossible = TRUE;
  729. } else {
  730. //
  731. // This should never happen, since its unlikely that there is
  732. // someone else registering a FILE_DEVICE_DFS_FILE_SYSTEM, and
  733. // even if they did, we wouldn't be attaching to it.
  734. //
  735. DebugTrace(0, 0,
  736. "DfsFastIoDeviceControl: Unknown device %08lx\n",
  737. DeviceObject);
  738. ASSERT( FALSE && "FastIO fsctrl on illegal device!\n" );
  739. DebugTrace(-1,Dbg, "DfsFastIoDeviceControl: Exit\n", 0);
  740. fPossible = FALSE;
  741. }
  742. } else if (IS_DFS_CTL_CODE(IoControlCode)) {
  743. //
  744. // One of our control codes, can't handle it via fast IO
  745. //
  746. DebugTrace(0, Dbg, "Dfs fsctrl code %08lx - returning FALSE\n",
  747. ULongToPtr( IoControlCode ));
  748. fPossible = FALSE;
  749. } else {
  750. pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
  751. if ( IS_VALID_INDEX(pFastIoTable, FastIoDeviceControl) ) {
  752. fPossible = pFastIoTable->FastIoDeviceControl(
  753. FileObject,
  754. Wait,
  755. InputBuffer,
  756. InputBufferLength,
  757. OutputBuffer,
  758. OutputBufferLength,
  759. IoControlCode,
  760. IoStatus,
  761. targetVdo);
  762. } else {
  763. fPossible = FALSE;
  764. }
  765. }
  766. DebugTrace(-1, Dbg, "DfsFastIoDeviceControl Exit \n", 0);
  767. return(fPossible);
  768. }
  769. //+----------------------------------------------------------------------------
  770. //
  771. // Function: DfsFastIoAcquireFile
  772. //
  773. // Synopsis: Acquire file for NtCreateSection. Due to a long chain of
  774. // events, this routine must either call the underlying FS's
  775. // AcquireFileForNtCreateSection routine or, if there isn't one,
  776. // we must acquire the FileObject resource ourselves, since
  777. // there is no possibility of returning a BOOLEAN.
  778. //
  779. // Arguments: [FileObject] -- The file to be acquired.
  780. //
  781. // Returns: Nothing
  782. //
  783. //-----------------------------------------------------------------------------
  784. VOID
  785. DfsFastIoAcquireFile(
  786. IN PFILE_OBJECT FileObject)
  787. {
  788. PFAST_IO_DISPATCH pFastIoTable;
  789. PDEVICE_OBJECT deviceObject, targetVdo;
  790. PFSRTL_COMMON_FCB_HEADER header;
  791. //
  792. // Due to an error, this routine was defined without a device object
  793. // argument. We will have to locate our device object
  794. //
  795. if (FileObject->Vpb == NULL) {
  796. deviceObject = FileObject->DeviceObject;
  797. } else {
  798. //
  799. // Pick up the bottommost device object
  800. //
  801. ASSERT( FileObject->Vpb->DeviceObject != NULL );
  802. deviceObject = FileObject->Vpb->DeviceObject;
  803. ASSERT( deviceObject->DeviceType != FILE_DEVICE_DFS_VOLUME );
  804. //
  805. // Now, walk up the attached chain and find our own device object
  806. //
  807. while (deviceObject &&
  808. (deviceObject->DeviceType != FILE_DEVICE_DFS_VOLUME)) {
  809. deviceObject = deviceObject->AttachedDevice;
  810. }
  811. }
  812. ASSERT( deviceObject != NULL );
  813. pFastIoTable = DfsFastIoLookup( FileObject, deviceObject, &targetVdo );
  814. if (IS_VALID_INDEX( pFastIoTable, AcquireFileForNtCreateSection) ) {
  815. IoSetTopLevelIrp( (PIRP) FSRTL_FSP_TOP_LEVEL_IRP );
  816. pFastIoTable->AcquireFileForNtCreateSection( FileObject );
  817. } else if ((header = FileObject->FsContext) && header->Resource) {
  818. IoSetTopLevelIrp( (PIRP) FSRTL_FSP_TOP_LEVEL_IRP );
  819. ExAcquireResourceExclusiveLite( header->Resource, TRUE );
  820. } else {
  821. NOTHING;
  822. }
  823. }
  824. //+----------------------------------------------------------------------------
  825. //
  826. // Function: DfsFastIoReleaseFile
  827. //
  828. // Synopsis: Release file for NtCreateSection. Due to a long chain of
  829. // events, this routine must either call the underlying FS's
  830. // ReleaseFileForNtCreateSection routine or, if there isn't one,
  831. // we must Release the FileObject resource ourselves, since
  832. // there is no possibility of returning a BOOLEAN.
  833. //
  834. // Arguments: [FileObject] -- The file to be Released.
  835. //
  836. // Returns: Nothing
  837. //
  838. //-----------------------------------------------------------------------------
  839. VOID
  840. DfsFastIoReleaseFile(
  841. IN PFILE_OBJECT FileObject)
  842. {
  843. PFAST_IO_DISPATCH pFastIoTable;
  844. PDEVICE_OBJECT deviceObject, targetVdo;
  845. PFSRTL_COMMON_FCB_HEADER header;
  846. //
  847. // Due to an error, this routine was defined without a device object
  848. // argument. We will have to locate our device object
  849. //
  850. if (FileObject->Vpb == NULL) {
  851. deviceObject = FileObject->DeviceObject;
  852. } else {
  853. //
  854. // Pick up the bottommost device object
  855. //
  856. ASSERT( FileObject->Vpb->DeviceObject != NULL );
  857. deviceObject = FileObject->Vpb->DeviceObject;
  858. ASSERT( deviceObject->DeviceType != FILE_DEVICE_DFS_VOLUME );
  859. //
  860. // Now, walk up the attached chain and find our own device object
  861. //
  862. while (deviceObject &&
  863. (deviceObject->DeviceType != FILE_DEVICE_DFS_VOLUME)) {
  864. deviceObject = deviceObject->AttachedDevice;
  865. }
  866. }
  867. ASSERT( deviceObject != NULL );
  868. pFastIoTable = DfsFastIoLookup( FileObject, deviceObject, &targetVdo );
  869. if (IS_VALID_INDEX( pFastIoTable, ReleaseFileForNtCreateSection) ) {
  870. IoSetTopLevelIrp( (PIRP) NULL );
  871. pFastIoTable->ReleaseFileForNtCreateSection( FileObject );
  872. } else if ((header = FileObject->FsContext) && header->Resource) {
  873. IoSetTopLevelIrp( (PIRP) NULL );
  874. ExReleaseResourceLite( header->Resource );
  875. } else {
  876. NOTHING;
  877. }
  878. }
  879. //+----------------------------------------------------------------------------
  880. //
  881. // Function: DfsFastIoDetachDevice, public
  882. //
  883. // Synopsis: This routine is a different from the rest of the fast io
  884. // routines. It is called when a device object is being deleted,
  885. // and that device object has an attached device. The semantics
  886. // of this routine are "You attached to a device object that now
  887. // needs to be deleted; please detach from the said device
  888. // object."
  889. //
  890. // Arguments: [SourceDevice] -- Our device, the one that we created to
  891. // attach ourselves to the target device.
  892. // [TargetDevice] -- Their device, the one that we are attached
  893. // to.
  894. //
  895. // Returns: Nothing - we must succeed.
  896. //
  897. //-----------------------------------------------------------------------------
  898. VOID
  899. DfsFastIoDetachDevice(
  900. IN PDEVICE_OBJECT SourceDevice,
  901. IN PDEVICE_OBJECT TargetDevice)
  902. {
  903. DfsDetachVolumeForDelete( SourceDevice );
  904. }
  905. BOOLEAN
  906. DfsFastIoQueryNetworkOpenInfo(
  907. IN PFILE_OBJECT FileObject,
  908. IN BOOLEAN Wait,
  909. OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
  910. OUT PIO_STATUS_BLOCK IoStatus,
  911. IN PDEVICE_OBJECT DeviceObject)
  912. {
  913. PFAST_IO_DISPATCH pFastIoTable;
  914. PDEVICE_OBJECT targetVdo;
  915. BOOLEAN fPossible;
  916. DebugTrace(+1, Dbg, "DfsFastIoQueryNetworkOpenInfo Enter \n", 0);
  917. pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
  918. if ( IS_VALID_INDEX(pFastIoTable, FastIoQueryNetworkOpenInfo) ) {
  919. fPossible = pFastIoTable->FastIoQueryNetworkOpenInfo(
  920. FileObject,
  921. Wait,
  922. Buffer,
  923. IoStatus,
  924. targetVdo);
  925. } else {
  926. fPossible = FALSE;
  927. IoStatus->Status = STATUS_NOT_SUPPORTED;
  928. }
  929. DebugTrace(-1, Dbg, "DfsFastIoQueryNetworkOpenInfo Exit \n", 0);
  930. return( fPossible );
  931. }
  932. BOOLEAN
  933. DfsFastIoMdlRead(
  934. IN PFILE_OBJECT FileObject,
  935. IN PLARGE_INTEGER FileOffset,
  936. IN ULONG Length,
  937. IN ULONG LockKey,
  938. OUT PMDL *MdlChain,
  939. OUT PIO_STATUS_BLOCK IoStatus,
  940. IN PDEVICE_OBJECT DeviceObject)
  941. {
  942. PFAST_IO_DISPATCH pFastIoTable;
  943. PDEVICE_OBJECT targetVdo;
  944. BOOLEAN fPossible;
  945. DebugTrace(+1, Dbg, "DfsFastIoMdlRead Enter \n", 0);
  946. pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
  947. if ( IS_VALID_INDEX(pFastIoTable, MdlRead) ) {
  948. fPossible = pFastIoTable->MdlRead(
  949. FileObject,
  950. FileOffset,
  951. Length,
  952. LockKey,
  953. MdlChain,
  954. IoStatus,
  955. targetVdo);
  956. } else {
  957. fPossible = FsRtlMdlReadDev(
  958. FileObject,
  959. FileOffset,
  960. Length,
  961. LockKey,
  962. MdlChain,
  963. IoStatus,
  964. targetVdo);
  965. }
  966. DebugTrace(-1, Dbg, "DfsFastIoMdlRead Exit \n", 0);
  967. return( fPossible );
  968. }
  969. BOOLEAN
  970. DfsFastIoMdlReadComplete(
  971. IN PFILE_OBJECT FileObject,
  972. IN PMDL MdlChain,
  973. IN PDEVICE_OBJECT DeviceObject
  974. )
  975. {
  976. PFAST_IO_DISPATCH pFastIoTable;
  977. PDEVICE_OBJECT targetVdo;
  978. BOOLEAN fSuccess;
  979. DebugTrace(+1, Dbg, "DfsFastIoMdlReadComplete Enter \n", 0);
  980. pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
  981. if ( IS_VALID_INDEX(pFastIoTable, MdlReadComplete) ) {
  982. fSuccess = pFastIoTable->MdlReadComplete(
  983. FileObject,
  984. MdlChain,
  985. targetVdo);
  986. } else {
  987. fSuccess = FsRtlMdlReadCompleteDev(
  988. FileObject,
  989. MdlChain,
  990. targetVdo);
  991. }
  992. DebugTrace(-1, Dbg, "DfsFastIoMdlReadComplete Exit \n", 0);
  993. return( fSuccess );
  994. }
  995. BOOLEAN
  996. DfsFastIoPrepareMdlWrite(
  997. IN PFILE_OBJECT FileObject,
  998. IN PLARGE_INTEGER FileOffset,
  999. IN ULONG Length,
  1000. IN ULONG LockKey,
  1001. OUT PMDL *MdlChain,
  1002. OUT PIO_STATUS_BLOCK IoStatus,
  1003. IN PDEVICE_OBJECT DeviceObject)
  1004. {
  1005. PFAST_IO_DISPATCH pFastIoTable;
  1006. PDEVICE_OBJECT targetVdo;
  1007. BOOLEAN fPossible;
  1008. DebugTrace(+1, Dbg, "DfsFastIoPrepareMdlWrite Enter \n", 0);
  1009. pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
  1010. if ( IS_VALID_INDEX(pFastIoTable, PrepareMdlWrite) ) {
  1011. fPossible = pFastIoTable->PrepareMdlWrite(
  1012. FileObject,
  1013. FileOffset,
  1014. Length,
  1015. LockKey,
  1016. MdlChain,
  1017. IoStatus,
  1018. targetVdo);
  1019. } else {
  1020. fPossible = FsRtlPrepareMdlWriteDev(
  1021. FileObject,
  1022. FileOffset,
  1023. Length,
  1024. LockKey,
  1025. MdlChain,
  1026. IoStatus,
  1027. targetVdo);
  1028. }
  1029. DebugTrace(-1, Dbg, "DfsFastIoPrepareMdlWrite Exit \n", 0);
  1030. return( fPossible );
  1031. }
  1032. BOOLEAN
  1033. DfsFastIoMdlWriteComplete(
  1034. IN PFILE_OBJECT FileObject,
  1035. IN PLARGE_INTEGER FileOffset,
  1036. IN PMDL MdlChain,
  1037. IN PDEVICE_OBJECT DeviceObject
  1038. )
  1039. {
  1040. PFAST_IO_DISPATCH pFastIoTable;
  1041. PDEVICE_OBJECT targetVdo;
  1042. BOOLEAN fSuccess;
  1043. DebugTrace(+1, Dbg, "DfsFastIoMdlWriteComplete Enter \n", 0);
  1044. pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
  1045. if ( IS_VALID_INDEX(pFastIoTable, MdlWriteComplete) ) {
  1046. fSuccess = pFastIoTable->MdlWriteComplete(
  1047. FileObject,
  1048. FileOffset,
  1049. MdlChain,
  1050. targetVdo);
  1051. } else {
  1052. fSuccess = FsRtlMdlWriteCompleteDev(
  1053. FileObject,
  1054. FileOffset,
  1055. MdlChain,
  1056. targetVdo);
  1057. }
  1058. DebugTrace(-1, Dbg, "DfsFastIoMdlWriteComplete Exit \n", 0);
  1059. return( fSuccess );
  1060. }
  1061. //
  1062. // If this routine is present, it will be called by FsRtl
  1063. // to acquire the file for the mapped page writer.
  1064. //
  1065. NTSTATUS
  1066. DfsFastIoAcquireForModWrite(
  1067. IN PFILE_OBJECT FileObject,
  1068. IN PLARGE_INTEGER EndingOffset,
  1069. OUT PERESOURCE *ResourceToRelease,
  1070. IN PDEVICE_OBJECT DeviceObject)
  1071. {
  1072. NTSTATUS Status;
  1073. PFAST_IO_DISPATCH pFastIoTable;
  1074. PDEVICE_OBJECT targetVdo;
  1075. DebugTrace(+1, Dbg, "DfsFastIoAcquireForModWrite Enter \n", 0);
  1076. pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
  1077. if ( IS_VALID_INDEX(pFastIoTable, AcquireForModWrite) ) {
  1078. Status = pFastIoTable->AcquireForModWrite(
  1079. FileObject,
  1080. EndingOffset,
  1081. ResourceToRelease,
  1082. targetVdo);
  1083. } else {
  1084. Status = STATUS_INVALID_DEVICE_REQUEST;
  1085. }
  1086. DebugTrace(-1, Dbg, "DfsFastIoAcquireForModWrite Exit \n", 0);
  1087. return( Status );
  1088. }
  1089. BOOLEAN
  1090. DfsFastIoReadCompressed(
  1091. IN PFILE_OBJECT FileObject,
  1092. IN PLARGE_INTEGER FileOffset,
  1093. IN ULONG Length,
  1094. IN ULONG LockKey,
  1095. OUT PVOID Buffer,
  1096. OUT PMDL *MdlChain,
  1097. OUT PIO_STATUS_BLOCK IoStatus,
  1098. OUT PCOMPRESSED_DATA_INFO CompressedDataInfo,
  1099. IN ULONG CompressedDataInfoLength,
  1100. IN PDEVICE_OBJECT DeviceObject)
  1101. {
  1102. PFAST_IO_DISPATCH pFastIoTable;
  1103. PDEVICE_OBJECT targetVdo;
  1104. BOOLEAN fPossible;
  1105. DebugTrace(+1, Dbg, "DfsFastIoReadCompressed Enter \n", 0);
  1106. pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
  1107. if ( IS_VALID_INDEX(pFastIoTable, FastIoReadCompressed) ) {
  1108. fPossible = pFastIoTable->FastIoReadCompressed(
  1109. FileObject,
  1110. FileOffset,
  1111. Length,
  1112. LockKey,
  1113. Buffer,
  1114. MdlChain,
  1115. IoStatus,
  1116. CompressedDataInfo,
  1117. CompressedDataInfoLength,
  1118. targetVdo);
  1119. } else {
  1120. fPossible = FALSE;
  1121. IoStatus->Status = STATUS_NOT_SUPPORTED;
  1122. }
  1123. DebugTrace(-1, Dbg, "DfsFastIoReadCompressed Exit \n", 0);
  1124. return( fPossible );
  1125. }
  1126. BOOLEAN
  1127. DfsFastIoWriteCompressed(
  1128. IN PFILE_OBJECT FileObject,
  1129. IN PLARGE_INTEGER FileOffset,
  1130. IN ULONG Length,
  1131. IN ULONG LockKey,
  1132. IN PVOID Buffer,
  1133. OUT PMDL *MdlChain,
  1134. OUT PIO_STATUS_BLOCK IoStatus,
  1135. IN PCOMPRESSED_DATA_INFO CompressedDataInfo,
  1136. IN ULONG CompressedDataInfoLength,
  1137. IN PDEVICE_OBJECT DeviceObject)
  1138. {
  1139. PFAST_IO_DISPATCH pFastIoTable;
  1140. PDEVICE_OBJECT targetVdo;
  1141. BOOLEAN fPossible;
  1142. DebugTrace(+1, Dbg, "DfsFastIoWriteCompressed Enter \n", 0);
  1143. pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
  1144. if ( IS_VALID_INDEX(pFastIoTable, FastIoWriteCompressed) ) {
  1145. fPossible = pFastIoTable->FastIoWriteCompressed(
  1146. FileObject,
  1147. FileOffset,
  1148. Length,
  1149. LockKey,
  1150. Buffer,
  1151. MdlChain,
  1152. IoStatus,
  1153. CompressedDataInfo,
  1154. CompressedDataInfoLength,
  1155. targetVdo);
  1156. } else {
  1157. fPossible = FALSE;
  1158. IoStatus->Status = STATUS_NOT_SUPPORTED;
  1159. }
  1160. DebugTrace(-1, Dbg, "DfsFastIoWriteCompressed Exit \n", 0);
  1161. return( fPossible );
  1162. }
  1163. BOOLEAN
  1164. DfsFastIoMdlReadCompleteCompressed(
  1165. IN PFILE_OBJECT FileObject,
  1166. IN PMDL MdlChain,
  1167. IN PDEVICE_OBJECT DeviceObject)
  1168. {
  1169. PFAST_IO_DISPATCH pFastIoTable;
  1170. PDEVICE_OBJECT targetVdo;
  1171. BOOLEAN fSuccess;
  1172. DebugTrace(+1, Dbg, "DfsFastIoMdlReadCompleteCompressed Enter \n", 0);
  1173. pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
  1174. if ( IS_VALID_INDEX(pFastIoTable, MdlReadCompleteCompressed) ) {
  1175. fSuccess = pFastIoTable->MdlReadCompleteCompressed(
  1176. FileObject,
  1177. MdlChain,
  1178. targetVdo);
  1179. } else {
  1180. fSuccess = FALSE;
  1181. }
  1182. DebugTrace(-1, Dbg, "DfsFastIoMdlReadCompleteCompressed Exit \n", 0);
  1183. return( fSuccess );
  1184. }
  1185. BOOLEAN
  1186. DfsFastIoMdlWriteCompleteCompressed(
  1187. IN PFILE_OBJECT FileObject,
  1188. IN PLARGE_INTEGER FileOffset,
  1189. IN PMDL MdlChain,
  1190. IN PDEVICE_OBJECT DeviceObject)
  1191. {
  1192. PFAST_IO_DISPATCH pFastIoTable;
  1193. PDEVICE_OBJECT targetVdo;
  1194. BOOLEAN fSuccess;
  1195. DebugTrace(+1, Dbg, "DfsFastIoMdlWriteCompleteCompressed Enter \n", 0);
  1196. pFastIoTable = DfsFastIoLookup(FileObject, DeviceObject, &targetVdo);
  1197. if ( IS_VALID_INDEX(pFastIoTable, MdlWriteCompleteCompressed) ) {
  1198. fSuccess = pFastIoTable->MdlWriteCompleteCompressed(
  1199. FileObject,
  1200. FileOffset,
  1201. MdlChain,
  1202. targetVdo);
  1203. } else {
  1204. fSuccess = FALSE;
  1205. }
  1206. DebugTrace(-1, Dbg, "DfsFastIoMdlWriteCompleteCompressed Exit \n", 0);
  1207. return( fSuccess );
  1208. }