Lightweight SD card FAT file system. Originaled by chan http://elm-chan.org/fsw/ff/00index_p.html

Petit FAT File System for LPC1114

originaled by elm

If you want to use except LPC1114, you can change pin definitions at mmcPinConfig.h

more detail and original code at http://elm-chan.org/fsw/ff/00index_p.html

This library is NOT compatible with mbed official SDFileSystem

Committer:
hsgw
Date:
Fri May 09 19:41:49 2014 +0000
Revision:
0:845390b117a7
1st commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hsgw 0:845390b117a7 1 /*----------------------------------------------------------------------------/
hsgw 0:845390b117a7 2 / Petit FatFs - FAT file system module R0.02a (C)ChaN, 2010
hsgw 0:845390b117a7 3 /-----------------------------------------------------------------------------/
hsgw 0:845390b117a7 4 / Petit FatFs module is an open source software to implement FAT file system to
hsgw 0:845390b117a7 5 / small embedded systems. This is a free software and is opened for education,
hsgw 0:845390b117a7 6 / research and commercial developments under license policy of following trems.
hsgw 0:845390b117a7 7 /
hsgw 0:845390b117a7 8 / Copyright (C) 2010, ChaN, all right reserved.
hsgw 0:845390b117a7 9 /
hsgw 0:845390b117a7 10 / * The Petit FatFs module is a free software and there is NO WARRANTY.
hsgw 0:845390b117a7 11 / * No restriction on use. You can use, modify and redistribute it for
hsgw 0:845390b117a7 12 / personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY.
hsgw 0:845390b117a7 13 / * Redistributions of source code must retain the above copyright notice.
hsgw 0:845390b117a7 14 /
hsgw 0:845390b117a7 15 /-----------------------------------------------------------------------------/
hsgw 0:845390b117a7 16 / Jun 15,'09 R0.01a First release. (Branched from FatFs R0.07b.)
hsgw 0:845390b117a7 17 /
hsgw 0:845390b117a7 18 / Dec 14,'09 R0.02 Added multiple code page support.
hsgw 0:845390b117a7 19 / Added write funciton.
hsgw 0:845390b117a7 20 / Changed stream read mode interface.
hsgw 0:845390b117a7 21 / Dec 07,'10 R0.02a Added some configuration options.
hsgw 0:845390b117a7 22 / Fixed fails to open objects with DBCS character.
hsgw 0:845390b117a7 23 /----------------------------------------------------------------------------*/
hsgw 0:845390b117a7 24
hsgw 0:845390b117a7 25 #include "pff.h" /* Petit FatFs configurations and declarations */
hsgw 0:845390b117a7 26 #include "diskio.h" /* Declarations of low level disk I/O functions */
hsgw 0:845390b117a7 27
hsgw 0:845390b117a7 28
hsgw 0:845390b117a7 29 /*--------------------------------------------------------------------------
hsgw 0:845390b117a7 30
hsgw 0:845390b117a7 31 Module Private Definitions
hsgw 0:845390b117a7 32
hsgw 0:845390b117a7 33 ---------------------------------------------------------------------------*/
hsgw 0:845390b117a7 34
hsgw 0:845390b117a7 35
hsgw 0:845390b117a7 36 #if _FS_FAT32
hsgw 0:845390b117a7 37 #define LD_CLUST(dir) (((DWORD)LD_WORD(dir+PFFDIR_FstClusHI)<<16) | LD_WORD(dir+PFFDIR_FstClusLO))
hsgw 0:845390b117a7 38 #else
hsgw 0:845390b117a7 39 #define LD_CLUST(dir) LD_WORD(dir+PFFDIR_FstClusLO)
hsgw 0:845390b117a7 40 #endif
hsgw 0:845390b117a7 41
hsgw 0:845390b117a7 42
hsgw 0:845390b117a7 43 /*--------------------------------------------------------*/
hsgw 0:845390b117a7 44 /* DBCS code ranges and SBCS extend char conversion table */
hsgw 0:845390b117a7 45
hsgw 0:845390b117a7 46 #if _CODE_PAGE == 932 /* Japanese Shift-JIS */
hsgw 0:845390b117a7 47 #define _DF1S 0x81 /* DBC 1st byte range 1 start */
hsgw 0:845390b117a7 48 #define _DF1E 0x9F /* DBC 1st byte range 1 end */
hsgw 0:845390b117a7 49 #define _DF2S 0xE0 /* DBC 1st byte range 2 start */
hsgw 0:845390b117a7 50 #define _DF2E 0xFC /* DBC 1st byte range 2 end */
hsgw 0:845390b117a7 51 #define _DS1S 0x40 /* DBC 2nd byte range 1 start */
hsgw 0:845390b117a7 52 #define _DS1E 0x7E /* DBC 2nd byte range 1 end */
hsgw 0:845390b117a7 53 #define _DS2S 0x80 /* DBC 2nd byte range 2 start */
hsgw 0:845390b117a7 54 #define _DS2E 0xFC /* DBC 2nd byte range 2 end */
hsgw 0:845390b117a7 55
hsgw 0:845390b117a7 56 #elif _CODE_PAGE == 936 /* Simplified Chinese GBK */
hsgw 0:845390b117a7 57 #define _DF1S 0x81
hsgw 0:845390b117a7 58 #define _DF1E 0xFE
hsgw 0:845390b117a7 59 #define _DS1S 0x40
hsgw 0:845390b117a7 60 #define _DS1E 0x7E
hsgw 0:845390b117a7 61 #define _DS2S 0x80
hsgw 0:845390b117a7 62 #define _DS2E 0xFE
hsgw 0:845390b117a7 63
hsgw 0:845390b117a7 64 #elif _CODE_PAGE == 949 /* Korean */
hsgw 0:845390b117a7 65 #define _DF1S 0x81
hsgw 0:845390b117a7 66 #define _DF1E 0xFE
hsgw 0:845390b117a7 67 #define _DS1S 0x41
hsgw 0:845390b117a7 68 #define _DS1E 0x5A
hsgw 0:845390b117a7 69 #define _DS2S 0x61
hsgw 0:845390b117a7 70 #define _DS2E 0x7A
hsgw 0:845390b117a7 71 #define _DS3S 0x81
hsgw 0:845390b117a7 72 #define _DS3E 0xFE
hsgw 0:845390b117a7 73
hsgw 0:845390b117a7 74 #elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */
hsgw 0:845390b117a7 75 #define _DF1S 0x81
hsgw 0:845390b117a7 76 #define _DF1E 0xFE
hsgw 0:845390b117a7 77 #define _DS1S 0x40
hsgw 0:845390b117a7 78 #define _DS1E 0x7E
hsgw 0:845390b117a7 79 #define _DS2S 0xA1
hsgw 0:845390b117a7 80 #define _DS2E 0xFE
hsgw 0:845390b117a7 81
hsgw 0:845390b117a7 82 #elif _CODE_PAGE == 437 /* U.S. (OEM) */
hsgw 0:845390b117a7 83 #define _DF1S 0
hsgw 0:845390b117a7 84 #define _EXCVT {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F,0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
hsgw 0:845390b117a7 85 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
hsgw 0:845390b117a7 86 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
hsgw 0:845390b117a7 87 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
hsgw 0:845390b117a7 88
hsgw 0:845390b117a7 89 #elif _CODE_PAGE == 720 /* Arabic (OEM) */
hsgw 0:845390b117a7 90 #define _DF1S 0
hsgw 0:845390b117a7 91 #define _EXCVT {0x80,0x81,0x45,0x41,0x84,0x41,0x86,0x43,0x45,0x45,0x45,0x49,0x49,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x49,0x49,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
hsgw 0:845390b117a7 92 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
hsgw 0:845390b117a7 93 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
hsgw 0:845390b117a7 94 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
hsgw 0:845390b117a7 95
hsgw 0:845390b117a7 96 #elif _CODE_PAGE == 737 /* Greek (OEM) */
hsgw 0:845390b117a7 97 #define _DF1S 0
hsgw 0:845390b117a7 98 #define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x96,0x97,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, \
hsgw 0:845390b117a7 99 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
hsgw 0:845390b117a7 100 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
hsgw 0:845390b117a7 101 0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xE7,0xE8,0xF1,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
hsgw 0:845390b117a7 102
hsgw 0:845390b117a7 103 #elif _CODE_PAGE == 775 /* Baltic (OEM) */
hsgw 0:845390b117a7 104 #define _DF1S 0
hsgw 0:845390b117a7 105 #define _EXCVT {0x80,0x9A,0x91,0xA0,0x8E,0x95,0x8F,0x80,0xAD,0xED,0x8A,0x8A,0xA1,0x8D,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0x95,0x96,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
hsgw 0:845390b117a7 106 0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
hsgw 0:845390b117a7 107 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
hsgw 0:845390b117a7 108 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
hsgw 0:845390b117a7 109
hsgw 0:845390b117a7 110 #elif _CODE_PAGE == 850 /* Multilingual Latin 1 (OEM) */
hsgw 0:845390b117a7 111 #define _DF1S 0
hsgw 0:845390b117a7 112 #define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
hsgw 0:845390b117a7 113 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
hsgw 0:845390b117a7 114 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
hsgw 0:845390b117a7 115 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
hsgw 0:845390b117a7 116
hsgw 0:845390b117a7 117 #elif _CODE_PAGE == 852 /* Latin 2 (OEM) */
hsgw 0:845390b117a7 118 #define _DF1S 0
hsgw 0:845390b117a7 119 #define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xDE,0x8F,0x80,0x9D,0xD3,0x8A,0x8A,0xD7,0x8D,0x8E,0x8F,0x90,0x91,0x91,0xE2,0x99,0x95,0x95,0x97,0x97,0x99,0x9A,0x9B,0x9B,0x9D,0x9E,0x9F, \
hsgw 0:845390b117a7 120 0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \
hsgw 0:845390b117a7 121 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
hsgw 0:845390b117a7 122 0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF}
hsgw 0:845390b117a7 123
hsgw 0:845390b117a7 124 #elif _CODE_PAGE == 855 /* Cyrillic (OEM) */
hsgw 0:845390b117a7 125 #define _DF1S 0
hsgw 0:845390b117a7 126 #define _EXCVT {0x81,0x81,0x83,0x83,0x85,0x85,0x87,0x87,0x89,0x89,0x8B,0x8B,0x8D,0x8D,0x8F,0x8F,0x91,0x91,0x93,0x93,0x95,0x95,0x97,0x97,0x99,0x99,0x9B,0x9B,0x9D,0x9D,0x9F,0x9F, \
hsgw 0:845390b117a7 127 0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \
hsgw 0:845390b117a7 128 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \
hsgw 0:845390b117a7 129 0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF}
hsgw 0:845390b117a7 130
hsgw 0:845390b117a7 131 #elif _CODE_PAGE == 857 /* Turkish (OEM) */
hsgw 0:845390b117a7 132 #define _DF1S 0
hsgw 0:845390b117a7 133 #define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0x98,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x98,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9E, \
hsgw 0:845390b117a7 134 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
hsgw 0:845390b117a7 135 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
hsgw 0:845390b117a7 136 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0x59,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
hsgw 0:845390b117a7 137
hsgw 0:845390b117a7 138 #elif _CODE_PAGE == 858 /* Multilingual Latin 1 + Euro (OEM) */
hsgw 0:845390b117a7 139 #define _DF1S 0
hsgw 0:845390b117a7 140 #define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
hsgw 0:845390b117a7 141 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
hsgw 0:845390b117a7 142 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
hsgw 0:845390b117a7 143 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
hsgw 0:845390b117a7 144
hsgw 0:845390b117a7 145 #elif _CODE_PAGE == 862 /* Hebrew (OEM) */
hsgw 0:845390b117a7 146 #define _DF1S 0
hsgw 0:845390b117a7 147 #define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
hsgw 0:845390b117a7 148 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
hsgw 0:845390b117a7 149 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
hsgw 0:845390b117a7 150 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
hsgw 0:845390b117a7 151
hsgw 0:845390b117a7 152 #elif _CODE_PAGE == 866 /* Russian (OEM) */
hsgw 0:845390b117a7 153 #define _DF1S 0
hsgw 0:845390b117a7 154 #define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
hsgw 0:845390b117a7 155 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
hsgw 0:845390b117a7 156 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
hsgw 0:845390b117a7 157 0x90,0x91,0x92,0x93,0x9d,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
hsgw 0:845390b117a7 158
hsgw 0:845390b117a7 159 #elif _CODE_PAGE == 874 /* Thai (OEM, Windows) */
hsgw 0:845390b117a7 160 #define _DF1S 0
hsgw 0:845390b117a7 161 #define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
hsgw 0:845390b117a7 162 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
hsgw 0:845390b117a7 163 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
hsgw 0:845390b117a7 164 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
hsgw 0:845390b117a7 165
hsgw 0:845390b117a7 166 #elif _CODE_PAGE == 1250 /* Central Europe (Windows) */
hsgw 0:845390b117a7 167 #define _DF1S 0
hsgw 0:845390b117a7 168 #define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \
hsgw 0:845390b117a7 169 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xA3,0xB4,0xB5,0xB6,0xB7,0xB8,0xA5,0xAA,0xBB,0xBC,0xBD,0xBC,0xAF, \
hsgw 0:845390b117a7 170 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
hsgw 0:845390b117a7 171 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF}
hsgw 0:845390b117a7 172
hsgw 0:845390b117a7 173 #elif _CODE_PAGE == 1251 /* Cyrillic (Windows) */
hsgw 0:845390b117a7 174 #define _DF1S 0
hsgw 0:845390b117a7 175 #define _EXCVT {0x80,0x81,0x82,0x82,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x80,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \
hsgw 0:845390b117a7 176 0xA0,0xA2,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB2,0xA5,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xA3,0xBD,0xBD,0xAF, \
hsgw 0:845390b117a7 177 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
hsgw 0:845390b117a7 178 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF}
hsgw 0:845390b117a7 179
hsgw 0:845390b117a7 180 #elif _CODE_PAGE == 1252 /* Latin 1 (Windows) */
hsgw 0:845390b117a7 181 #define _DF1S 0
hsgw 0:845390b117a7 182 #define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0xAd,0x9B,0x8C,0x9D,0xAE,0x9F, \
hsgw 0:845390b117a7 183 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
hsgw 0:845390b117a7 184 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
hsgw 0:845390b117a7 185 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F}
hsgw 0:845390b117a7 186
hsgw 0:845390b117a7 187 #elif _CODE_PAGE == 1253 /* Greek (Windows) */
hsgw 0:845390b117a7 188 #define _DF1S 0
hsgw 0:845390b117a7 189 #define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
hsgw 0:845390b117a7 190 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
hsgw 0:845390b117a7 191 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xA2,0xB8,0xB9,0xBA, \
hsgw 0:845390b117a7 192 0xE0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xFB,0xBC,0xFD,0xBF,0xFF}
hsgw 0:845390b117a7 193
hsgw 0:845390b117a7 194 #elif _CODE_PAGE == 1254 /* Turkish (Windows) */
hsgw 0:845390b117a7 195 #define _DF1S 0
hsgw 0:845390b117a7 196 #define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x9D,0x9E,0x9F, \
hsgw 0:845390b117a7 197 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
hsgw 0:845390b117a7 198 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
hsgw 0:845390b117a7 199 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F}
hsgw 0:845390b117a7 200
hsgw 0:845390b117a7 201 #elif _CODE_PAGE == 1255 /* Hebrew (Windows) */
hsgw 0:845390b117a7 202 #define _DF1S 0
hsgw 0:845390b117a7 203 #define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
hsgw 0:845390b117a7 204 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
hsgw 0:845390b117a7 205 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
hsgw 0:845390b117a7 206 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
hsgw 0:845390b117a7 207
hsgw 0:845390b117a7 208 #elif _CODE_PAGE == 1256 /* Arabic (Windows) */
hsgw 0:845390b117a7 209 #define _DF1S 0
hsgw 0:845390b117a7 210 #define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x8C,0x9D,0x9E,0x9F, \
hsgw 0:845390b117a7 211 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
hsgw 0:845390b117a7 212 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
hsgw 0:845390b117a7 213 0x41,0xE1,0x41,0xE3,0xE4,0xE5,0xE6,0x43,0x45,0x45,0x45,0x45,0xEC,0xED,0x49,0x49,0xF0,0xF1,0xF2,0xF3,0x4F,0xF5,0xF6,0xF7,0xF8,0x55,0xFA,0x55,0x55,0xFD,0xFE,0xFF}
hsgw 0:845390b117a7 214
hsgw 0:845390b117a7 215 #elif _CODE_PAGE == 1257 /* Baltic (Windows) */
hsgw 0:845390b117a7 216 #define _DF1S 0
hsgw 0:845390b117a7 217 #define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
hsgw 0:845390b117a7 218 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xBC,0xBD,0xBE,0xAF, \
hsgw 0:845390b117a7 219 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
hsgw 0:845390b117a7 220 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF}
hsgw 0:845390b117a7 221
hsgw 0:845390b117a7 222 #elif _CODE_PAGE == 1258 /* Vietnam (OEM, Windows) */
hsgw 0:845390b117a7 223 #define _DF1S 0
hsgw 0:845390b117a7 224 #define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0xAC,0x9D,0x9E,0x9F, \
hsgw 0:845390b117a7 225 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
hsgw 0:845390b117a7 226 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
hsgw 0:845390b117a7 227 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xEC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xFE,0x9F}
hsgw 0:845390b117a7 228
hsgw 0:845390b117a7 229 #elif _CODE_PAGE == 1 /* ASCII (for only non-LFN cfg) */
hsgw 0:845390b117a7 230 #define _DF1S 0
hsgw 0:845390b117a7 231
hsgw 0:845390b117a7 232 #else
hsgw 0:845390b117a7 233 #error Unknown code page
hsgw 0:845390b117a7 234
hsgw 0:845390b117a7 235 #endif
hsgw 0:845390b117a7 236
hsgw 0:845390b117a7 237
hsgw 0:845390b117a7 238
hsgw 0:845390b117a7 239 /* Character code support macros */
hsgw 0:845390b117a7 240
hsgw 0:845390b117a7 241 #define IsUpper(c) (((c)>='A')&&((c)<='Z'))
hsgw 0:845390b117a7 242 #define IsLower(c) (((c)>='a')&&((c)<='z'))
hsgw 0:845390b117a7 243
hsgw 0:845390b117a7 244 #if _DF1S /* DBCS configuration */
hsgw 0:845390b117a7 245
hsgw 0:845390b117a7 246 #ifdef _DF2S /* Two 1st byte areas */
hsgw 0:845390b117a7 247 #define IsDBCS1(c) (((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) || ((BYTE)(c) >= _DF2S && (BYTE)(c) <= _DF2E))
hsgw 0:845390b117a7 248 #else /* One 1st byte area */
hsgw 0:845390b117a7 249 #define IsDBCS1(c) ((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E)
hsgw 0:845390b117a7 250 #endif
hsgw 0:845390b117a7 251
hsgw 0:845390b117a7 252 #ifdef _DS3S /* Three 2nd byte areas */
hsgw 0:845390b117a7 253 #define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E) || ((BYTE)(c) >= _DS3S && (BYTE)(c) <= _DS3E))
hsgw 0:845390b117a7 254 #else /* Two 2nd byte areas */
hsgw 0:845390b117a7 255 #define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E))
hsgw 0:845390b117a7 256 #endif
hsgw 0:845390b117a7 257
hsgw 0:845390b117a7 258 #else /* SBCS configuration */
hsgw 0:845390b117a7 259
hsgw 0:845390b117a7 260 #define IsDBCS1(c) 0
hsgw 0:845390b117a7 261 #define IsDBCS2(c) 0
hsgw 0:845390b117a7 262
hsgw 0:845390b117a7 263 #endif /* _DF1S */
hsgw 0:845390b117a7 264
hsgw 0:845390b117a7 265
hsgw 0:845390b117a7 266 /* FatFs refers the members in the FAT structures with byte offset instead
hsgw 0:845390b117a7 267 / of structure member because there are incompatibility of the packing option
hsgw 0:845390b117a7 268 / between various compilers. */
hsgw 0:845390b117a7 269
hsgw 0:845390b117a7 270 #define BS_jmpBoot 0
hsgw 0:845390b117a7 271 #define BS_OEMName 3
hsgw 0:845390b117a7 272 #define BPB_BytsPerSec 11
hsgw 0:845390b117a7 273 #define BPB_SecPerClus 13
hsgw 0:845390b117a7 274 #define BPB_RsvdSecCnt 14
hsgw 0:845390b117a7 275 #define BPB_NumFATs 16
hsgw 0:845390b117a7 276 #define BPB_RootEntCnt 17
hsgw 0:845390b117a7 277 #define BPB_TotSec16 19
hsgw 0:845390b117a7 278 #define BPB_Media 21
hsgw 0:845390b117a7 279 #define BPB_FATSz16 22
hsgw 0:845390b117a7 280 #define BPB_SecPerTrk 24
hsgw 0:845390b117a7 281 #define BPB_NumHeads 26
hsgw 0:845390b117a7 282 #define BPB_HiddSec 28
hsgw 0:845390b117a7 283 #define BPB_TotSec32 32
hsgw 0:845390b117a7 284 #define BS_55AA 510
hsgw 0:845390b117a7 285
hsgw 0:845390b117a7 286 #define BS_DrvNum 36
hsgw 0:845390b117a7 287 #define BS_BootSig 38
hsgw 0:845390b117a7 288 #define BS_VolID 39
hsgw 0:845390b117a7 289 #define BS_VolLab 43
hsgw 0:845390b117a7 290 #define BS_FilSysType 54
hsgw 0:845390b117a7 291
hsgw 0:845390b117a7 292 #define BPB_FATSz32 36
hsgw 0:845390b117a7 293 #define BPB_ExtFlags 40
hsgw 0:845390b117a7 294 #define BPB_FSVer 42
hsgw 0:845390b117a7 295 #define BPB_RootClus 44
hsgw 0:845390b117a7 296 #define BPB_FSInfo 48
hsgw 0:845390b117a7 297 #define BPB_BkBootSec 50
hsgw 0:845390b117a7 298 #define BS_DrvNum32 64
hsgw 0:845390b117a7 299 #define BS_BootSig32 66
hsgw 0:845390b117a7 300 #define BS_VolID32 67
hsgw 0:845390b117a7 301 #define BS_VolLab32 71
hsgw 0:845390b117a7 302 #define BS_FilSysType32 82
hsgw 0:845390b117a7 303
hsgw 0:845390b117a7 304 #define MBR_Table 446
hsgw 0:845390b117a7 305
hsgw 0:845390b117a7 306 #define PFFDIR_Name 0
hsgw 0:845390b117a7 307 #define PFFDIR_Attr 11
hsgw 0:845390b117a7 308 #define PFFDIR_NTres 12
hsgw 0:845390b117a7 309 #define PFFDIR_CrtTime 14
hsgw 0:845390b117a7 310 #define PFFDIR_CrtDate 16
hsgw 0:845390b117a7 311 #define PFFDIR_FstClusHI 20
hsgw 0:845390b117a7 312 #define PFFDIR_WrtTime 22
hsgw 0:845390b117a7 313 #define PFFDIR_WrtDate 24
hsgw 0:845390b117a7 314 #define PFFDIR_FstClusLO 26
hsgw 0:845390b117a7 315 #define PFFDIR_FileSize 28
hsgw 0:845390b117a7 316
hsgw 0:845390b117a7 317
hsgw 0:845390b117a7 318
hsgw 0:845390b117a7 319 /*--------------------------------------------------------------------------
hsgw 0:845390b117a7 320
hsgw 0:845390b117a7 321 Private Functions
hsgw 0:845390b117a7 322
hsgw 0:845390b117a7 323 ---------------------------------------------------------------------------*/
hsgw 0:845390b117a7 324
hsgw 0:845390b117a7 325
hsgw 0:845390b117a7 326 static
hsgw 0:845390b117a7 327 FATFS *FatFs; /* Pointer to the file system object (logical drive) */
hsgw 0:845390b117a7 328
hsgw 0:845390b117a7 329
hsgw 0:845390b117a7 330 /* Fill memory */
hsgw 0:845390b117a7 331 static
hsgw 0:845390b117a7 332 void mem_set (void* dst, int val, int cnt) {
hsgw 0:845390b117a7 333 char *d = (char*)dst;
hsgw 0:845390b117a7 334 while (cnt--) *d++ = (char)val;
hsgw 0:845390b117a7 335 }
hsgw 0:845390b117a7 336
hsgw 0:845390b117a7 337 /* Compare memory to memory */
hsgw 0:845390b117a7 338 static
hsgw 0:845390b117a7 339 int mem_cmp (const void* dst, const void* src, int cnt) {
hsgw 0:845390b117a7 340 const char *d = (const char *)dst, *s = (const char *)src;
hsgw 0:845390b117a7 341 int r = 0;
hsgw 0:845390b117a7 342 while (cnt-- && (r = *d++ - *s++) == 0) ;
hsgw 0:845390b117a7 343 return r;
hsgw 0:845390b117a7 344 }
hsgw 0:845390b117a7 345
hsgw 0:845390b117a7 346
hsgw 0:845390b117a7 347
hsgw 0:845390b117a7 348 /*-----------------------------------------------------------------------*/
hsgw 0:845390b117a7 349 /* FAT access - Read value of a FAT entry */
hsgw 0:845390b117a7 350 /*-----------------------------------------------------------------------*/
hsgw 0:845390b117a7 351
hsgw 0:845390b117a7 352 static
hsgw 0:845390b117a7 353 CLUST get_fat ( /* 1:IO error, Else:Cluster status */
hsgw 0:845390b117a7 354 CLUST clst /* Cluster# to get the link information */
hsgw 0:845390b117a7 355 )
hsgw 0:845390b117a7 356 {
hsgw 0:845390b117a7 357 WORD wc, bc, ofs;
hsgw 0:845390b117a7 358 BYTE buf[4];
hsgw 0:845390b117a7 359 FATFS *fs = FatFs;
hsgw 0:845390b117a7 360
hsgw 0:845390b117a7 361
hsgw 0:845390b117a7 362 if (clst < 2 || clst >= fs->n_fatent) /* Range check */
hsgw 0:845390b117a7 363 return 1;
hsgw 0:845390b117a7 364
hsgw 0:845390b117a7 365 switch (fs->fs_type) {
hsgw 0:845390b117a7 366 #if _FS_FAT12
hsgw 0:845390b117a7 367 case FS_FAT12 :
hsgw 0:845390b117a7 368 bc = (WORD)clst; bc += bc / 2;
hsgw 0:845390b117a7 369 ofs = bc % 512; bc /= 512;
hsgw 0:845390b117a7 370 if (ofs != 511) {
hsgw 0:845390b117a7 371 if (disk_readp(buf, fs->fatbase + bc, ofs, 2)) break;
hsgw 0:845390b117a7 372 } else {
hsgw 0:845390b117a7 373 if (disk_readp(buf, fs->fatbase + bc, 511, 1)) break;
hsgw 0:845390b117a7 374 if (disk_readp(buf+1, fs->fatbase + bc + 1, 0, 1)) break;
hsgw 0:845390b117a7 375 }
hsgw 0:845390b117a7 376 wc = LD_WORD(buf);
hsgw 0:845390b117a7 377 return (clst & 1) ? (wc >> 4) : (wc & 0xFFF);
hsgw 0:845390b117a7 378 #endif
hsgw 0:845390b117a7 379 case FS_FAT16 :
hsgw 0:845390b117a7 380 if (disk_readp(buf, fs->fatbase + clst / 256, (WORD)(((WORD)clst % 256) * 2), 2)) break;
hsgw 0:845390b117a7 381 return LD_WORD(buf);
hsgw 0:845390b117a7 382 #if _FS_FAT32
hsgw 0:845390b117a7 383 case FS_FAT32 :
hsgw 0:845390b117a7 384 if (disk_readp(buf, fs->fatbase + clst / 128, (WORD)(((WORD)clst % 128) * 4), 4)) break;
hsgw 0:845390b117a7 385 return LD_DWORD(buf) & 0x0FFFFFFF;
hsgw 0:845390b117a7 386 #endif
hsgw 0:845390b117a7 387 }
hsgw 0:845390b117a7 388
hsgw 0:845390b117a7 389 return 1; /* An error occured at the disk I/O layer */
hsgw 0:845390b117a7 390 }
hsgw 0:845390b117a7 391
hsgw 0:845390b117a7 392
hsgw 0:845390b117a7 393
hsgw 0:845390b117a7 394
hsgw 0:845390b117a7 395 /*-----------------------------------------------------------------------*/
hsgw 0:845390b117a7 396 /* Get sector# from cluster# */
hsgw 0:845390b117a7 397 /*-----------------------------------------------------------------------*/
hsgw 0:845390b117a7 398
hsgw 0:845390b117a7 399 static
hsgw 0:845390b117a7 400 DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */
hsgw 0:845390b117a7 401 CLUST clst /* Cluster# to be converted */
hsgw 0:845390b117a7 402 )
hsgw 0:845390b117a7 403 {
hsgw 0:845390b117a7 404 FATFS *fs = FatFs;
hsgw 0:845390b117a7 405
hsgw 0:845390b117a7 406
hsgw 0:845390b117a7 407 clst -= 2;
hsgw 0:845390b117a7 408 if (clst >= (fs->n_fatent - 2)) return 0; /* Invalid cluster# */
hsgw 0:845390b117a7 409 return (DWORD)clst * fs->csize + fs->database;
hsgw 0:845390b117a7 410 }
hsgw 0:845390b117a7 411
hsgw 0:845390b117a7 412
hsgw 0:845390b117a7 413
hsgw 0:845390b117a7 414
hsgw 0:845390b117a7 415 /*-----------------------------------------------------------------------*/
hsgw 0:845390b117a7 416 /* Directory handling - Rewind directory index */
hsgw 0:845390b117a7 417 /*-----------------------------------------------------------------------*/
hsgw 0:845390b117a7 418
hsgw 0:845390b117a7 419 static
hsgw 0:845390b117a7 420 FRESULT dir_rewind (
hsgw 0:845390b117a7 421 PFFDIR *dj /* Pointer to directory object */
hsgw 0:845390b117a7 422 )
hsgw 0:845390b117a7 423 {
hsgw 0:845390b117a7 424 CLUST clst;
hsgw 0:845390b117a7 425 FATFS *fs = FatFs;
hsgw 0:845390b117a7 426
hsgw 0:845390b117a7 427
hsgw 0:845390b117a7 428 dj->index = 0;
hsgw 0:845390b117a7 429 clst = dj->sclust;
hsgw 0:845390b117a7 430 if (clst == 1 || clst >= fs->n_fatent) /* Check start cluster range */
hsgw 0:845390b117a7 431 return FR_DISK_ERR;
hsgw 0:845390b117a7 432 if (_FS_FAT32 && !clst && fs->fs_type == FS_FAT32) /* Replace cluster# 0 with root cluster# if in FAT32 */
hsgw 0:845390b117a7 433 clst = (CLUST)fs->dirbase;
hsgw 0:845390b117a7 434 dj->clust = clst; /* Current cluster */
hsgw 0:845390b117a7 435 dj->sect = clst ? clust2sect(clst) : fs->dirbase; /* Current sector */
hsgw 0:845390b117a7 436
hsgw 0:845390b117a7 437 return FR_OK; /* Seek succeeded */
hsgw 0:845390b117a7 438 }
hsgw 0:845390b117a7 439
hsgw 0:845390b117a7 440
hsgw 0:845390b117a7 441
hsgw 0:845390b117a7 442
hsgw 0:845390b117a7 443 /*-----------------------------------------------------------------------*/
hsgw 0:845390b117a7 444 /* Directory handling - Move directory index next */
hsgw 0:845390b117a7 445 /*-----------------------------------------------------------------------*/
hsgw 0:845390b117a7 446
hsgw 0:845390b117a7 447 static
hsgw 0:845390b117a7 448 FRESULT dir_next ( /* FR_OK:Succeeded, FR_NO_FILE:End of table */
hsgw 0:845390b117a7 449 PFFDIR *dj /* Pointer to directory object */
hsgw 0:845390b117a7 450 )
hsgw 0:845390b117a7 451 {
hsgw 0:845390b117a7 452 CLUST clst;
hsgw 0:845390b117a7 453 WORD i;
hsgw 0:845390b117a7 454 FATFS *fs = FatFs;
hsgw 0:845390b117a7 455
hsgw 0:845390b117a7 456
hsgw 0:845390b117a7 457 i = dj->index + 1;
hsgw 0:845390b117a7 458 if (!i || !dj->sect) /* Report EOT when index has reached 65535 */
hsgw 0:845390b117a7 459 return FR_NO_FILE;
hsgw 0:845390b117a7 460
hsgw 0:845390b117a7 461 if (!(i % 16)) { /* Sector changed? */
hsgw 0:845390b117a7 462 dj->sect++; /* Next sector */
hsgw 0:845390b117a7 463
hsgw 0:845390b117a7 464 if (dj->clust == 0) { /* Static table */
hsgw 0:845390b117a7 465 if (i >= fs->n_rootdir) /* Report EOT when end of table */
hsgw 0:845390b117a7 466 return FR_NO_FILE;
hsgw 0:845390b117a7 467 }
hsgw 0:845390b117a7 468 else { /* Dynamic table */
hsgw 0:845390b117a7 469 if (((i / 16) & (fs->csize-1)) == 0) { /* Cluster changed? */
hsgw 0:845390b117a7 470 clst = get_fat(dj->clust); /* Get next cluster */
hsgw 0:845390b117a7 471 if (clst <= 1) return FR_DISK_ERR;
hsgw 0:845390b117a7 472 if (clst >= fs->n_fatent) /* When it reached end of dynamic table */
hsgw 0:845390b117a7 473 return FR_NO_FILE; /* Report EOT */
hsgw 0:845390b117a7 474 dj->clust = clst; /* Initialize data for new cluster */
hsgw 0:845390b117a7 475 dj->sect = clust2sect(clst);
hsgw 0:845390b117a7 476 }
hsgw 0:845390b117a7 477 }
hsgw 0:845390b117a7 478 }
hsgw 0:845390b117a7 479
hsgw 0:845390b117a7 480 dj->index = i;
hsgw 0:845390b117a7 481
hsgw 0:845390b117a7 482 return FR_OK;
hsgw 0:845390b117a7 483 }
hsgw 0:845390b117a7 484
hsgw 0:845390b117a7 485
hsgw 0:845390b117a7 486
hsgw 0:845390b117a7 487
hsgw 0:845390b117a7 488 /*-----------------------------------------------------------------------*/
hsgw 0:845390b117a7 489 /* Directory handling - Find an object in the directory */
hsgw 0:845390b117a7 490 /*-----------------------------------------------------------------------*/
hsgw 0:845390b117a7 491
hsgw 0:845390b117a7 492 static
hsgw 0:845390b117a7 493 FRESULT dir_find (
hsgw 0:845390b117a7 494 PFFDIR *dj, /* Pointer to the directory object linked to the file name */
hsgw 0:845390b117a7 495 BYTE *dir /* 32-byte working buffer */
hsgw 0:845390b117a7 496 )
hsgw 0:845390b117a7 497 {
hsgw 0:845390b117a7 498 FRESULT res;
hsgw 0:845390b117a7 499 BYTE c;
hsgw 0:845390b117a7 500
hsgw 0:845390b117a7 501
hsgw 0:845390b117a7 502 res = dir_rewind(dj); /* Rewind directory object */
hsgw 0:845390b117a7 503 if (res != FR_OK) return res;
hsgw 0:845390b117a7 504
hsgw 0:845390b117a7 505 do {
hsgw 0:845390b117a7 506 res = disk_readp(dir, dj->sect, (WORD)((dj->index % 16) * 32), 32) /* Read an entry */
hsgw 0:845390b117a7 507 ? FR_DISK_ERR : FR_OK;
hsgw 0:845390b117a7 508 if (res != FR_OK) break;
hsgw 0:845390b117a7 509 c = dir[PFFDIR_Name]; /* First character */
hsgw 0:845390b117a7 510 if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */
hsgw 0:845390b117a7 511 if (!(dir[PFFDIR_Attr] & AM_VOL) && !mem_cmp(dir, dj->fn, 11)) /* Is it a valid entry? */
hsgw 0:845390b117a7 512 break;
hsgw 0:845390b117a7 513 res = dir_next(dj); /* Next entry */
hsgw 0:845390b117a7 514 } while (res == FR_OK);
hsgw 0:845390b117a7 515
hsgw 0:845390b117a7 516 return res;
hsgw 0:845390b117a7 517 }
hsgw 0:845390b117a7 518
hsgw 0:845390b117a7 519
hsgw 0:845390b117a7 520
hsgw 0:845390b117a7 521
hsgw 0:845390b117a7 522 /*-----------------------------------------------------------------------*/
hsgw 0:845390b117a7 523 /* Read an object from the directory */
hsgw 0:845390b117a7 524 /*-----------------------------------------------------------------------*/
hsgw 0:845390b117a7 525 #if _USE_DIR
hsgw 0:845390b117a7 526 static
hsgw 0:845390b117a7 527 FRESULT dir_read (
hsgw 0:845390b117a7 528 PFFDIR *dj, /* Pointer to the directory object to store read object name */
hsgw 0:845390b117a7 529 BYTE *dir /* 32-byte working buffer */
hsgw 0:845390b117a7 530 )
hsgw 0:845390b117a7 531 {
hsgw 0:845390b117a7 532 FRESULT res;
hsgw 0:845390b117a7 533 BYTE a, c;
hsgw 0:845390b117a7 534
hsgw 0:845390b117a7 535
hsgw 0:845390b117a7 536 res = FR_NO_FILE;
hsgw 0:845390b117a7 537 while (dj->sect) {
hsgw 0:845390b117a7 538 res = disk_readp(dir, dj->sect, (WORD)((dj->index % 16) * 32), 32) /* Read an entry */
hsgw 0:845390b117a7 539 ? FR_DISK_ERR : FR_OK;
hsgw 0:845390b117a7 540 if (res != FR_OK) break;
hsgw 0:845390b117a7 541 c = dir[PFFDIR_Name];
hsgw 0:845390b117a7 542 if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */
hsgw 0:845390b117a7 543 a = dir[PFFDIR_Attr] & AM_MASK;
hsgw 0:845390b117a7 544 if (c != 0xE5 && c != '.' && !(a & AM_VOL)) /* Is it a valid entry? */
hsgw 0:845390b117a7 545 break;
hsgw 0:845390b117a7 546 res = dir_next(dj); /* Next entry */
hsgw 0:845390b117a7 547 if (res != FR_OK) break;
hsgw 0:845390b117a7 548 }
hsgw 0:845390b117a7 549
hsgw 0:845390b117a7 550 if (res != FR_OK) dj->sect = 0;
hsgw 0:845390b117a7 551
hsgw 0:845390b117a7 552 return res;
hsgw 0:845390b117a7 553 }
hsgw 0:845390b117a7 554 #endif
hsgw 0:845390b117a7 555
hsgw 0:845390b117a7 556
hsgw 0:845390b117a7 557
hsgw 0:845390b117a7 558 /*-----------------------------------------------------------------------*/
hsgw 0:845390b117a7 559 /* Pick a segment and create the object name in directory form */
hsgw 0:845390b117a7 560 /*-----------------------------------------------------------------------*/
hsgw 0:845390b117a7 561
hsgw 0:845390b117a7 562 #ifdef _EXCVT
hsgw 0:845390b117a7 563 static const BYTE cvt[] = _EXCVT;
hsgw 0:845390b117a7 564 #endif
hsgw 0:845390b117a7 565
hsgw 0:845390b117a7 566 static
hsgw 0:845390b117a7 567 FRESULT create_name (
hsgw 0:845390b117a7 568 PFFDIR *dj, /* Pointer to the directory object */
hsgw 0:845390b117a7 569 const char **path /* Pointer to pointer to the segment in the path string */
hsgw 0:845390b117a7 570 )
hsgw 0:845390b117a7 571 {
hsgw 0:845390b117a7 572 BYTE c, d, ni, si, i, *sfn;
hsgw 0:845390b117a7 573 const char *p;
hsgw 0:845390b117a7 574
hsgw 0:845390b117a7 575 /* Create file name in directory form */
hsgw 0:845390b117a7 576 sfn = dj->fn;
hsgw 0:845390b117a7 577 mem_set(sfn, ' ', 11);
hsgw 0:845390b117a7 578 si = i = 0; ni = 8;
hsgw 0:845390b117a7 579 p = *path;
hsgw 0:845390b117a7 580 for (;;) {
hsgw 0:845390b117a7 581 c = p[si++];
hsgw 0:845390b117a7 582 if (c <= ' ' || c == '/') break; /* Break on end of segment */
hsgw 0:845390b117a7 583 if (c == '.' || i >= ni) {
hsgw 0:845390b117a7 584 if (ni != 8 || c != '.') break;
hsgw 0:845390b117a7 585 i = 8; ni = 11;
hsgw 0:845390b117a7 586 continue;
hsgw 0:845390b117a7 587 }
hsgw 0:845390b117a7 588 #ifdef _EXCVT
hsgw 0:845390b117a7 589 if (c >= 0x80) /* To upper extended char (SBCS) */
hsgw 0:845390b117a7 590 c = cvt[c - 0x80];
hsgw 0:845390b117a7 591 #endif
hsgw 0:845390b117a7 592 if (IsDBCS1(c) && i < ni - 1) { /* DBC 1st byte? */
hsgw 0:845390b117a7 593 d = p[si++]; /* Get 2nd byte */
hsgw 0:845390b117a7 594 sfn[i++] = c;
hsgw 0:845390b117a7 595 sfn[i++] = d;
hsgw 0:845390b117a7 596 } else { /* Single byte code */
hsgw 0:845390b117a7 597 if (IsLower(c)) c -= 0x20; /* toupper */
hsgw 0:845390b117a7 598 sfn[i++] = c;
hsgw 0:845390b117a7 599 }
hsgw 0:845390b117a7 600 }
hsgw 0:845390b117a7 601 *path = &p[si]; /* Rerurn pointer to the next segment */
hsgw 0:845390b117a7 602
hsgw 0:845390b117a7 603 sfn[11] = (c <= ' ') ? 1 : 0; /* Set last segment flag if end of path */
hsgw 0:845390b117a7 604
hsgw 0:845390b117a7 605 return FR_OK;
hsgw 0:845390b117a7 606 }
hsgw 0:845390b117a7 607
hsgw 0:845390b117a7 608
hsgw 0:845390b117a7 609
hsgw 0:845390b117a7 610
hsgw 0:845390b117a7 611 /*-----------------------------------------------------------------------*/
hsgw 0:845390b117a7 612 /* Get file information from directory entry */
hsgw 0:845390b117a7 613 /*-----------------------------------------------------------------------*/
hsgw 0:845390b117a7 614 #if _USE_DIR
hsgw 0:845390b117a7 615 static
hsgw 0:845390b117a7 616 void get_fileinfo ( /* No return code */
hsgw 0:845390b117a7 617 PFFDIR *dj, /* Pointer to the directory object */
hsgw 0:845390b117a7 618 BYTE *dir, /* 32-byte working buffer */
hsgw 0:845390b117a7 619 FILINFO *fno /* Pointer to store the file information */
hsgw 0:845390b117a7 620 )
hsgw 0:845390b117a7 621 {
hsgw 0:845390b117a7 622 BYTE i, c;
hsgw 0:845390b117a7 623 char *p;
hsgw 0:845390b117a7 624
hsgw 0:845390b117a7 625
hsgw 0:845390b117a7 626 p = fno->fname;
hsgw 0:845390b117a7 627 if (dj->sect) {
hsgw 0:845390b117a7 628 for (i = 0; i < 8; i++) { /* Copy file name body */
hsgw 0:845390b117a7 629 c = dir[i];
hsgw 0:845390b117a7 630 if (c == ' ') break;
hsgw 0:845390b117a7 631 if (c == 0x05) c = 0xE5;
hsgw 0:845390b117a7 632 *p++ = c;
hsgw 0:845390b117a7 633 }
hsgw 0:845390b117a7 634 if (dir[8] != ' ') { /* Copy file name extension */
hsgw 0:845390b117a7 635 *p++ = '.';
hsgw 0:845390b117a7 636 for (i = 8; i < 11; i++) {
hsgw 0:845390b117a7 637 c = dir[i];
hsgw 0:845390b117a7 638 if (c == ' ') break;
hsgw 0:845390b117a7 639 *p++ = c;
hsgw 0:845390b117a7 640 }
hsgw 0:845390b117a7 641 }
hsgw 0:845390b117a7 642 fno->fattrib = dir[PFFDIR_Attr]; /* Attribute */
hsgw 0:845390b117a7 643 fno->fsize = LD_DWORD(dir+PFFDIR_FileSize); /* Size */
hsgw 0:845390b117a7 644 fno->fdate = LD_WORD(dir+PFFDIR_WrtDate); /* Date */
hsgw 0:845390b117a7 645 fno->ftime = LD_WORD(dir+PFFDIR_WrtTime); /* Time */
hsgw 0:845390b117a7 646 }
hsgw 0:845390b117a7 647 *p = 0;
hsgw 0:845390b117a7 648 }
hsgw 0:845390b117a7 649 #endif /* _USE_DIR */
hsgw 0:845390b117a7 650
hsgw 0:845390b117a7 651
hsgw 0:845390b117a7 652
hsgw 0:845390b117a7 653 /*-----------------------------------------------------------------------*/
hsgw 0:845390b117a7 654 /* Follow a file path */
hsgw 0:845390b117a7 655 /*-----------------------------------------------------------------------*/
hsgw 0:845390b117a7 656
hsgw 0:845390b117a7 657 static
hsgw 0:845390b117a7 658 FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */
hsgw 0:845390b117a7 659 PFFDIR *dj, /* Directory object to return last directory and found object */
hsgw 0:845390b117a7 660 BYTE *dir, /* 32-byte working buffer */
hsgw 0:845390b117a7 661 const char *path /* Full-path string to find a file or directory */
hsgw 0:845390b117a7 662 )
hsgw 0:845390b117a7 663 {
hsgw 0:845390b117a7 664 FRESULT res;
hsgw 0:845390b117a7 665
hsgw 0:845390b117a7 666
hsgw 0:845390b117a7 667 while (*path == ' ') path++; /* Skip leading spaces */
hsgw 0:845390b117a7 668 if (*path == '/') path++; /* Strip heading separator */
hsgw 0:845390b117a7 669 dj->sclust = 0; /* Set start directory (always root dir) */
hsgw 0:845390b117a7 670
hsgw 0:845390b117a7 671 if ((BYTE)*path <= ' ') { /* Null path means the root directory */
hsgw 0:845390b117a7 672 res = dir_rewind(dj);
hsgw 0:845390b117a7 673 dir[0] = 0;
hsgw 0:845390b117a7 674
hsgw 0:845390b117a7 675 } else { /* Follow path */
hsgw 0:845390b117a7 676 for (;;) {
hsgw 0:845390b117a7 677 res = create_name(dj, &path); /* Get a segment */
hsgw 0:845390b117a7 678 if (res != FR_OK) break;
hsgw 0:845390b117a7 679 res = dir_find(dj, dir); /* Find it */
hsgw 0:845390b117a7 680 if (res != FR_OK) { /* Could not find the object */
hsgw 0:845390b117a7 681 if (res == FR_NO_FILE && !*(dj->fn+11))
hsgw 0:845390b117a7 682 res = FR_NO_PATH;
hsgw 0:845390b117a7 683 break;
hsgw 0:845390b117a7 684 }
hsgw 0:845390b117a7 685 if (*(dj->fn+11)) break; /* Last segment match. Function completed. */
hsgw 0:845390b117a7 686 if (!(dir[PFFDIR_Attr] & AM_DIR)) { /* Cannot follow because it is a file */
hsgw 0:845390b117a7 687 res = FR_NO_PATH; break;
hsgw 0:845390b117a7 688 }
hsgw 0:845390b117a7 689 dj->sclust = LD_CLUST(dir);
hsgw 0:845390b117a7 690 }
hsgw 0:845390b117a7 691 }
hsgw 0:845390b117a7 692
hsgw 0:845390b117a7 693 return res;
hsgw 0:845390b117a7 694 }
hsgw 0:845390b117a7 695
hsgw 0:845390b117a7 696
hsgw 0:845390b117a7 697
hsgw 0:845390b117a7 698
hsgw 0:845390b117a7 699 /*-----------------------------------------------------------------------*/
hsgw 0:845390b117a7 700 /* Check a sector if it is an FAT boot record */
hsgw 0:845390b117a7 701 /*-----------------------------------------------------------------------*/
hsgw 0:845390b117a7 702
hsgw 0:845390b117a7 703 static
hsgw 0:845390b117a7 704 BYTE check_fs ( /* 0:The FAT boot record, 1:Valid boot record but not an FAT, 2:Not a boot record, 3:Error */
hsgw 0:845390b117a7 705 BYTE *buf, /* Working buffer */
hsgw 0:845390b117a7 706 DWORD sect /* Sector# (lba) to check if it is an FAT boot record or not */
hsgw 0:845390b117a7 707 )
hsgw 0:845390b117a7 708 {
hsgw 0:845390b117a7 709 if (disk_readp(buf, sect, 510, 2)) /* Read the boot sector */
hsgw 0:845390b117a7 710 return 3;
hsgw 0:845390b117a7 711 if (LD_WORD(buf) != 0xAA55) /* Check record signature */
hsgw 0:845390b117a7 712 return 2;
hsgw 0:845390b117a7 713
hsgw 0:845390b117a7 714 if (!disk_readp(buf, sect, BS_FilSysType, 2) && LD_WORD(buf) == 0x4146) /* Check FAT12/16 */
hsgw 0:845390b117a7 715 return 0;
hsgw 0:845390b117a7 716 if (_FS_FAT32 && !disk_readp(buf, sect, BS_FilSysType32, 2) && LD_WORD(buf) == 0x4146) /* Check FAT32 */
hsgw 0:845390b117a7 717 return 0;
hsgw 0:845390b117a7 718 return 1;
hsgw 0:845390b117a7 719 }
hsgw 0:845390b117a7 720
hsgw 0:845390b117a7 721
hsgw 0:845390b117a7 722
hsgw 0:845390b117a7 723
hsgw 0:845390b117a7 724 /*--------------------------------------------------------------------------
hsgw 0:845390b117a7 725
hsgw 0:845390b117a7 726 Public Functions
hsgw 0:845390b117a7 727
hsgw 0:845390b117a7 728 --------------------------------------------------------------------------*/
hsgw 0:845390b117a7 729
hsgw 0:845390b117a7 730
hsgw 0:845390b117a7 731
hsgw 0:845390b117a7 732 /*-----------------------------------------------------------------------*/
hsgw 0:845390b117a7 733 /* Mount/Unmount a Locical Drive */
hsgw 0:845390b117a7 734 /*-----------------------------------------------------------------------*/
hsgw 0:845390b117a7 735
hsgw 0:845390b117a7 736 FRESULT pf_mount (
hsgw 0:845390b117a7 737 FATFS *fs /* Pointer to new file system object (NULL: Unmount) */
hsgw 0:845390b117a7 738 )
hsgw 0:845390b117a7 739 {
hsgw 0:845390b117a7 740 BYTE fmt, buf[36];
hsgw 0:845390b117a7 741 DWORD bsect, fsize, tsect, mclst;
hsgw 0:845390b117a7 742
hsgw 0:845390b117a7 743
hsgw 0:845390b117a7 744 FatFs = 0;
hsgw 0:845390b117a7 745 if (!fs) return FR_OK; /* Unregister fs object */
hsgw 0:845390b117a7 746
hsgw 0:845390b117a7 747 if (disk_initialize() & STA_NOINIT) /* Check if the drive is ready or not */
hsgw 0:845390b117a7 748 return FR_NOT_READY;
hsgw 0:845390b117a7 749
hsgw 0:845390b117a7 750 /* Search FAT partition on the drive */
hsgw 0:845390b117a7 751 bsect = 0;
hsgw 0:845390b117a7 752 fmt = check_fs(buf, bsect); /* Check sector 0 as an SFD format */
hsgw 0:845390b117a7 753 if (fmt == 1) { /* Not an FAT boot record, it may be FDISK format */
hsgw 0:845390b117a7 754 /* Check a partition listed in top of the partition table */
hsgw 0:845390b117a7 755 if (disk_readp(buf, bsect, MBR_Table, 16)) { /* 1st partition entry */
hsgw 0:845390b117a7 756 fmt = 3;
hsgw 0:845390b117a7 757 } else {
hsgw 0:845390b117a7 758 if (buf[4]) { /* Is the partition existing? */
hsgw 0:845390b117a7 759 bsect = LD_DWORD(&buf[8]); /* Partition offset in LBA */
hsgw 0:845390b117a7 760 fmt = check_fs(buf, bsect); /* Check the partition */
hsgw 0:845390b117a7 761 }
hsgw 0:845390b117a7 762 }
hsgw 0:845390b117a7 763 }
hsgw 0:845390b117a7 764 if (fmt == 3) return FR_DISK_ERR;
hsgw 0:845390b117a7 765 if (fmt) return FR_NO_FILESYSTEM; /* No valid FAT patition is found */
hsgw 0:845390b117a7 766
hsgw 0:845390b117a7 767 /* Initialize the file system object */
hsgw 0:845390b117a7 768 if (disk_readp(buf, bsect, 13, sizeof(buf))) return FR_DISK_ERR;
hsgw 0:845390b117a7 769
hsgw 0:845390b117a7 770 fsize = LD_WORD(buf+BPB_FATSz16-13); /* Number of sectors per FAT */
hsgw 0:845390b117a7 771 if (!fsize) fsize = LD_DWORD(buf+BPB_FATSz32-13);
hsgw 0:845390b117a7 772
hsgw 0:845390b117a7 773 fsize *= buf[BPB_NumFATs-13]; /* Number of sectors in FAT area */
hsgw 0:845390b117a7 774 fs->fatbase = bsect + LD_WORD(buf+BPB_RsvdSecCnt-13); /* FAT start sector (lba) */
hsgw 0:845390b117a7 775 fs->csize = buf[BPB_SecPerClus-13]; /* Number of sectors per cluster */
hsgw 0:845390b117a7 776 fs->n_rootdir = LD_WORD(buf+BPB_RootEntCnt-13); /* Nmuber of root directory entries */
hsgw 0:845390b117a7 777 tsect = LD_WORD(buf+BPB_TotSec16-13); /* Number of sectors on the file system */
hsgw 0:845390b117a7 778 if (!tsect) tsect = LD_DWORD(buf+BPB_TotSec32-13);
hsgw 0:845390b117a7 779 mclst = (tsect /* Last cluster# + 1 */
hsgw 0:845390b117a7 780 - LD_WORD(buf+BPB_RsvdSecCnt-13) - fsize - fs->n_rootdir / 16
hsgw 0:845390b117a7 781 ) / fs->csize + 2;
hsgw 0:845390b117a7 782 fs->n_fatent = (CLUST)mclst;
hsgw 0:845390b117a7 783
hsgw 0:845390b117a7 784 fmt = FS_FAT16; /* Determine the FAT sub type */
hsgw 0:845390b117a7 785 if (mclst < 0xFF7) /* Number of clusters < 0xFF5 */
hsgw 0:845390b117a7 786 #if _FS_FAT12
hsgw 0:845390b117a7 787 fmt = FS_FAT12;
hsgw 0:845390b117a7 788 #else
hsgw 0:845390b117a7 789 return FR_NO_FILESYSTEM;
hsgw 0:845390b117a7 790 #endif
hsgw 0:845390b117a7 791 if (mclst >= 0xFFF7) /* Number of clusters >= 0xFFF5 */
hsgw 0:845390b117a7 792 #if _FS_FAT32
hsgw 0:845390b117a7 793 fmt = FS_FAT32;
hsgw 0:845390b117a7 794 #else
hsgw 0:845390b117a7 795 return FR_NO_FILESYSTEM;
hsgw 0:845390b117a7 796 #endif
hsgw 0:845390b117a7 797
hsgw 0:845390b117a7 798 fs->fs_type = fmt; /* FAT sub-type */
hsgw 0:845390b117a7 799 if (_FS_FAT32 && fmt == FS_FAT32)
hsgw 0:845390b117a7 800 fs->dirbase = LD_DWORD(buf+(BPB_RootClus-13)); /* Root directory start cluster */
hsgw 0:845390b117a7 801 else
hsgw 0:845390b117a7 802 fs->dirbase = fs->fatbase + fsize; /* Root directory start sector (lba) */
hsgw 0:845390b117a7 803 fs->database = fs->fatbase + fsize + fs->n_rootdir / 16; /* Data start sector (lba) */
hsgw 0:845390b117a7 804
hsgw 0:845390b117a7 805 fs->flag = 0;
hsgw 0:845390b117a7 806 FatFs = fs;
hsgw 0:845390b117a7 807
hsgw 0:845390b117a7 808 return FR_OK;
hsgw 0:845390b117a7 809 }
hsgw 0:845390b117a7 810
hsgw 0:845390b117a7 811
hsgw 0:845390b117a7 812
hsgw 0:845390b117a7 813
hsgw 0:845390b117a7 814 /*-----------------------------------------------------------------------*/
hsgw 0:845390b117a7 815 /* Open or Create a File */
hsgw 0:845390b117a7 816 /*-----------------------------------------------------------------------*/
hsgw 0:845390b117a7 817
hsgw 0:845390b117a7 818 FRESULT pf_open (
hsgw 0:845390b117a7 819 const char *path /* Pointer to the file name */
hsgw 0:845390b117a7 820 )
hsgw 0:845390b117a7 821 {
hsgw 0:845390b117a7 822 FRESULT res;
hsgw 0:845390b117a7 823 PFFDIR dj;
hsgw 0:845390b117a7 824 BYTE sp[12], dir[32];
hsgw 0:845390b117a7 825 FATFS *fs = FatFs;
hsgw 0:845390b117a7 826
hsgw 0:845390b117a7 827
hsgw 0:845390b117a7 828 if (!fs) /* Check file system */
hsgw 0:845390b117a7 829 return FR_NOT_ENABLED;
hsgw 0:845390b117a7 830
hsgw 0:845390b117a7 831 fs->flag = 0;
hsgw 0:845390b117a7 832 dj.fn = sp;
hsgw 0:845390b117a7 833 res = follow_path(&dj, dir, path); /* Follow the file path */
hsgw 0:845390b117a7 834 if (res != FR_OK) return res; /* Follow failed */
hsgw 0:845390b117a7 835 if (!dir[0] || (dir[PFFDIR_Attr] & AM_DIR)) /* It is a directory */
hsgw 0:845390b117a7 836 return FR_NO_FILE;
hsgw 0:845390b117a7 837
hsgw 0:845390b117a7 838 fs->org_clust = LD_CLUST(dir); /* File start cluster */
hsgw 0:845390b117a7 839 fs->fsize = LD_DWORD(dir+PFFDIR_FileSize); /* File size */
hsgw 0:845390b117a7 840 fs->fptr = 0; /* File pointer */
hsgw 0:845390b117a7 841 fs->flag = FA_OPENED;
hsgw 0:845390b117a7 842
hsgw 0:845390b117a7 843 return FR_OK;
hsgw 0:845390b117a7 844 }
hsgw 0:845390b117a7 845
hsgw 0:845390b117a7 846
hsgw 0:845390b117a7 847
hsgw 0:845390b117a7 848
hsgw 0:845390b117a7 849 /*-----------------------------------------------------------------------*/
hsgw 0:845390b117a7 850 /* Read File */
hsgw 0:845390b117a7 851 /*-----------------------------------------------------------------------*/
hsgw 0:845390b117a7 852 #if _USE_READ
hsgw 0:845390b117a7 853
hsgw 0:845390b117a7 854 FRESULT pf_read (
hsgw 0:845390b117a7 855 void* buff, /* Pointer to the read buffer (NULL:Forward data to the stream)*/
hsgw 0:845390b117a7 856 WORD btr, /* Number of bytes to read */
hsgw 0:845390b117a7 857 WORD* br /* Pointer to number of bytes read */
hsgw 0:845390b117a7 858 )
hsgw 0:845390b117a7 859 {
hsgw 0:845390b117a7 860 DRESULT dr;
hsgw 0:845390b117a7 861 CLUST clst;
hsgw 0:845390b117a7 862 DWORD sect, remain;
hsgw 0:845390b117a7 863 WORD rcnt;
hsgw 0:845390b117a7 864 BYTE cs, *rbuff = (BYTE *)buff;
hsgw 0:845390b117a7 865 FATFS *fs = FatFs;
hsgw 0:845390b117a7 866
hsgw 0:845390b117a7 867
hsgw 0:845390b117a7 868 *br = 0;
hsgw 0:845390b117a7 869 if (!fs) return FR_NOT_ENABLED; /* Check file system */
hsgw 0:845390b117a7 870 if (!(fs->flag & FA_OPENED)) /* Check if opened */
hsgw 0:845390b117a7 871 return FR_NOT_OPENED;
hsgw 0:845390b117a7 872
hsgw 0:845390b117a7 873 remain = fs->fsize - fs->fptr;
hsgw 0:845390b117a7 874 if (btr > remain) btr = (WORD)remain; /* Truncate btr by remaining bytes */
hsgw 0:845390b117a7 875
hsgw 0:845390b117a7 876 while (btr) { /* Repeat until all data transferred */
hsgw 0:845390b117a7 877 if ((fs->fptr % 512) == 0) { /* On the sector boundary? */
hsgw 0:845390b117a7 878 cs = (BYTE)(fs->fptr / 512 & (fs->csize - 1)); /* Sector offset in the cluster */
hsgw 0:845390b117a7 879 if (!cs) { /* On the cluster boundary? */
hsgw 0:845390b117a7 880 clst = (fs->fptr == 0) ? /* On the top of the file? */
hsgw 0:845390b117a7 881 fs->org_clust : get_fat(fs->curr_clust);
hsgw 0:845390b117a7 882 if (clst <= 1) goto fr_abort;
hsgw 0:845390b117a7 883 fs->curr_clust = clst; /* Update current cluster */
hsgw 0:845390b117a7 884 }
hsgw 0:845390b117a7 885 sect = clust2sect(fs->curr_clust); /* Get current sector */
hsgw 0:845390b117a7 886 if (!sect) goto fr_abort;
hsgw 0:845390b117a7 887 fs->dsect = sect + cs;
hsgw 0:845390b117a7 888 }
hsgw 0:845390b117a7 889 rcnt = (WORD)(512 - (fs->fptr % 512)); /* Get partial sector data from sector buffer */
hsgw 0:845390b117a7 890 if (rcnt > btr) rcnt = btr;
hsgw 0:845390b117a7 891 dr = disk_readp(!buff ? 0 : rbuff, fs->dsect, (WORD)(fs->fptr % 512), rcnt);
hsgw 0:845390b117a7 892 if (dr) goto fr_abort;
hsgw 0:845390b117a7 893 fs->fptr += rcnt; rbuff += rcnt; /* Update pointers and counters */
hsgw 0:845390b117a7 894 btr -= rcnt; *br += rcnt;
hsgw 0:845390b117a7 895 }
hsgw 0:845390b117a7 896
hsgw 0:845390b117a7 897 return FR_OK;
hsgw 0:845390b117a7 898
hsgw 0:845390b117a7 899 fr_abort:
hsgw 0:845390b117a7 900 fs->flag = 0;
hsgw 0:845390b117a7 901 return FR_DISK_ERR;
hsgw 0:845390b117a7 902 }
hsgw 0:845390b117a7 903 #endif
hsgw 0:845390b117a7 904
hsgw 0:845390b117a7 905
hsgw 0:845390b117a7 906
hsgw 0:845390b117a7 907 /*-----------------------------------------------------------------------*/
hsgw 0:845390b117a7 908 /* Write File */
hsgw 0:845390b117a7 909 /*-----------------------------------------------------------------------*/
hsgw 0:845390b117a7 910 #if _USE_WRITE
hsgw 0:845390b117a7 911
hsgw 0:845390b117a7 912 FRESULT pf_write (
hsgw 0:845390b117a7 913 const void* buff, /* Pointer to the data to be written */
hsgw 0:845390b117a7 914 WORD btw, /* Number of bytes to write (0:Finalize the current write operation) */
hsgw 0:845390b117a7 915 WORD* bw /* Pointer to number of bytes written */
hsgw 0:845390b117a7 916 )
hsgw 0:845390b117a7 917 {
hsgw 0:845390b117a7 918 CLUST clst;
hsgw 0:845390b117a7 919 DWORD sect, remain;
hsgw 0:845390b117a7 920 const BYTE *p =(const BYTE *) buff;
hsgw 0:845390b117a7 921 BYTE cs;
hsgw 0:845390b117a7 922 WORD wcnt;
hsgw 0:845390b117a7 923 FATFS *fs = FatFs;
hsgw 0:845390b117a7 924
hsgw 0:845390b117a7 925
hsgw 0:845390b117a7 926 *bw = 0;
hsgw 0:845390b117a7 927 if (!fs) return FR_NOT_ENABLED; /* Check file system */
hsgw 0:845390b117a7 928 if (!(fs->flag & FA_OPENED)) /* Check if opened */
hsgw 0:845390b117a7 929 return FR_NOT_OPENED;
hsgw 0:845390b117a7 930
hsgw 0:845390b117a7 931 if (!btw) { /* Finalize request */
hsgw 0:845390b117a7 932 if ((fs->flag & FA__WIP) && disk_writep(0, 0)) goto fw_abort;
hsgw 0:845390b117a7 933 fs->flag &= ~FA__WIP;
hsgw 0:845390b117a7 934 return FR_OK;
hsgw 0:845390b117a7 935 } else { /* Write data request */
hsgw 0:845390b117a7 936 if (!(fs->flag & FA__WIP)) /* Round-down fptr to the sector boundary */
hsgw 0:845390b117a7 937 fs->fptr &= 0xFFFFFE00;
hsgw 0:845390b117a7 938 }
hsgw 0:845390b117a7 939 remain = fs->fsize - fs->fptr;
hsgw 0:845390b117a7 940 if (btw > remain) btw = (WORD)remain; /* Truncate btw by remaining bytes */
hsgw 0:845390b117a7 941
hsgw 0:845390b117a7 942 while (btw) { /* Repeat until all data transferred */
hsgw 0:845390b117a7 943 if (((WORD)fs->fptr % 512) == 0) { /* On the sector boundary? */
hsgw 0:845390b117a7 944 cs = (BYTE)(fs->fptr / 512 & (fs->csize - 1)); /* Sector offset in the cluster */
hsgw 0:845390b117a7 945 if (!cs) { /* On the cluster boundary? */
hsgw 0:845390b117a7 946 clst = (fs->fptr == 0) ? /* On the top of the file? */
hsgw 0:845390b117a7 947 fs->org_clust : get_fat(fs->curr_clust);
hsgw 0:845390b117a7 948 if (clst <= 1) goto fw_abort;
hsgw 0:845390b117a7 949 fs->curr_clust = clst; /* Update current cluster */
hsgw 0:845390b117a7 950 }
hsgw 0:845390b117a7 951 sect = clust2sect(fs->curr_clust); /* Get current sector */
hsgw 0:845390b117a7 952 if (!sect) goto fw_abort;
hsgw 0:845390b117a7 953 fs->dsect = sect + cs;
hsgw 0:845390b117a7 954 if (disk_writep(0, fs->dsect)) goto fw_abort; /* Initiate a sector write operation */
hsgw 0:845390b117a7 955 fs->flag |= FA__WIP;
hsgw 0:845390b117a7 956 }
hsgw 0:845390b117a7 957 wcnt = 512 - ((WORD)fs->fptr % 512); /* Number of bytes to write to the sector */
hsgw 0:845390b117a7 958 if (wcnt > btw) wcnt = btw;
hsgw 0:845390b117a7 959 if (disk_writep(p, wcnt)) goto fw_abort; /* Send data to the sector */
hsgw 0:845390b117a7 960 fs->fptr += wcnt; p += wcnt; /* Update pointers and counters */
hsgw 0:845390b117a7 961 btw -= wcnt; *bw += wcnt;
hsgw 0:845390b117a7 962 if (((WORD)fs->fptr % 512) == 0) {
hsgw 0:845390b117a7 963 if (disk_writep(0, 0)) goto fw_abort; /* Finalize the currtent secter write operation */
hsgw 0:845390b117a7 964 fs->flag &= ~FA__WIP;
hsgw 0:845390b117a7 965 }
hsgw 0:845390b117a7 966 }
hsgw 0:845390b117a7 967
hsgw 0:845390b117a7 968 return FR_OK;
hsgw 0:845390b117a7 969
hsgw 0:845390b117a7 970 fw_abort:
hsgw 0:845390b117a7 971 fs->flag = 0;
hsgw 0:845390b117a7 972 return FR_DISK_ERR;
hsgw 0:845390b117a7 973 }
hsgw 0:845390b117a7 974 #endif
hsgw 0:845390b117a7 975
hsgw 0:845390b117a7 976
hsgw 0:845390b117a7 977
hsgw 0:845390b117a7 978 /*-----------------------------------------------------------------------*/
hsgw 0:845390b117a7 979 /* Seek File R/W Pointer */
hsgw 0:845390b117a7 980 /*-----------------------------------------------------------------------*/
hsgw 0:845390b117a7 981 #if _USE_LSEEK
hsgw 0:845390b117a7 982
hsgw 0:845390b117a7 983 FRESULT pf_lseek (
hsgw 0:845390b117a7 984 DWORD ofs /* File pointer from top of file */
hsgw 0:845390b117a7 985 )
hsgw 0:845390b117a7 986 {
hsgw 0:845390b117a7 987 CLUST clst;
hsgw 0:845390b117a7 988 DWORD bcs, sect, ifptr;
hsgw 0:845390b117a7 989 FATFS *fs = FatFs;
hsgw 0:845390b117a7 990
hsgw 0:845390b117a7 991
hsgw 0:845390b117a7 992 if (!fs) return FR_NOT_ENABLED; /* Check file system */
hsgw 0:845390b117a7 993 if (!(fs->flag & FA_OPENED)) /* Check if opened */
hsgw 0:845390b117a7 994 return FR_NOT_OPENED;
hsgw 0:845390b117a7 995
hsgw 0:845390b117a7 996 if (ofs > fs->fsize) ofs = fs->fsize; /* Clip offset with the file size */
hsgw 0:845390b117a7 997 ifptr = fs->fptr;
hsgw 0:845390b117a7 998 fs->fptr = 0;
hsgw 0:845390b117a7 999 if (ofs > 0) {
hsgw 0:845390b117a7 1000 bcs = (DWORD)fs->csize * 512; /* Cluster size (byte) */
hsgw 0:845390b117a7 1001 if (ifptr > 0 &&
hsgw 0:845390b117a7 1002 (ofs - 1) / bcs >= (ifptr - 1) / bcs) { /* When seek to same or following cluster, */
hsgw 0:845390b117a7 1003 fs->fptr = (ifptr - 1) & ~(bcs - 1); /* start from the current cluster */
hsgw 0:845390b117a7 1004 ofs -= fs->fptr;
hsgw 0:845390b117a7 1005 clst = fs->curr_clust;
hsgw 0:845390b117a7 1006 } else { /* When seek to back cluster, */
hsgw 0:845390b117a7 1007 clst = fs->org_clust; /* start from the first cluster */
hsgw 0:845390b117a7 1008 fs->curr_clust = clst;
hsgw 0:845390b117a7 1009 }
hsgw 0:845390b117a7 1010 while (ofs > bcs) { /* Cluster following loop */
hsgw 0:845390b117a7 1011 clst = get_fat(clst); /* Follow cluster chain */
hsgw 0:845390b117a7 1012 if (clst <= 1 || clst >= fs->n_fatent) goto fe_abort;
hsgw 0:845390b117a7 1013 fs->curr_clust = clst;
hsgw 0:845390b117a7 1014 fs->fptr += bcs;
hsgw 0:845390b117a7 1015 ofs -= bcs;
hsgw 0:845390b117a7 1016 }
hsgw 0:845390b117a7 1017 fs->fptr += ofs;
hsgw 0:845390b117a7 1018 sect = clust2sect(clst); /* Current sector */
hsgw 0:845390b117a7 1019 if (!sect) goto fe_abort;
hsgw 0:845390b117a7 1020 fs->dsect = sect + (fs->fptr / 512 & (fs->csize - 1));
hsgw 0:845390b117a7 1021 }
hsgw 0:845390b117a7 1022
hsgw 0:845390b117a7 1023 return FR_OK;
hsgw 0:845390b117a7 1024
hsgw 0:845390b117a7 1025 fe_abort:
hsgw 0:845390b117a7 1026 fs->flag = 0;
hsgw 0:845390b117a7 1027 return FR_DISK_ERR;
hsgw 0:845390b117a7 1028 }
hsgw 0:845390b117a7 1029 #endif
hsgw 0:845390b117a7 1030
hsgw 0:845390b117a7 1031
hsgw 0:845390b117a7 1032
hsgw 0:845390b117a7 1033 /*-----------------------------------------------------------------------*/
hsgw 0:845390b117a7 1034 /* Create a Directroy Object */
hsgw 0:845390b117a7 1035 /*-----------------------------------------------------------------------*/
hsgw 0:845390b117a7 1036 #if _USE_DIR
hsgw 0:845390b117a7 1037
hsgw 0:845390b117a7 1038 FRESULT pf_opendir (
hsgw 0:845390b117a7 1039 PFFDIR *dj, /* Pointer to directory object to create */
hsgw 0:845390b117a7 1040 const char *path /* Pointer to the directory path */
hsgw 0:845390b117a7 1041 )
hsgw 0:845390b117a7 1042 {
hsgw 0:845390b117a7 1043 FRESULT res;
hsgw 0:845390b117a7 1044 BYTE sp[12], dir[32];
hsgw 0:845390b117a7 1045 FATFS *fs = FatFs;
hsgw 0:845390b117a7 1046
hsgw 0:845390b117a7 1047
hsgw 0:845390b117a7 1048 if (!fs) { /* Check file system */
hsgw 0:845390b117a7 1049 res = FR_NOT_ENABLED;
hsgw 0:845390b117a7 1050 } else {
hsgw 0:845390b117a7 1051 dj->fn = sp;
hsgw 0:845390b117a7 1052 res = follow_path(dj, dir, path); /* Follow the path to the directory */
hsgw 0:845390b117a7 1053 if (res == FR_OK) { /* Follow completed */
hsgw 0:845390b117a7 1054 if (dir[0]) { /* It is not the root dir */
hsgw 0:845390b117a7 1055 if (dir[PFFDIR_Attr] & AM_DIR) /* The object is a directory */
hsgw 0:845390b117a7 1056 dj->sclust = LD_CLUST(dir);
hsgw 0:845390b117a7 1057 else /* The object is not a directory */
hsgw 0:845390b117a7 1058 res = FR_NO_PATH;
hsgw 0:845390b117a7 1059 }
hsgw 0:845390b117a7 1060 if (res == FR_OK)
hsgw 0:845390b117a7 1061 res = dir_rewind(dj); /* Rewind dir */
hsgw 0:845390b117a7 1062 }
hsgw 0:845390b117a7 1063 if (res == FR_NO_FILE) res = FR_NO_PATH;
hsgw 0:845390b117a7 1064 }
hsgw 0:845390b117a7 1065
hsgw 0:845390b117a7 1066 return res;
hsgw 0:845390b117a7 1067 }
hsgw 0:845390b117a7 1068
hsgw 0:845390b117a7 1069
hsgw 0:845390b117a7 1070
hsgw 0:845390b117a7 1071
hsgw 0:845390b117a7 1072 /*-----------------------------------------------------------------------*/
hsgw 0:845390b117a7 1073 /* Read Directory Entry in Sequense */
hsgw 0:845390b117a7 1074 /*-----------------------------------------------------------------------*/
hsgw 0:845390b117a7 1075
hsgw 0:845390b117a7 1076 FRESULT pf_readdir (
hsgw 0:845390b117a7 1077 PFFDIR *dj, /* Pointer to the open directory object */
hsgw 0:845390b117a7 1078 FILINFO *fno /* Pointer to file information to return */
hsgw 0:845390b117a7 1079 )
hsgw 0:845390b117a7 1080 {
hsgw 0:845390b117a7 1081 FRESULT res;
hsgw 0:845390b117a7 1082 BYTE sp[12], dir[32];
hsgw 0:845390b117a7 1083 FATFS *fs = FatFs;
hsgw 0:845390b117a7 1084
hsgw 0:845390b117a7 1085
hsgw 0:845390b117a7 1086 if (!fs) { /* Check file system */
hsgw 0:845390b117a7 1087 res = FR_NOT_ENABLED;
hsgw 0:845390b117a7 1088 } else {
hsgw 0:845390b117a7 1089 dj->fn = sp;
hsgw 0:845390b117a7 1090 if (!fno) {
hsgw 0:845390b117a7 1091 res = dir_rewind(dj);
hsgw 0:845390b117a7 1092 } else {
hsgw 0:845390b117a7 1093 res = dir_read(dj, dir);
hsgw 0:845390b117a7 1094 if (res == FR_NO_FILE) {
hsgw 0:845390b117a7 1095 dj->sect = 0;
hsgw 0:845390b117a7 1096 res = FR_OK;
hsgw 0:845390b117a7 1097 }
hsgw 0:845390b117a7 1098 if (res == FR_OK) { /* A valid entry is found */
hsgw 0:845390b117a7 1099 get_fileinfo(dj, dir, fno); /* Get the object information */
hsgw 0:845390b117a7 1100 res = dir_next(dj); /* Increment index for next */
hsgw 0:845390b117a7 1101 if (res == FR_NO_FILE) {
hsgw 0:845390b117a7 1102 dj->sect = 0;
hsgw 0:845390b117a7 1103 res = FR_OK;
hsgw 0:845390b117a7 1104 }
hsgw 0:845390b117a7 1105 }
hsgw 0:845390b117a7 1106 }
hsgw 0:845390b117a7 1107 }
hsgw 0:845390b117a7 1108
hsgw 0:845390b117a7 1109 return res;
hsgw 0:845390b117a7 1110 }
hsgw 0:845390b117a7 1111
hsgw 0:845390b117a7 1112 #endif /* _USE_DIR */
hsgw 0:845390b117a7 1113