fatio.c 17 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003
  1. /*++
  2. Copyright (c) 2012 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. fatio.c
  5. Abstract:
  6. This module implements the underlying device support for the FAT library
  7. when running as a kernel-mode driver.
  8. Author:
  9. Evan Green 25-Sep-2012
  10. Environment:
  11. Kernel
  12. --*/
  13. //
  14. // ------------------------------------------------------------------- Includes
  15. //
  16. #include <minoca/kernel/driver.h>
  17. #include <minoca/lib/fat/fat.h>
  18. //
  19. // ---------------------------------------------------------------- Definitions
  20. //
  21. //
  22. // ------------------------------------------------------ Data Type Definitions
  23. //
  24. /*++
  25. Structure Description:
  26. This structure stores information about a block device backing a FAT file
  27. system.
  28. Members:
  29. BlockDevice - Stores the block device parameters for the device.
  30. --*/
  31. typedef struct _FAT_DEVICE {
  32. BLOCK_DEVICE_PARAMETERS BlockDevice;
  33. } FAT_DEVICE, *PFAT_DEVICE;
  34. //
  35. // ----------------------------------------------- Internal Function Prototypes
  36. //
  37. //
  38. // -------------------------------------------------------------------- Globals
  39. //
  40. //
  41. // ------------------------------------------------------------------ Functions
  42. //
  43. PFAT_IO_BUFFER
  44. FatAllocateIoBuffer (
  45. PVOID DeviceToken,
  46. UINTN Size
  47. )
  48. /*++
  49. Routine Description:
  50. This routine allocates memory for device I/O use.
  51. Arguments:
  52. DeviceToken - Supplies an opaque token identifying the underlying device.
  53. Size - Supplies the size of the required allocation, in bytes.
  54. Return Value:
  55. Returns a pointer to the FAT I/O buffer, or NULL on failure.
  56. --*/
  57. {
  58. PIO_BUFFER IoBuffer;
  59. IoBuffer = MmAllocateUninitializedIoBuffer(Size, 0);
  60. return (PFAT_IO_BUFFER)IoBuffer;
  61. }
  62. PFAT_IO_BUFFER
  63. FatCreateIoBuffer (
  64. PVOID Buffer,
  65. UINTN Size
  66. )
  67. /*++
  68. Routine Description:
  69. This routine creates a FAT I/O buffer from the given buffer.
  70. Arguments:
  71. Buffer - Supplies a pointer to the memory buffer on which to base the FAT
  72. I/O buffer.
  73. Size - Supplies the size of the memory buffer, in bytes.
  74. Return Value:
  75. Returns an pointer to the FAT I/O buffer, or NULL on failure.
  76. --*/
  77. {
  78. PIO_BUFFER IoBuffer;
  79. KSTATUS Status;
  80. Status = MmCreateIoBuffer(Buffer,
  81. Size,
  82. IO_BUFFER_FLAG_KERNEL_MODE_DATA,
  83. &IoBuffer);
  84. if (!KSUCCESS(Status)) {
  85. return NULL;
  86. }
  87. return (PFAT_IO_BUFFER)IoBuffer;
  88. }
  89. VOID
  90. FatIoBufferUpdateOffset (
  91. PFAT_IO_BUFFER FatIoBuffer,
  92. UINTN OffsetUpdate,
  93. BOOL Decrement
  94. )
  95. /*++
  96. Routine Description:
  97. This routine increments the given FAT I/O buffer's current offset by the
  98. given amount.
  99. Arguments:
  100. FatIoBuffer - Supplies a pointer to a FAT I/O buffer.
  101. OffsetUpdate - Supplies the number of bytes by which the offset will be
  102. updated.
  103. Decrement - Supplies a boolean indicating whether the update will be a
  104. decrement (TRUE) or an increment (FALSE).
  105. Return Value:
  106. None.
  107. --*/
  108. {
  109. if (Decrement == FALSE) {
  110. MmIoBufferIncrementOffset((PIO_BUFFER)FatIoBuffer, OffsetUpdate);
  111. } else {
  112. MmIoBufferDecrementOffset((PIO_BUFFER)FatIoBuffer, OffsetUpdate);
  113. }
  114. return;
  115. }
  116. VOID
  117. FatIoBufferSetOffset (
  118. PFAT_IO_BUFFER FatIoBuffer,
  119. UINTN Offset
  120. )
  121. /*++
  122. Routine Description:
  123. This routine sets the given FAT I/O buffer's current offset.
  124. Arguments:
  125. FatIoBuffer - Supplies a pointer to a FAT I/O buffer.
  126. Offset - Supplies the new offset to set.
  127. Return Value:
  128. None.
  129. --*/
  130. {
  131. MmSetIoBufferCurrentOffset((PIO_BUFFER)FatIoBuffer, Offset);
  132. return;
  133. }
  134. KSTATUS
  135. FatZeroIoBuffer (
  136. PFAT_IO_BUFFER FatIoBuffer,
  137. UINTN Offset,
  138. UINTN ByteCount
  139. )
  140. /*++
  141. Routine Description:
  142. This routine zeros the contents of the FAT I/O buffer starting at the
  143. offset for the given number of bytes.
  144. Arguments:
  145. FatIoBuffer - Supplies a pointer to the FAT I/O buffer that is to be zeroed.
  146. Offset - Supplies the offset within the I/O buffer where the zeroing should
  147. begin.
  148. ByteCount - Supplies the number of bytes to zero.
  149. Return Value:
  150. Status code.
  151. --*/
  152. {
  153. return MmZeroIoBuffer((PIO_BUFFER)FatIoBuffer, Offset, ByteCount);
  154. }
  155. KSTATUS
  156. FatCopyIoBuffer (
  157. PFAT_IO_BUFFER Destination,
  158. UINTN DestinationOffset,
  159. PFAT_IO_BUFFER Source,
  160. UINTN SourceOffset,
  161. UINTN ByteCount
  162. )
  163. /*++
  164. Routine Description:
  165. This routine copies the contents of the source I/O buffer starting at the
  166. source offset to the destination I/O buffer starting at the destination
  167. offset. It assumes that the arguments are correct such that the copy can
  168. succeed.
  169. Arguments:
  170. Destination - Supplies a pointer to the destination I/O buffer that is to
  171. be copied into.
  172. DestinationOffset - Supplies the offset into the destination I/O buffer
  173. where the copy should begin.
  174. Source - Supplies a pointer to the source I/O buffer whose contents will be
  175. copied to the destination.
  176. SourceOffset - Supplies the offset into the source I/O buffer where the
  177. copy should begin.
  178. ByteCount - Supplies the size of the requested copy in bytes.
  179. Return Value:
  180. Status code.
  181. --*/
  182. {
  183. KSTATUS Status;
  184. Status = MmCopyIoBuffer((PIO_BUFFER)Destination,
  185. DestinationOffset,
  186. (PIO_BUFFER)Source,
  187. SourceOffset,
  188. ByteCount);
  189. return Status;
  190. }
  191. KSTATUS
  192. FatCopyIoBufferData (
  193. PFAT_IO_BUFFER FatIoBuffer,
  194. PVOID Buffer,
  195. UINTN Offset,
  196. UINTN Size,
  197. BOOL ToIoBuffer
  198. )
  199. /*++
  200. Routine Description:
  201. This routine copies from a buffer into the given I/O buffer or out of the
  202. given I/O buffer.
  203. Arguments:
  204. FatIoBuffer - Supplies a pointer to the FAT I/O buffer to copy in or out of.
  205. Buffer - Supplies a pointer to the regular linear buffer to copy to or from.
  206. Offset - Supplies an offset in bytes from the beginning of the I/O buffer
  207. to copy to or from.
  208. Size - Supplies the number of bytes to copy.
  209. ToIoBuffer - Supplies a boolean indicating whether data is copied into the
  210. I/O buffer (TRUE) or out of the I/O buffer (FALSE).
  211. Return Value:
  212. Status code.
  213. --*/
  214. {
  215. KSTATUS Status;
  216. Status = MmCopyIoBufferData((PIO_BUFFER)FatIoBuffer,
  217. Buffer,
  218. Offset,
  219. Size,
  220. ToIoBuffer);
  221. return Status;
  222. }
  223. PVOID
  224. FatMapIoBuffer (
  225. PFAT_IO_BUFFER FatIoBuffer
  226. )
  227. /*++
  228. Routine Description:
  229. This routine maps the given FAT I/O buffer and returns the base of the
  230. virtually contiguous mapping.
  231. Arguments:
  232. FatIoBuffer - Supplies a pointer to a FAT I/O buffer.
  233. Return Value:
  234. Returns a pointer to the virtual address of the mapping on success, or
  235. NULL on failure.
  236. --*/
  237. {
  238. PIO_BUFFER IoBuffer;
  239. KSTATUS Status;
  240. IoBuffer = (PFAT_IO_BUFFER)FatIoBuffer;
  241. Status = MmMapIoBuffer(IoBuffer, FALSE, FALSE, TRUE);
  242. if (!KSUCCESS(Status)) {
  243. return NULL;
  244. }
  245. return IoBuffer->Fragment[0].VirtualAddress;
  246. }
  247. VOID
  248. FatFreeIoBuffer (
  249. PFAT_IO_BUFFER FatIoBuffer
  250. )
  251. /*++
  252. Routine Description:
  253. This routine frees a FAT I/O buffer.
  254. Arguments:
  255. FatIoBuffer - Supplies a pointer to a FAT I/O buffer.
  256. Return Value:
  257. None.
  258. --*/
  259. {
  260. MmFreeIoBuffer((PIO_BUFFER)FatIoBuffer);
  261. return;
  262. }
  263. PVOID
  264. FatAllocatePagedMemory (
  265. PVOID DeviceToken,
  266. ULONG SizeInBytes
  267. )
  268. /*++
  269. Routine Description:
  270. This routine allocates paged memory for the FAT library.
  271. Arguments:
  272. DeviceToken - Supplies an opaque token identifying the underlying device.
  273. SizeInBytes - Supplies the number of bytes to allocate.
  274. Return Value:
  275. Returns a pointer to the allocated memory, or NULL on failure.
  276. --*/
  277. {
  278. return MmAllocatePagedPool(SizeInBytes, FAT_ALLOCATION_TAG);
  279. }
  280. PVOID
  281. FatAllocateNonPagedMemory (
  282. PVOID DeviceToken,
  283. ULONG SizeInBytes
  284. )
  285. /*++
  286. Routine Description:
  287. This routine allocates non-paged memory for the FAT library.
  288. Arguments:
  289. DeviceToken - Supplies an opaque token identifying the underlying device.
  290. SizeInBytes - Supplies the number of bytes to allocate.
  291. Return Value:
  292. Returns a pointer to the allocated memory, or NULL on failure.
  293. --*/
  294. {
  295. return MmAllocateNonPagedPool(SizeInBytes, FAT_ALLOCATION_TAG);
  296. }
  297. VOID
  298. FatFreePagedMemory (
  299. PVOID DeviceToken,
  300. PVOID Allocation
  301. )
  302. /*++
  303. Routine Description:
  304. This routine frees paged memory for the FAT library.
  305. Arguments:
  306. DeviceToken - Supplies an opaque token identifying the underlying device.
  307. Allocation - Supplies a pointer to the allocation to free.
  308. Return Value:
  309. None.
  310. --*/
  311. {
  312. MmFreePagedPool(Allocation);
  313. return;
  314. }
  315. VOID
  316. FatFreeNonPagedMemory (
  317. PVOID DeviceToken,
  318. PVOID Allocation
  319. )
  320. /*++
  321. Routine Description:
  322. This routine frees memory for the FAT library.
  323. Arguments:
  324. DeviceToken - Supplies an opaque token identifying the underlying device.
  325. Allocation - Supplies a pointer to the allocation to free.
  326. Return Value:
  327. None.
  328. --*/
  329. {
  330. MmFreeNonPagedPool(Allocation);
  331. return;
  332. }
  333. KSTATUS
  334. FatCreateLock (
  335. PVOID *Lock
  336. )
  337. /*++
  338. Routine Description:
  339. This routine creates a lock.
  340. Arguments:
  341. Lock - Supplies a pointer where an opaque pointer will be returned
  342. representing the lock.
  343. Return Value:
  344. STATUS_SUCCESS on success.
  345. STATUS_INSUFFICIENT_RESOURCES if the lock could not be allocated.
  346. --*/
  347. {
  348. PQUEUED_LOCK NewLock;
  349. NewLock = KeCreateQueuedLock();
  350. if (NewLock == NULL) {
  351. return STATUS_INSUFFICIENT_RESOURCES;
  352. }
  353. *Lock = NewLock;
  354. return STATUS_SUCCESS;
  355. }
  356. VOID
  357. FatDestroyLock (
  358. PVOID Lock
  359. )
  360. /*++
  361. Routine Description:
  362. This routine destroys a created lock.
  363. Arguments:
  364. Lock - Supplies a the opaque pointer returned upon creation.
  365. Return Value:
  366. None.
  367. --*/
  368. {
  369. KeDestroyQueuedLock(Lock);
  370. return;
  371. }
  372. VOID
  373. FatAcquireLock (
  374. PVOID Lock
  375. )
  376. /*++
  377. Routine Description:
  378. This routine acquires a lock.
  379. Arguments:
  380. Lock - Supplies a the opaque pointer returned upon creation.
  381. Return Value:
  382. None.
  383. --*/
  384. {
  385. KeAcquireQueuedLock(Lock);
  386. return;
  387. }
  388. VOID
  389. FatReleaseLock (
  390. PVOID Lock
  391. )
  392. /*++
  393. Routine Description:
  394. This routine releases a lock.
  395. Arguments:
  396. Lock - Supplies a the opaque pointer returned upon creation.
  397. Return Value:
  398. None.
  399. --*/
  400. {
  401. KeReleaseQueuedLock(Lock);
  402. return;
  403. }
  404. KSTATUS
  405. FatOpenDevice (
  406. PBLOCK_DEVICE_PARAMETERS BlockParameters
  407. )
  408. /*++
  409. Routine Description:
  410. This routine opens the underlying device that the FAT file system reads
  411. and writes blocks to.
  412. Arguments:
  413. BlockParameters - Supplies the initial block device parameters for the
  414. device. These parameters may be modified by this call.
  415. Return Value:
  416. STATUS_SUCCESS on success.
  417. STATUS_INSUFFICIENT_RESOURCES if there were not enough resources to open
  418. the device.
  419. --*/
  420. {
  421. PFAT_DEVICE FatDevice;
  422. FatDevice = MmAllocateNonPagedPool(sizeof(FAT_DEVICE), FAT_ALLOCATION_TAG);
  423. if (FatDevice == NULL) {
  424. return STATUS_INSUFFICIENT_RESOURCES;
  425. }
  426. FatDevice->BlockDevice = *BlockParameters;
  427. //
  428. // Overwrite the device token so this layer gets this pointer.
  429. //
  430. BlockParameters->DeviceToken = FatDevice;
  431. return STATUS_SUCCESS;
  432. }
  433. VOID
  434. FatCloseDevice (
  435. PVOID DeviceToken
  436. )
  437. /*++
  438. Routine Description:
  439. This routine closes the device backing the FAT file system.
  440. Arguments:
  441. DeviceToken - Supplies a pointer to the device token returned upon opening
  442. the underlying device.
  443. Return Value:
  444. None.
  445. --*/
  446. {
  447. MmFreeNonPagedPool(DeviceToken);
  448. return;
  449. }
  450. KSTATUS
  451. FatReadDevice (
  452. PVOID DeviceToken,
  453. ULONGLONG BlockAddress,
  454. UINTN BlockCount,
  455. ULONG Flags,
  456. PVOID Irp,
  457. PFAT_IO_BUFFER FatIoBuffer
  458. )
  459. /*++
  460. Routine Description:
  461. This routine reads data from the underlying disk.
  462. Arguments:
  463. DeviceToken - Supplies an opaque token identifying the underlying device.
  464. BlockAddress - Supplies the block index to read (for physical disks, this is
  465. the LBA).
  466. BlockCount - Supplies the number of blocks to read.
  467. Flags - Supplies flags regarding the I/O operation. See IO_FLAG_*
  468. definitions.
  469. Irp - Supplies an optional pointer to the IRP to pass to the read file
  470. function.
  471. FatIoBuffer - Supplies a pointer to a FAT I/O buffer where the data from
  472. the disk will be returned.
  473. Return Value:
  474. Status code.
  475. --*/
  476. {
  477. ULONG BlockSize;
  478. UINTN BytesCompleted;
  479. PFAT_DEVICE FatDevice;
  480. PIO_BUFFER IoBuffer;
  481. UINTN SizeInBytes;
  482. KSTATUS Status;
  483. IoBuffer = (PIO_BUFFER)FatIoBuffer;
  484. FatDevice = (PFAT_DEVICE)DeviceToken;
  485. BlockSize = FatDevice->BlockDevice.BlockSize;
  486. SizeInBytes = BlockCount * BlockSize;
  487. ASSERT(IoBuffer != NULL);
  488. Status = IoReadAtOffset(FatDevice->BlockDevice.DeviceToken,
  489. IoBuffer,
  490. BlockAddress * BlockSize,
  491. SizeInBytes,
  492. Flags,
  493. WAIT_TIME_INDEFINITE,
  494. &BytesCompleted,
  495. Irp);
  496. if (!KSUCCESS(Status)) {
  497. goto ReadDeviceEnd;
  498. }
  499. if (BytesCompleted != SizeInBytes) {
  500. ASSERT(FALSE);
  501. Status = STATUS_DATA_LENGTH_MISMATCH;
  502. goto ReadDeviceEnd;
  503. }
  504. ReadDeviceEnd:
  505. return Status;
  506. }
  507. KSTATUS
  508. FatWriteDevice (
  509. PVOID DeviceToken,
  510. ULONGLONG BlockAddress,
  511. UINTN BlockCount,
  512. ULONG Flags,
  513. PVOID Irp,
  514. PFAT_IO_BUFFER FatIoBuffer
  515. )
  516. /*++
  517. Routine Description:
  518. This routine writes data to the underlying disk.
  519. Arguments:
  520. DeviceToken - Supplies an opaque token identifying the underlying device.
  521. BlockAddress - Supplies the block index to write to (for physical disks,
  522. this is the LBA).
  523. BlockCount - Supplies the number of blocks to write.
  524. Flags - Supplies flags regarding the I/O operation. See IO_FLAG_*
  525. definitions.
  526. Irp - Supplies an optional pointer to an IRP to use for the disk operation.
  527. FatIoBuffer - Supplies a pointer to a FAT I/O buffer containing the data to
  528. write.
  529. Return Value:
  530. Status code.
  531. --*/
  532. {
  533. ULONG BlockSize;
  534. UINTN BytesCompleted;
  535. PFAT_DEVICE FatDevice;
  536. KSTATUS Status;
  537. FatDevice = (PFAT_DEVICE)DeviceToken;
  538. BlockSize = FatDevice->BlockDevice.BlockSize;
  539. Status = IoWriteAtOffset(FatDevice->BlockDevice.DeviceToken,
  540. (PIO_BUFFER)FatIoBuffer,
  541. BlockAddress * BlockSize,
  542. BlockCount * BlockSize,
  543. Flags,
  544. WAIT_TIME_INDEFINITE,
  545. &BytesCompleted,
  546. Irp);
  547. if (!KSUCCESS(Status)) {
  548. goto WriteDeviceEnd;
  549. }
  550. if (BytesCompleted != (BlockCount * BlockSize)) {
  551. ASSERT(FALSE);
  552. Status = STATUS_DATA_LENGTH_MISMATCH;
  553. goto WriteDeviceEnd;
  554. }
  555. WriteDeviceEnd:
  556. return Status;
  557. }
  558. KSTATUS
  559. FatGetDeviceBlockInformation (
  560. PVOID DeviceToken,
  561. PFILE_BLOCK_INFORMATION BlockInformation
  562. )
  563. /*++
  564. Routine Description:
  565. This routine converts a file's block information into disk level block
  566. information by modifying the offsets of each contiguous run.
  567. Arguments:
  568. DeviceToken - Supplies an opaque token identify the underlying device.
  569. BlockInformation - Supplies a pointer to the block information to be
  570. updated.
  571. Return Value:
  572. Status code.
  573. --*/
  574. {
  575. PFAT_DEVICE FatDevice;
  576. KSTATUS Status;
  577. ASSERT(BlockInformation != NULL);
  578. FatDevice = (PFAT_DEVICE)DeviceToken;
  579. Status = IoGetFileBlockInformation(FatDevice->BlockDevice.DeviceToken,
  580. &BlockInformation);
  581. return Status;
  582. }
  583. ULONG
  584. FatGetIoCacheEntryDataSize (
  585. VOID
  586. )
  587. /*++
  588. Routine Description:
  589. This routine returns the size of data stored in each cache entry.
  590. Arguments:
  591. None.
  592. Return Value:
  593. Returns the size of the data stored in each cache entry, or 0 if there is
  594. no cache.
  595. --*/
  596. {
  597. return IoGetCacheEntryDataSize();
  598. }
  599. ULONG
  600. FatGetPageSize (
  601. VOID
  602. )
  603. /*++
  604. Routine Description:
  605. This routine returns the size of a physical memory page for the current FAT
  606. environment.
  607. Arguments:
  608. None.
  609. Return Value:
  610. Returns the size of a page in the current environment. Returns 0 if the
  611. size is not known.
  612. --*/
  613. {
  614. return MmPageSize();
  615. }
  616. VOID
  617. FatGetCurrentSystemTime (
  618. PSYSTEM_TIME SystemTime
  619. )
  620. /*++
  621. Routine Description:
  622. This routine returns the current system time.
  623. Arguments:
  624. SystemTime - Supplies a pointer where the current system time will be
  625. returned.
  626. Return Value:
  627. None.
  628. --*/
  629. {
  630. KeGetSystemTime(SystemTime);
  631. return;
  632. }
  633. //
  634. // --------------------------------------------------------- Internal Functions
  635. //