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