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.

1209 lines
17 KiB

  1. /*++
  2. Copyright (c) 1990-2001 Microsoft Corporation
  3. Module Name:
  4. fatdent.hxx
  5. Abstract:
  6. This class models a FAT directory entry.
  7. Author:
  8. Norbert P. Kusters (norbertk) 4-Dec-90
  9. --*/
  10. #ifndef MAKEULONG
  11. #define MAKEULONG(a, b) ((ULONG)(((USHORT)(a)) | ((ULONG)((USHORT)(b))) << 16))
  12. #define LOUSHORT(l) ((USHORT)(l & 0xFFFF))
  13. #define HIUSHORT(l) ((USHORT)(((l) >> 16) & 0xFFFF))
  14. #endif // !MAKEULONG
  15. #if !defined(FAT_DIRENT_DEFN)
  16. #define FAT_DIRENT_DEFN
  17. #if defined ( _AUTOCHECK_ )
  18. #define UFAT_EXPORT
  19. #elif defined ( _UFAT_MEMBER_ )
  20. #define UFAT_EXPORT __declspec(dllexport)
  21. #else
  22. #define UFAT_EXPORT __declspec(dllimport)
  23. #endif
  24. DECLARE_CLASS( FAT_DIRENT );
  25. DECLARE_CLASS( WSTRING );
  26. DECLARE_CLASS( WSTRING );
  27. DECLARE_CLASS( TIMEINFO );
  28. typedef struct _SHORT_FAT_DIRENT {
  29. UCHAR Name[11];
  30. UCHAR Attributes[1];
  31. UCHAR NtByte[1];
  32. UCHAR CreationMSec[1]; // actually count of 10msec's
  33. UCHAR CreationTime[2]; // two-second resolution
  34. UCHAR CreationDate[2];
  35. UCHAR LastAccessDate[2];
  36. UCHAR EaHandle[2];
  37. UCHAR LastWriteTime[2];
  38. UCHAR LastWriteDate[2];
  39. UCHAR FirstCluster[2];
  40. UCHAR Size[4];
  41. };
  42. DEFINE_TYPE( _SHORT_FAT_DIRENT, SHORT_FAT_DIRENT );
  43. typedef struct _LONG_FAT_DIRENT {
  44. UCHAR Ordinal[1];
  45. UCHAR Name1[10];
  46. UCHAR Attribute[1];
  47. UCHAR Type[1];
  48. UCHAR Checksum[1];
  49. UCHAR Name2[12];
  50. UCHAR FirstCluster[2];
  51. UCHAR Name3[4];
  52. };
  53. DEFINE_TYPE( _LONG_FAT_DIRENT, LONG_FAT_DIRENT );
  54. #define LONG_DIRENT_TYPE_NAME 0
  55. #define LONG_DIRENT_TYPE_CLASS 1
  56. class FAT_DIRENT : public OBJECT {
  57. public:
  58. UFAT_EXPORT
  59. DECLARE_CONSTRUCTOR( FAT_DIRENT );
  60. VIRTUAL
  61. UFAT_EXPORT
  62. ~FAT_DIRENT(
  63. );
  64. NONVIRTUAL
  65. UFAT_EXPORT
  66. BOOLEAN
  67. Initialize(
  68. IN OUT PVOID Dirent
  69. );
  70. NONVIRTUAL
  71. UFAT_EXPORT
  72. BOOLEAN
  73. Initialize(
  74. IN OUT PVOID Dirent,
  75. IN UCHAR FatType
  76. );
  77. NONVIRTUAL
  78. VOID
  79. Clear(
  80. );
  81. NONVIRTUAL
  82. UFAT_EXPORT
  83. BOOLEAN
  84. QueryName(
  85. OUT PWSTRING Name
  86. ) CONST;
  87. NONVIRTUAL
  88. BOOLEAN
  89. SetName(
  90. IN PCWSTRING Name
  91. );
  92. NONVIRTUAL
  93. BOOLEAN
  94. IsValidName(
  95. ) CONST;
  96. NONVIRTUAL
  97. BOOLEAN
  98. IsDot(
  99. ) CONST;
  100. NONVIRTUAL
  101. BOOLEAN
  102. IsDotDot(
  103. ) CONST;
  104. NONVIRTUAL
  105. BYTE
  106. QueryAttributeByte(
  107. ) CONST;
  108. NONVIRTUAL
  109. UFAT_EXPORT
  110. BOOLEAN
  111. IsValidLastWriteTime(
  112. ) CONST;
  113. NONVIRTUAL
  114. UFAT_EXPORT
  115. BOOLEAN
  116. QueryLastWriteTime(
  117. OUT LARGE_INTEGER *TimeStamp
  118. ) CONST;
  119. NONVIRTUAL
  120. BOOLEAN
  121. SetLastWriteTime(
  122. );
  123. NONVIRTUAL
  124. UFAT_EXPORT
  125. BOOLEAN
  126. IsValidCreationTime(
  127. ) CONST;
  128. NONVIRTUAL
  129. UFAT_EXPORT
  130. BOOLEAN
  131. QueryCreationTime(
  132. OUT LARGE_INTEGER *TimeStamp
  133. ) CONST;
  134. NONVIRTUAL
  135. BOOLEAN
  136. SetCreationTime(
  137. );
  138. NONVIRTUAL
  139. UFAT_EXPORT
  140. BOOLEAN
  141. IsValidLastAccessTime(
  142. ) CONST;
  143. NONVIRTUAL
  144. UFAT_EXPORT
  145. BOOLEAN
  146. QueryLastAccessTime(
  147. OUT LARGE_INTEGER *TimeStamp
  148. ) CONST;
  149. NONVIRTUAL
  150. BOOLEAN
  151. SetLastAccessTime(
  152. );
  153. NONVIRTUAL
  154. ULONG
  155. QueryStartingCluster(
  156. ) CONST;
  157. NONVIRTUAL
  158. VOID
  159. SetStartingCluster(
  160. IN ULONG NewStartingCluster
  161. );
  162. NONVIRTUAL
  163. ULONG
  164. QueryFileSize(
  165. ) CONST;
  166. NONVIRTUAL
  167. VOID
  168. SetFileSize(
  169. IN ULONG NewFileSize
  170. );
  171. NONVIRTUAL
  172. USHORT
  173. QueryEaHandle(
  174. ) CONST;
  175. NONVIRTUAL
  176. VOID
  177. SetEaHandle(
  178. IN USHORT NewHandle
  179. );
  180. NONVIRTUAL
  181. BOOLEAN
  182. IsEndOfDirectory(
  183. ) CONST;
  184. NONVIRTUAL
  185. VOID
  186. SetEndOfDirectory(
  187. );
  188. NONVIRTUAL
  189. BOOLEAN
  190. IsErased(
  191. ) CONST;
  192. NONVIRTUAL
  193. VOID
  194. SetErased(
  195. );
  196. NONVIRTUAL
  197. BOOLEAN
  198. IsHidden(
  199. ) CONST;
  200. NONVIRTUAL
  201. VOID
  202. SetHidden(
  203. );
  204. NONVIRTUAL
  205. BOOLEAN
  206. IsReadOnly(
  207. ) CONST;
  208. NONVIRTUAL
  209. VOID
  210. SetReadOnly(
  211. );
  212. NONVIRTUAL
  213. BOOLEAN
  214. IsSystem(
  215. ) CONST;
  216. NONVIRTUAL
  217. VOID
  218. SetSystem(
  219. );
  220. NONVIRTUAL
  221. BOOLEAN
  222. IsVolumeLabel(
  223. ) CONST;
  224. NONVIRTUAL
  225. VOID
  226. SetVolumeLabel(
  227. );
  228. NONVIRTUAL
  229. BOOLEAN
  230. IsDirectory(
  231. ) CONST;
  232. NONVIRTUAL
  233. VOID
  234. SetDirectory(
  235. );
  236. NONVIRTUAL
  237. VOID
  238. ResetDirectory(
  239. );
  240. NONVIRTUAL
  241. UCHAR
  242. QueryChecksum(
  243. ) CONST;
  244. NONVIRTUAL
  245. BOOLEAN
  246. Is8LowerCase(
  247. ) CONST;
  248. NONVIRTUAL
  249. BOOLEAN
  250. Is3LowerCase(
  251. ) CONST;
  252. NONVIRTUAL
  253. BOOLEAN
  254. IsLongEntry(
  255. ) CONST;
  256. NONVIRTUAL
  257. BOOLEAN
  258. IsLongNameEntry(
  259. ) CONST;
  260. NONVIRTUAL
  261. BOOLEAN
  262. QueryLongOrdinal(
  263. ) CONST;
  264. NONVIRTUAL
  265. BOOLEAN
  266. IsLastLongEntry(
  267. ) CONST;
  268. NONVIRTUAL
  269. BOOLEAN
  270. IsWellTerminatedLongNameEntry(
  271. ) CONST;
  272. NONVIRTUAL
  273. BOOLEAN
  274. QueryLongNameComponent(
  275. OUT PWSTRING NameComponent
  276. ) CONST;
  277. NONVIRTUAL
  278. BOOLEAN
  279. NameHasTilde(
  280. ) CONST;
  281. NONVIRTUAL
  282. BOOLEAN
  283. NameHasExtendedChars(
  284. ) CONST;
  285. STATIC
  286. BOOLEAN
  287. IsValidLongName(
  288. IN PWSTRING LongName
  289. );
  290. private:
  291. NONVIRTUAL
  292. BOOLEAN
  293. TimeStampsAreValid(
  294. USHORT t,
  295. USHORT d
  296. ) CONST;
  297. NONVIRTUAL
  298. VOID
  299. Construct(
  300. );
  301. NONVIRTUAL
  302. VOID
  303. Destroy(
  304. );
  305. PUCHAR _dirent;
  306. UCHAR _FatType;
  307. };
  308. INLINE
  309. VOID
  310. FAT_DIRENT::Clear(
  311. )
  312. /*++
  313. Routine Description:
  314. This routine zeros out the directory entry.
  315. Arguments:
  316. None.
  317. Return Value:
  318. None.
  319. --*/
  320. {
  321. memset(_dirent, 0, 32);
  322. }
  323. INLINE
  324. BOOLEAN
  325. FAT_DIRENT::IsDot(
  326. ) CONST
  327. /*++
  328. Routine Description:
  329. This routine computes whether or not the directory entry is the "."
  330. entry.
  331. Arguments:
  332. None.
  333. Return Value:
  334. FALSE - The entry is not the "." entry.
  335. TRUE - The entry is the "." entry.
  336. --*/
  337. {
  338. return !memcmp(_dirent, ". ", 11);
  339. }
  340. INLINE
  341. BOOLEAN
  342. FAT_DIRENT::IsDotDot(
  343. ) CONST
  344. /*++
  345. Routine Description:
  346. This routine computes whether or not the directory entry is the ".."
  347. entry.
  348. Arguments:
  349. None.
  350. Return Value:
  351. FALSE - The entry is not the ".." entry.
  352. TRUE - The entry is the ".." entry.
  353. --*/
  354. {
  355. return !memcmp(_dirent, ".. ", 11);
  356. }
  357. INLINE
  358. ULONG
  359. FAT_DIRENT::QueryStartingCluster(
  360. ) CONST
  361. /*++
  362. Routine Description:
  363. This routine computes the starting cluster number of the directory entry.
  364. Arguments:
  365. None.
  366. Return Value:
  367. The starting cluster number of the directory entry.
  368. --*/
  369. {
  370. DebugAssert(_dirent);
  371. ULONG dwSCN;
  372. if ( FAT_TYPE_FAT32 == _FatType )
  373. dwSCN = MAKEULONG( (*((PUSHORT) &_dirent[26])), (*((PUSHORT) &_dirent[20])));
  374. else
  375. dwSCN = *((PUSHORT) &_dirent[26]);
  376. return dwSCN;
  377. }
  378. INLINE
  379. VOID
  380. FAT_DIRENT::SetStartingCluster(
  381. IN ULONG NewStartingCluster
  382. )
  383. /*++
  384. Routine Description:
  385. This routine sets the starting cluster number for the directory entry.
  386. Arguments:
  387. NewStartingCluster - Supplies the starting cluster number for the
  388. directory entry.
  389. Return Value:
  390. None.
  391. --*/
  392. {
  393. DebugAssert(_dirent);
  394. if ( FAT_TYPE_FAT32 == _FatType )
  395. *((PUSHORT) &_dirent[20]) = HIUSHORT( NewStartingCluster );
  396. *((PUSHORT) &_dirent[26]) = LOUSHORT( NewStartingCluster );
  397. }
  398. INLINE
  399. ULONG
  400. FAT_DIRENT::QueryFileSize(
  401. ) CONST
  402. /*++
  403. Routine Description:
  404. This routine returns the number of bytes in the file.
  405. Arguments:
  406. None.
  407. Return Value:
  408. The number of bytes in the file.
  409. --*/
  410. {
  411. DebugAssert(_dirent);
  412. return *((PULONG) &_dirent[28]);
  413. }
  414. INLINE
  415. VOID
  416. FAT_DIRENT::SetFileSize(
  417. IN ULONG NewFileSize
  418. )
  419. /*++
  420. Routine Description:
  421. This routine sets the file size in the directory entry.
  422. Arguments:
  423. NewFileSize - Supplies the new file size.
  424. Return Value:
  425. None.
  426. --*/
  427. {
  428. DebugAssert(_dirent);
  429. *((PULONG) &_dirent[28]) = NewFileSize;
  430. }
  431. INLINE
  432. USHORT
  433. FAT_DIRENT::QueryEaHandle(
  434. ) CONST
  435. /*++
  436. Routine Description:
  437. This routine returns the EA handle for the file.
  438. Arguments:
  439. None.
  440. Return Value:
  441. The EA handle for the file.
  442. --*/
  443. {
  444. DebugAssert(_dirent);
  445. if ( FAT_TYPE_FAT32 == _FatType )
  446. return ( 0 );
  447. else
  448. return *((PUSHORT) &_dirent[20]);
  449. }
  450. INLINE
  451. VOID
  452. FAT_DIRENT::SetEaHandle(
  453. IN USHORT NewHandle
  454. )
  455. /*++
  456. Routine Description:
  457. This routine sets the EA handle for the file.
  458. Arguments:
  459. NewHandle - Supplies the EA handle for the file.
  460. Return Value:
  461. None.
  462. --*/
  463. {
  464. DebugAssert(_dirent);
  465. *((PUSHORT) &_dirent[20]) = NewHandle;
  466. }
  467. INLINE
  468. BOOLEAN
  469. FAT_DIRENT::IsEndOfDirectory(
  470. ) CONST
  471. /*++
  472. Routine Description:
  473. This routine computes whether or not this directory entry marks
  474. the end of the directory.
  475. Arguments:
  476. None.
  477. Return Value:
  478. FALSE - This entry does not mark the end of the directory.
  479. TRUE - This entry marks the end of the directory.
  480. --*/
  481. {
  482. DebugAssert(_dirent);
  483. return _dirent[0] ? FALSE : TRUE;
  484. }
  485. INLINE
  486. VOID
  487. FAT_DIRENT::SetEndOfDirectory(
  488. )
  489. /*++
  490. Routine Description:
  491. This routine sets this directory entry marks to the end of the
  492. directory.
  493. Arguments:
  494. None.
  495. Return Value:
  496. None.
  497. --*/
  498. {
  499. DebugAssert(_dirent);
  500. _dirent[0] = 0;
  501. }
  502. INLINE
  503. BOOLEAN
  504. FAT_DIRENT::IsErased(
  505. ) CONST
  506. /*++
  507. Routine Description:
  508. This routine computes whether or not the directory entry is erased or not.
  509. Arguments:
  510. None.
  511. Return Value:
  512. FALSE - The directory entry is not erased.
  513. TRUE - The directory entry is erased.
  514. --*/
  515. {
  516. DebugAssert(_dirent);
  517. return _dirent[0] == 0xE5 ? TRUE : FALSE;
  518. }
  519. INLINE
  520. VOID
  521. FAT_DIRENT::SetErased(
  522. )
  523. /*++
  524. Routine Description:
  525. This routine marks the directory entry as erased.
  526. Arguments:
  527. None.
  528. Return Value:
  529. None.
  530. --*/
  531. {
  532. DebugAssert(_dirent);
  533. _dirent[0] = 0xE5;
  534. }
  535. INLINE
  536. BOOLEAN
  537. FAT_DIRENT::IsHidden(
  538. ) CONST
  539. /*++
  540. Routine Description:
  541. This routine computes whether or not the file is hidden.
  542. Arguments:
  543. None.
  544. Return Value:
  545. FALSE - The file is not hidden.
  546. TRUE - The file is hidden.
  547. --*/
  548. {
  549. DebugAssert(_dirent);
  550. return _dirent[11]&0x02 ? TRUE : FALSE; // FILE_ATTRIBUTE_HIDDEN
  551. }
  552. INLINE
  553. VOID
  554. FAT_DIRENT::SetHidden(
  555. )
  556. /*++
  557. Routine Description:
  558. This routine marks the directory entry as hidden.
  559. Arguments:
  560. None.
  561. Return Value:
  562. None.
  563. --*/
  564. {
  565. DebugAssert(_dirent);
  566. _dirent[11] |= 0x02; // FILE_ATTRIBUTE_HIDDEN
  567. }
  568. INLINE
  569. BOOLEAN
  570. FAT_DIRENT::IsReadOnly(
  571. ) CONST
  572. /*++
  573. Routine Description:
  574. This routine computes whether or not the file is read only.
  575. Arguments:
  576. None.
  577. Return Value:
  578. FALSE - The file is not read only.
  579. TRUE - The file is read only.
  580. --*/
  581. {
  582. DebugAssert(_dirent);
  583. return _dirent[11]&0x01 ? TRUE : FALSE; // FILE_ATTRIBUTE_READONLY
  584. }
  585. INLINE
  586. VOID
  587. FAT_DIRENT::SetReadOnly(
  588. )
  589. /*++
  590. Routine Description:
  591. This routine marks the directory entry as read only.
  592. Arguments:
  593. None.
  594. Return Value:
  595. None.
  596. --*/
  597. {
  598. DebugAssert(_dirent);
  599. _dirent[11] |= 0x01; // FILE_ATTRIBUTE_READONLY
  600. }
  601. INLINE
  602. BOOLEAN
  603. FAT_DIRENT::IsSystem(
  604. ) CONST
  605. /*++
  606. Routine Description:
  607. This routine computes whether or not the file is a system file.
  608. Arguments:
  609. None.
  610. Return Value:
  611. FALSE - The file is not a system file.
  612. TRUE - The file is a system file.
  613. --*/
  614. {
  615. DebugAssert(_dirent);
  616. return _dirent[11]&0x04 ? TRUE : FALSE;
  617. }
  618. INLINE
  619. VOID
  620. FAT_DIRENT::SetSystem(
  621. )
  622. /*++
  623. Routine Description:
  624. This routine marks the directory entry as system.
  625. Arguments:
  626. None.
  627. Return Value:
  628. None.
  629. --*/
  630. {
  631. DebugAssert(_dirent);
  632. _dirent[11] |= 0x04; // FILE_ATTRIBUTE_SYSTEM
  633. }
  634. INLINE
  635. BOOLEAN
  636. FAT_DIRENT::IsVolumeLabel(
  637. ) CONST
  638. /*++
  639. Routine Description:
  640. This routine computes whether or not the first 11 characters of the
  641. directory entry are the volume label or not.
  642. Arguments:
  643. None.
  644. Return Value:
  645. FALSE - The directory entry is not a volume label.
  646. TRUE - The directory entry is a volume label.
  647. --*/
  648. {
  649. DebugAssert(_dirent);
  650. return ((_dirent[11]&0x08) && !IsLongEntry());
  651. }
  652. INLINE
  653. BOOLEAN
  654. FAT_DIRENT::IsLongEntry(
  655. ) CONST
  656. /*++
  657. Routine Description;
  658. This routine determines whether this entry is a
  659. Long Directory Entry.
  660. The entry is a Long Directory Entry if the attribute
  661. field has all four low-order bits (read-only, hidden,
  662. system, and volume-label) set. The four high-order
  663. bits are ignored.
  664. Arguments:
  665. None.
  666. Return Value:
  667. TRUE if the entry is a Long Name Directory Entry.
  668. --*/
  669. {
  670. return( (_dirent[11] & 0xF) == 0xF );
  671. }
  672. INLINE
  673. BOOLEAN
  674. FAT_DIRENT::IsLongNameEntry(
  675. ) CONST
  676. /*++
  677. Routine Description;
  678. This routine determines whether this entry is a
  679. Long Name Directory Entry.
  680. A Long Name directory entry is a Long Directory Entry
  681. with a type field of LONG_DIRENT_TYPE_LONG_NAME.
  682. Arguments:
  683. None.
  684. Return Value:
  685. TRUE if the entry is a Long Name Directory Entry.
  686. --*/
  687. {
  688. return( IsLongEntry() && (_dirent[12] == LONG_DIRENT_TYPE_NAME) );
  689. }
  690. INLINE
  691. BOOLEAN
  692. FAT_DIRENT::QueryLongOrdinal(
  693. ) CONST
  694. /*++
  695. Routine Description;
  696. This method returns the ordinal of a long directory entry.
  697. If the directory entry is not a long entry, it returns
  698. 0xFF. Note that this method strips off the Last Long Entry
  699. flag before returning the ordinal. To determine if an entry
  700. is the last of a set of long entries, call IsLastLongEntry.
  701. Arguments:
  702. None.
  703. Return Value:
  704. The ordinal of this entry.
  705. --*/
  706. {
  707. return( IsLongEntry() ? _dirent[0] & 0x3F: 0xFF );
  708. }
  709. INLINE
  710. BOOLEAN
  711. FAT_DIRENT::IsLastLongEntry(
  712. ) CONST
  713. /*++
  714. Routine Description:
  715. This method determines whether this entry is the last
  716. of a set of long directory entries.
  717. Arguments:
  718. None.
  719. Return Value:
  720. TRUE if this is the last of a set of long directory entries.
  721. --*/
  722. {
  723. return( IsLongEntry() ? _dirent[0] & 0x40 : FALSE );
  724. }
  725. INLINE
  726. VOID
  727. FAT_DIRENT::SetVolumeLabel(
  728. )
  729. /*++
  730. Routine Description:
  731. This routine sets the directory entry to be a volume label.
  732. Arguments:
  733. None.
  734. Return Value:
  735. None.
  736. --*/
  737. {
  738. DebugAssert(_dirent);
  739. _dirent[11] |= 0x08;
  740. }
  741. INLINE
  742. BOOLEAN
  743. FAT_DIRENT::IsDirectory(
  744. ) CONST
  745. /*++
  746. Routine Description:
  747. This routine computes whether or not the directory entry is a directory.
  748. Arguments:
  749. None.
  750. Return Value:
  751. FALSE - The directory entry is not a directory.
  752. TRUE - The directory entry is a directory.
  753. --*/
  754. {
  755. DebugAssert(_dirent);
  756. return ((_dirent[11]&0x10) && !IsLongEntry());
  757. }
  758. INLINE
  759. VOID
  760. FAT_DIRENT::SetDirectory(
  761. )
  762. /*++
  763. Routine Description:
  764. This routine sets the directory entry to be a directory.
  765. Arguments:
  766. None.
  767. Return Value:
  768. None.
  769. --*/
  770. {
  771. DebugAssert(_dirent);
  772. _dirent[11] |= 0x10;
  773. }
  774. INLINE
  775. VOID
  776. FAT_DIRENT::ResetDirectory(
  777. )
  778. /*++
  779. Routine Description:
  780. This routine sets the directory entry to not be a directory.
  781. Arguments:
  782. None.
  783. Return Value:
  784. None.
  785. --*/
  786. {
  787. DebugAssert(_dirent);
  788. _dirent[11] &= ~0x10;
  789. }
  790. INLINE
  791. BYTE
  792. FAT_DIRENT::QueryAttributeByte(
  793. ) CONST
  794. /*++
  795. Routine Description:
  796. This routine returns the attribute byte of the directory entry
  797. Arguments:
  798. None.
  799. Return Value:
  800. Attribute byte
  801. --*/
  802. {
  803. DebugAssert(_dirent);
  804. return _dirent[11];
  805. }
  806. INLINE
  807. BOOLEAN
  808. FAT_DIRENT::Is8LowerCase(
  809. ) CONST
  810. /*++
  811. Routine Description:
  812. This routine tells whether the first 8 bytes of the short name
  813. should be downcased after being read from the disk.
  814. Arguments:
  815. None.
  816. Return Value:
  817. TRUE or FALSE
  818. --*/
  819. {
  820. DebugAssert(_dirent);
  821. return (_dirent[12] & 0x08) != 0;
  822. }
  823. INLINE
  824. BOOLEAN
  825. FAT_DIRENT::Is3LowerCase(
  826. ) CONST
  827. /*++
  828. Routine Description:
  829. This routine tells whether the last 8 bytes of the short name
  830. should be downcased after being read from the disk.
  831. Arguments:
  832. None.
  833. Return Value:
  834. TRUE or FALSE
  835. --*/
  836. {
  837. DebugAssert(_dirent);
  838. return (_dirent[12] & 0x10) != 0;
  839. }
  840. #endif // FAT_DIRENT_DEFN