1*c2c66affSColin Finck /* 2*c2c66affSColin Finck * Copyright 2004 Martin Fuchs 3*c2c66affSColin Finck * 4*c2c66affSColin Finck * This library is free software; you can redistribute it and/or 5*c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public 6*c2c66affSColin Finck * License as published by the Free Software Foundation; either 7*c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version. 8*c2c66affSColin Finck * 9*c2c66affSColin Finck * This library is distributed in the hope that it will be useful, 10*c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of 11*c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12*c2c66affSColin Finck * Lesser General Public License for more details. 13*c2c66affSColin Finck * 14*c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public 15*c2c66affSColin Finck * License along with this library; if not, write to the Free Software 16*c2c66affSColin Finck * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17*c2c66affSColin Finck */ 18*c2c66affSColin Finck 19*c2c66affSColin Finck 20*c2c66affSColin Finck // 21*c2c66affSColin Finck // Explorer clone 22*c2c66affSColin Finck // 23*c2c66affSColin Finck // fatfs.h 24*c2c66affSColin Finck // 25*c2c66affSColin Finck // Martin Fuchs, 01.02.2004 26*c2c66affSColin Finck // 27*c2c66affSColin Finck 28*c2c66affSColin Finck 29*c2c66affSColin Finck /// FAT file system file-entry 30*c2c66affSColin Finck struct FATEntry : public Entry 31*c2c66affSColin Finck { FATEntryFATEntry32*c2c66affSColin Finck FATEntry(Entry* parent, unsigned cluster) : Entry(parent, ET_FAT), _cluster(cluster) {} 33*c2c66affSColin Finck 34*c2c66affSColin Finck protected: FATEntryFATEntry35*c2c66affSColin Finck FATEntry() : Entry(ET_FAT) {} 36*c2c66affSColin Finck 37*c2c66affSColin Finck virtual bool get_path(PTSTR path, size_t path_count) const; 38*c2c66affSColin Finck virtual ShellPath create_absolute_pidl() const; 39*c2c66affSColin Finck 40*c2c66affSColin Finck DWORD _cluster; 41*c2c66affSColin Finck }; 42*c2c66affSColin Finck 43*c2c66affSColin Finck 44*c2c66affSColin Finck struct FATDrive; 45*c2c66affSColin Finck 46*c2c66affSColin Finck /// FAT file system directory-entry 47*c2c66affSColin Finck struct FATDirectory : public FATEntry, public Directory 48*c2c66affSColin Finck { 49*c2c66affSColin Finck FATDirectory(FATDrive& drive, LPCTSTR root_path); 50*c2c66affSColin Finck FATDirectory(FATDrive& drive, Entry* parent, LPCTSTR path, unsigned cluster); 51*c2c66affSColin Finck ~FATDirectory(); 52*c2c66affSColin Finck 53*c2c66affSColin Finck virtual void read_directory(int scan_flags=0); 54*c2c66affSColin Finck virtual const void* get_next_path_component(const void*) const; 55*c2c66affSColin Finck virtual Entry* find_entry(const void*); 56*c2c66affSColin Finck 57*c2c66affSColin Finck protected: 58*c2c66affSColin Finck FATDrive& _drive; 59*c2c66affSColin Finck 60*c2c66affSColin Finck struct dirsecz* _secarr; 61*c2c66affSColin Finck int _cur_bufs; 62*c2c66affSColin Finck int _ents; 63*c2c66affSColin Finck struct dirent* _dir; 64*c2c66affSColin Finck struct Kette* _alloc; 65*c2c66affSColin Finck 66*c2c66affSColin Finck bool read_dir(); 67*c2c66affSColin Finck }; 68*c2c66affSColin Finck 69*c2c66affSColin Finck 70*c2c66affSColin Finck #pragma pack(push, 1) 71*c2c66affSColin Finck 72*c2c66affSColin Finck struct BootSector { 73*c2c66affSColin Finck BYTE jmp[3]; 74*c2c66affSColin Finck char OEM[8]; 75*c2c66affSColin Finck WORD BytesPerSector; // dpb.bsec 76*c2c66affSColin Finck BYTE SectorsPerCluster; // dpb.sclus + 1 77*c2c66affSColin Finck WORD ReservedSectors; // dpb.ffatsec 78*c2c66affSColin Finck BYTE NumberFATs; 79*c2c66affSColin Finck WORD RootEntries; // dpb.ndir 80*c2c66affSColin Finck WORD Sectors16; 81*c2c66affSColin Finck BYTE MediaDescr; 82*c2c66affSColin Finck WORD SectorsPerFAT; 83*c2c66affSColin Finck WORD SectorsPerTrack; 84*c2c66affSColin Finck WORD Heads; 85*c2c66affSColin Finck DWORD HiddenSectors; 86*c2c66affSColin Finck DWORD Sectors32; 87*c2c66affSColin Finck BYTE DriveUnit; 88*c2c66affSColin Finck WORD ExtBootFlag; 89*c2c66affSColin Finck DWORD SerialNr; 90*c2c66affSColin Finck char Label[11]; 91*c2c66affSColin Finck char FileSystem[8]; 92*c2c66affSColin Finck BYTE BootCode[448]; 93*c2c66affSColin Finck BYTE BootSignature[2]; 94*c2c66affSColin Finck }; 95*c2c66affSColin Finck 96*c2c66affSColin Finck struct BootSector32 { 97*c2c66affSColin Finck BYTE jmp[3]; 98*c2c66affSColin Finck char OEM[8]; 99*c2c66affSColin Finck WORD BytesPerSector; 100*c2c66affSColin Finck BYTE SectorsPerCluster; 101*c2c66affSColin Finck WORD ReservedSectors; 102*c2c66affSColin Finck BYTE NumberFATs; 103*c2c66affSColin Finck WORD reserved1; // immer 0 f�r FAT32 104*c2c66affSColin Finck WORD Sectors16; 105*c2c66affSColin Finck BYTE MediaDescr; 106*c2c66affSColin Finck WORD reserved2; // immer 0 f�r FAT32 107*c2c66affSColin Finck WORD SectorsPerTrack; 108*c2c66affSColin Finck WORD Heads; 109*c2c66affSColin Finck DWORD HiddenSectors; 110*c2c66affSColin Finck DWORD Sectors32; 111*c2c66affSColin Finck DWORD SectorsPerFAT32; 112*c2c66affSColin Finck DWORD unknown1; 113*c2c66affSColin Finck DWORD RootSectors; // correct? 114*c2c66affSColin Finck char unknown2[6]; 115*c2c66affSColin Finck char FileSystem[8]; 116*c2c66affSColin Finck BYTE BootCode[448]; 117*c2c66affSColin Finck BYTE BootSignature[2]; 118*c2c66affSColin Finck }; 119*c2c66affSColin Finck 120*c2c66affSColin Finck 121*c2c66affSColin Finck struct filetime { 122*c2c66affSColin Finck WORD sec2 : 5; 123*c2c66affSColin Finck WORD min : 6; 124*c2c66affSColin Finck WORD hour : 5; 125*c2c66affSColin Finck }; 126*c2c66affSColin Finck 127*c2c66affSColin Finck struct filedate { 128*c2c66affSColin Finck WORD day : 5; 129*c2c66affSColin Finck WORD month : 4; 130*c2c66affSColin Finck WORD year : 7; 131*c2c66affSColin Finck }; 132*c2c66affSColin Finck 133*c2c66affSColin Finck typedef struct { 134*c2c66affSColin Finck unsigned readonly : 1; 135*c2c66affSColin Finck unsigned hidden : 1; 136*c2c66affSColin Finck unsigned system : 1; 137*c2c66affSColin Finck unsigned volume : 1; 138*c2c66affSColin Finck unsigned directory : 1; 139*c2c66affSColin Finck unsigned archived : 1; 140*c2c66affSColin Finck unsigned deleted : 1; 141*c2c66affSColin Finck } fattr; 142*c2c66affSColin Finck 143*c2c66affSColin Finck typedef union { 144*c2c66affSColin Finck char b; 145*c2c66affSColin Finck fattr a; 146*c2c66affSColin Finck } FAT_attribute; 147*c2c66affSColin Finck 148*c2c66affSColin Finck struct DEntry_E { 149*c2c66affSColin Finck char name[8]; 150*c2c66affSColin Finck char ext[3]; 151*c2c66affSColin Finck char attr; 152*c2c66affSColin Finck char rsrvd[10]; 153*c2c66affSColin Finck struct filetime time; 154*c2c66affSColin Finck struct filedate date; 155*c2c66affSColin Finck WORD fclus; 156*c2c66affSColin Finck DWORD size; 157*c2c66affSColin Finck }; 158*c2c66affSColin Finck 159*c2c66affSColin Finck union DEntry { 160*c2c66affSColin Finck DEntry_E E; 161*c2c66affSColin Finck BYTE B[8+3+1+10+sizeof(struct filetime)+sizeof(struct filedate)+sizeof(WORD)+sizeof(DWORD)]; 162*c2c66affSColin Finck }; 163*c2c66affSColin Finck 164*c2c66affSColin Finck #pragma pack(pop) 165*c2c66affSColin Finck 166*c2c66affSColin Finck 167*c2c66affSColin Finck #define BufLen 512 168*c2c66affSColin Finck 169*c2c66affSColin Finck struct Buffer { 170*c2c66affSColin Finck BYTE dat[BufLen]; 171*c2c66affSColin Finck }; 172*c2c66affSColin Finck 173*c2c66affSColin Finck struct Cache { 174*c2c66affSColin Finck BYTE dat[BufLen]; 175*c2c66affSColin Finck }; 176*c2c66affSColin Finck 177*c2c66affSColin Finck struct dskrwblk { 178*c2c66affSColin Finck DWORD sec; 179*c2c66affSColin Finck WORD anz; 180*c2c66affSColin Finck struct buffer far *buf; 181*c2c66affSColin Finck }; 182*c2c66affSColin Finck 183*c2c66affSColin Finck #define RONLY 0x01 184*c2c66affSColin Finck #define HIDDEN 0x02 185*c2c66affSColin Finck #define SYSTEM 0x04 186*c2c66affSColin Finck #define VOLUME 0x08 187*c2c66affSColin Finck #define DIRENT 0x10 188*c2c66affSColin Finck #define ARCHIVE 0x20 189*c2c66affSColin Finck 190*c2c66affSColin Finck #define _A_DELETED 0x40 191*c2c66affSColin Finck #define _A_ILLEGAL 0x80 192*c2c66affSColin Finck #define IS_LNAME(a) ((a&0xFF)==0x0F) // "& 0xFF" correct? 193*c2c66affSColin Finck 194*c2c66affSColin Finck #define FAT_DEL_CHAR (char)0xe5 195*c2c66affSColin Finck 196*c2c66affSColin Finck #define AddP(p,s) {(int&)p += s;} 197*c2c66affSColin Finck 198*c2c66affSColin Finck struct dirent { 199*c2c66affSColin Finck union DEntry ent[1]; 200*c2c66affSColin Finck }; 201*c2c66affSColin Finck 202*c2c66affSColin Finck struct dirsecz { 203*c2c66affSColin Finck DWORD s[32]; // 32 only as placeholder 204*c2c66affSColin Finck }; 205*c2c66affSColin Finck 206*c2c66affSColin Finck struct Kette { 207*c2c66affSColin Finck struct Kette* Vorw; 208*c2c66affSColin Finck struct Kette* Rueck; 209*c2c66affSColin Finck union DEntry* Ent; 210*c2c66affSColin Finck }; 211*c2c66affSColin Finck 212*c2c66affSColin Finck 213*c2c66affSColin Finck #define MK_P(ofs) ((void*) ((size_t)(ofs))) 214*c2c66affSColin Finck #define MK_LONG(l,h) ((DWORD)WORD(l)|((DWORD)WORD(h)<<16)) 215*c2c66affSColin Finck 216*c2c66affSColin Finck #define spoke(ofs,w) (*((BYTE*)MK_P(ofs)) = (BYTE)(w)) 217*c2c66affSColin Finck #define wpoke(ofs,w) (*((WORD*)MK_P(ofs)) = (WORD)(w)) 218*c2c66affSColin Finck #define dpoke(ofs,w) (*((DWORD*)MK_P(ofs)) = (DWORD)(w)) 219*c2c66affSColin Finck #define speek(ofs) (*((BYTE*)MK_P(ofs))) 220*c2c66affSColin Finck #define wpeek(ofs) (*((WORD*)MK_P(ofs))) 221*c2c66affSColin Finck #define dpeek(p) (*((DWORD*)MK_P(p))) 222*c2c66affSColin Finck 223*c2c66affSColin Finck 224*c2c66affSColin Finck /// FAT drive root entry 225*c2c66affSColin Finck struct FATDrive : public FATDirectory 226*c2c66affSColin Finck { 227*c2c66affSColin Finck FATDrive(LPCTSTR path); 228*c2c66affSColin Finck /* 229*c2c66affSColin Finck FATDrive(Entry* parent, LPCTSTR path) 230*c2c66affSColin Finck : FATEntry(parent) 231*c2c66affSColin Finck { 232*c2c66affSColin Finck _path = _tcsdup(path); 233*c2c66affSColin Finck } 234*c2c66affSColin Finck */ 235*c2c66affSColin Finck ~FATDrive(); 236*c2c66affSColin Finck 237*c2c66affSColin Finck HANDLE _hDrive; 238*c2c66affSColin Finck BootSector _boot_sector; 239*c2c66affSColin Finck int _bufl; 240*c2c66affSColin Finck int _bufents; 241*c2c66affSColin Finck int _SClus; 242*c2c66affSColin Finck 243*c2c66affSColin Finck #define CACHE_SIZE_LOW 32 244*c2c66affSColin Finck Cache* _FATCache; 245*c2c66affSColin Finck int _CacheCount; 246*c2c66affSColin Finck DWORD* _CacheSec; // numbers of buffered cache sectors 247*c2c66affSColin Finck int* _CacheCnt; // counters for cache usage 248*c2c66affSColin Finck bool* _CacheDty; // dirty flags for cache 249*c2c66affSColin Finck int _Caches; 250*c2c66affSColin Finck bool _cache_empty; 251*c2c66affSColin Finck int _read_ahead; 252*c2c66affSColin Finck 253*c2c66affSColin Finck bool read_sector(DWORD sec, Buffer* buf, int len); 254*c2c66affSColin Finck DWORD read_FAT(DWORD Clus, bool& ok); 255*c2c66affSColin Finck 256*c2c66affSColin Finck void small_cache(); 257*c2c66affSColin Finck void reset_cache(); 258*c2c66affSColin Finck bool read_cache(DWORD sec, Buffer** bufptr); 259*c2c66affSColin Finck int get_cache_buffer(); 260*c2c66affSColin Finck }; 261