2006-02-16 23:23:37 +00:00
|
|
|
|
/*
|
|
|
|
|
* Copyright 2004 Martin Fuchs
|
|
|
|
|
*
|
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
* License along with this library; if not, write to the Free Software
|
2009-10-27 10:34:16 +00:00
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
2006-02-16 23:23:37 +00:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Explorer clone
|
|
|
|
|
//
|
|
|
|
|
// fatfs.h
|
|
|
|
|
//
|
|
|
|
|
// Martin Fuchs, 01.02.2004
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// FAT file system file-entry
|
|
|
|
|
struct FATEntry : public Entry
|
|
|
|
|
{
|
|
|
|
|
FATEntry(Entry* parent, unsigned cluster) : Entry(parent, ET_FAT), _cluster(cluster) {}
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
FATEntry() : Entry(ET_FAT) {}
|
|
|
|
|
|
|
|
|
|
virtual bool get_path(PTSTR path, size_t path_count) const;
|
|
|
|
|
virtual ShellPath create_absolute_pidl() const;
|
|
|
|
|
|
|
|
|
|
DWORD _cluster;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct FATDrive;
|
|
|
|
|
|
|
|
|
|
/// FAT file system directory-entry
|
|
|
|
|
struct FATDirectory : public FATEntry, public Directory
|
|
|
|
|
{
|
|
|
|
|
FATDirectory(FATDrive& drive, LPCTSTR root_path);
|
|
|
|
|
FATDirectory(FATDrive& drive, Entry* parent, LPCTSTR path, unsigned cluster);
|
|
|
|
|
~FATDirectory();
|
|
|
|
|
|
|
|
|
|
virtual void read_directory(int scan_flags=0);
|
|
|
|
|
virtual const void* get_next_path_component(const void*) const;
|
|
|
|
|
virtual Entry* find_entry(const void*);
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
FATDrive& _drive;
|
|
|
|
|
|
|
|
|
|
struct dirsecz* _secarr;
|
|
|
|
|
int _cur_bufs;
|
|
|
|
|
int _ents;
|
|
|
|
|
struct dirent* _dir;
|
|
|
|
|
struct Kette* _alloc;
|
|
|
|
|
|
|
|
|
|
bool read_dir();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#pragma pack(push, 1)
|
|
|
|
|
|
|
|
|
|
struct BootSector {
|
|
|
|
|
BYTE jmp[3];
|
|
|
|
|
char OEM[8];
|
|
|
|
|
WORD BytesPerSector; // dpb.bsec
|
|
|
|
|
BYTE SectorsPerCluster; // dpb.sclus + 1
|
|
|
|
|
WORD ReservedSectors; // dpb.ffatsec
|
|
|
|
|
BYTE NumberFATs;
|
|
|
|
|
WORD RootEntries; // dpb.ndir
|
|
|
|
|
WORD Sectors16;
|
|
|
|
|
BYTE MediaDescr;
|
|
|
|
|
WORD SectorsPerFAT;
|
|
|
|
|
WORD SectorsPerTrack;
|
|
|
|
|
WORD Heads;
|
|
|
|
|
DWORD HiddenSectors;
|
|
|
|
|
DWORD Sectors32;
|
|
|
|
|
BYTE DriveUnit;
|
|
|
|
|
WORD ExtBootFlag;
|
|
|
|
|
DWORD SerialNr;
|
|
|
|
|
char Label[11];
|
|
|
|
|
char FileSystem[8];
|
|
|
|
|
BYTE BootCode[448];
|
|
|
|
|
BYTE BootSignature[2];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct BootSector32 {
|
|
|
|
|
BYTE jmp[3];
|
|
|
|
|
char OEM[8];
|
|
|
|
|
WORD BytesPerSector;
|
|
|
|
|
BYTE SectorsPerCluster;
|
|
|
|
|
WORD ReservedSectors;
|
|
|
|
|
BYTE NumberFATs;
|
|
|
|
|
WORD reserved1; // immer 0 f<>r FAT32
|
|
|
|
|
WORD Sectors16;
|
|
|
|
|
BYTE MediaDescr;
|
|
|
|
|
WORD reserved2; // immer 0 f<>r FAT32
|
|
|
|
|
WORD SectorsPerTrack;
|
|
|
|
|
WORD Heads;
|
|
|
|
|
DWORD HiddenSectors;
|
|
|
|
|
DWORD Sectors32;
|
|
|
|
|
DWORD SectorsPerFAT32;
|
|
|
|
|
DWORD unknown1;
|
|
|
|
|
DWORD RootSectors; // correct?
|
|
|
|
|
char unknown2[6];
|
|
|
|
|
char FileSystem[8];
|
|
|
|
|
BYTE BootCode[448];
|
|
|
|
|
BYTE BootSignature[2];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2008-12-13 21:28:05 +00:00
|
|
|
|
struct filetime {
|
2006-02-16 23:23:37 +00:00
|
|
|
|
WORD sec2 : 5;
|
|
|
|
|
WORD min : 6;
|
|
|
|
|
WORD hour : 5;
|
|
|
|
|
};
|
|
|
|
|
|
2008-12-13 21:28:05 +00:00
|
|
|
|
struct filedate {
|
2006-02-16 23:23:37 +00:00
|
|
|
|
WORD day : 5;
|
|
|
|
|
WORD month : 4;
|
|
|
|
|
WORD year : 7;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
unsigned readonly : 1;
|
|
|
|
|
unsigned hidden : 1;
|
|
|
|
|
unsigned system : 1;
|
|
|
|
|
unsigned volume : 1;
|
|
|
|
|
unsigned directory : 1;
|
|
|
|
|
unsigned archived : 1;
|
|
|
|
|
unsigned deleted : 1;
|
|
|
|
|
} fattr;
|
|
|
|
|
|
|
|
|
|
typedef union {
|
|
|
|
|
char b;
|
|
|
|
|
fattr a;
|
|
|
|
|
} FAT_attribute;
|
|
|
|
|
|
|
|
|
|
struct DEntry_E {
|
|
|
|
|
char name[8];
|
|
|
|
|
char ext[3];
|
|
|
|
|
char attr;
|
|
|
|
|
char rsrvd[10];
|
2008-12-13 21:28:05 +00:00
|
|
|
|
struct filetime time;
|
|
|
|
|
struct filedate date;
|
2006-02-16 23:23:37 +00:00
|
|
|
|
WORD fclus;
|
|
|
|
|
DWORD size;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
union DEntry {
|
|
|
|
|
DEntry_E E;
|
2008-12-13 21:28:05 +00:00
|
|
|
|
BYTE B[8+3+1+10+sizeof(struct filetime)+sizeof(struct filedate)+sizeof(WORD)+sizeof(DWORD)];
|
2006-02-16 23:23:37 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#pragma pack(pop)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define BufLen 512
|
|
|
|
|
|
|
|
|
|
struct Buffer {
|
|
|
|
|
BYTE dat[BufLen];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct Cache {
|
|
|
|
|
BYTE dat[BufLen];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct dskrwblk {
|
|
|
|
|
DWORD sec;
|
|
|
|
|
WORD anz;
|
|
|
|
|
struct buffer far *buf;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#define RONLY 0x01
|
|
|
|
|
#define HIDDEN 0x02
|
|
|
|
|
#define SYSTEM 0x04
|
|
|
|
|
#define VOLUME 0x08
|
|
|
|
|
#define DIRENT 0x10
|
|
|
|
|
#define ARCHIVE 0x20
|
|
|
|
|
|
|
|
|
|
#define _A_DELETED 0x40
|
|
|
|
|
#define _A_ILLEGAL 0x80
|
|
|
|
|
#define IS_LNAME(a) ((a&0xFF)==0x0F) // "& 0xFF" correct?
|
|
|
|
|
|
|
|
|
|
#define FAT_DEL_CHAR (char)0xe5
|
|
|
|
|
|
|
|
|
|
#define AddP(p,s) {(int&)p += s;}
|
|
|
|
|
|
|
|
|
|
struct dirent {
|
|
|
|
|
union DEntry ent[1];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct dirsecz {
|
|
|
|
|
DWORD s[32]; // 32 only as placeholder
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct Kette {
|
|
|
|
|
struct Kette* Vorw;
|
|
|
|
|
struct Kette* Rueck;
|
|
|
|
|
union DEntry* Ent;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define MK_P(ofs) ((void*) ((size_t)(ofs)))
|
|
|
|
|
#define MK_LONG(l,h) ((DWORD)WORD(l)|((DWORD)WORD(h)<<16))
|
|
|
|
|
|
|
|
|
|
#define spoke(ofs,w) (*((BYTE*)MK_P(ofs)) = (BYTE)(w))
|
|
|
|
|
#define wpoke(ofs,w) (*((WORD*)MK_P(ofs)) = (WORD)(w))
|
|
|
|
|
#define dpoke(ofs,w) (*((DWORD*)MK_P(ofs)) = (DWORD)(w))
|
|
|
|
|
#define speek(ofs) (*((BYTE*)MK_P(ofs)))
|
|
|
|
|
#define wpeek(ofs) (*((WORD*)MK_P(ofs)))
|
|
|
|
|
#define dpeek(p) (*((DWORD*)MK_P(p)))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// FAT drive root entry
|
|
|
|
|
struct FATDrive : public FATDirectory
|
|
|
|
|
{
|
|
|
|
|
FATDrive(LPCTSTR path);
|
|
|
|
|
/*
|
|
|
|
|
FATDrive(Entry* parent, LPCTSTR path)
|
|
|
|
|
: FATEntry(parent)
|
|
|
|
|
{
|
|
|
|
|
_path = _tcsdup(path);
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
~FATDrive();
|
|
|
|
|
|
|
|
|
|
HANDLE _hDrive;
|
|
|
|
|
BootSector _boot_sector;
|
|
|
|
|
int _bufl;
|
|
|
|
|
int _bufents;
|
|
|
|
|
int _SClus;
|
|
|
|
|
|
|
|
|
|
#define CACHE_SIZE_LOW 32
|
|
|
|
|
Cache* _FATCache;
|
|
|
|
|
int _CacheCount;
|
|
|
|
|
DWORD* _CacheSec; // numbers of buffered cache sectors
|
|
|
|
|
int* _CacheCnt; // counters for cache usage
|
|
|
|
|
bool* _CacheDty; // dirty flags for cache
|
|
|
|
|
int _Caches;
|
|
|
|
|
bool _cache_empty;
|
|
|
|
|
int _read_ahead;
|
|
|
|
|
|
|
|
|
|
bool read_sector(DWORD sec, Buffer* buf, int len);
|
|
|
|
|
DWORD read_FAT(DWORD Clus, bool& ok);
|
|
|
|
|
|
|
|
|
|
void small_cache();
|
|
|
|
|
void reset_cache();
|
|
|
|
|
bool read_cache(DWORD sec, Buffer** bufptr);
|
|
|
|
|
int get_cache_buffer();
|
|
|
|
|
};
|