]>
Commit | Line | Data |
---|---|---|
57c72a9a A |
1 | /* |
2 | * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. | |
3 | * | |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
6 | * The contents of this file constitute Original Code as defined in and | |
7 | * are subject to the Apple Public Source License Version 2.0 (the | |
8 | * "License"). You may not use this file except in compliance with the | |
9 | * License. Please obtain a copy of the License at | |
10 | * http://www.apple.com/publicsource and read it before using this file. | |
11 | * | |
12 | * This Original Code and all software distributed under the License are | |
13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the | |
17 | * License for the specific language governing rights and limitations | |
18 | * under the License. | |
19 | * | |
20 | * @APPLE_LICENSE_HEADER_END@ | |
21 | */ | |
22 | /* | |
23 | * Written by Paul Popelka (paulp@uts.amdahl.com) | |
24 | * | |
25 | * You can do anything you want with this software, just don't say you wrote | |
26 | * it, and don't remove this notice. | |
27 | * | |
28 | * This software is provided "as is". | |
29 | * | |
30 | * The author supplies this software to be publicly redistributed on the | |
31 | * understanding that the author is not responsible for the correct | |
32 | * functioning of this software in any circumstances and is not liable for | |
33 | * any damages caused by this software. | |
34 | * | |
35 | * October 1992 | |
36 | */ | |
37 | ||
38 | /* | |
39 | * Format of a boot sector. This is the first sector on a DOS floppy disk | |
40 | * or the fist sector of a partition on a hard disk. But, it is not the | |
41 | * first sector of a partitioned hard disk. | |
42 | */ | |
43 | struct bootsector33 { | |
44 | u_int8_t bsJump[3]; /* jump inst E9xxxx or EBxx90 */ | |
45 | int8_t bsOemName[8]; /* OEM name and version */ | |
46 | int8_t bsBPB[19]; /* BIOS parameter block */ | |
47 | int8_t bsDriveNumber; /* drive number (0x80) */ | |
48 | int8_t bsBootCode[479]; /* pad so struct is 512b */ | |
49 | u_int8_t bsBootSectSig0; | |
50 | u_int8_t bsBootSectSig1; | |
51 | #define BOOTSIG0 0x55 | |
52 | #define BOOTSIG1 0xaa | |
53 | }; | |
54 | ||
55 | struct extboot { | |
56 | int8_t exDriveNumber; /* drive number (0x80) */ | |
57 | int8_t exReserved1; /* reserved */ | |
58 | int8_t exBootSignature; /* ext. boot signature (0x29) */ | |
59 | #define EXBOOTSIG 0x29 | |
60 | int8_t exVolumeID[4]; /* volume ID number */ | |
61 | int8_t exVolumeLabel[11]; /* volume label */ | |
62 | int8_t exFileSysType[8]; /* fs type (FAT12 or FAT16) */ | |
63 | }; | |
64 | ||
65 | struct bootsector50 { | |
66 | u_int8_t bsJump[3]; /* jump inst E9xxxx or EBxx90 */ | |
67 | int8_t bsOemName[8]; /* OEM name and version */ | |
68 | int8_t bsBPB[25]; /* BIOS parameter block */ | |
69 | int8_t bsExt[26]; /* Bootsector Extension */ | |
70 | int8_t bsBootCode[448]; /* pad so structure is 512b */ | |
71 | u_int8_t bsBootSectSig0; | |
72 | u_int8_t bsBootSectSig1; | |
73 | #define BOOTSIG0 0x55 | |
74 | #define BOOTSIG1 0xaa | |
75 | }; | |
76 | ||
77 | struct bootsector710 { | |
78 | u_int8_t bsJump[3]; /* jump inst E9xxxx or EBxx90 */ | |
79 | int8_t bsOEMName[8]; /* OEM name and version */ | |
80 | int8_t bsBPB[53]; /* BIOS parameter block */ | |
81 | int8_t bsExt[26]; /* Bootsector Extension */ | |
82 | int8_t bsBootCode[420]; /* pad so structure is 512b */ | |
83 | u_int8_t bsBootSectSig0; | |
84 | u_int8_t bsBootSectSig1; | |
85 | #define BOOTSIG0 0x55 | |
86 | #define BOOTSIG1 0xaa | |
87 | }; | |
88 | ||
89 | union bootsector { | |
90 | struct bootsector33 bs33; | |
91 | struct bootsector50 bs50; | |
92 | struct bootsector710 bs710; | |
93 | }; | |
94 | ||
95 | ||
96 | /* BPB */ | |
97 | ||
98 | /* | |
99 | * BIOS Parameter Block (BPB) for DOS 3.3 | |
100 | */ | |
101 | struct bpb33 { | |
102 | u_int16_t bpbBytesPerSec; /* bytes per sector */ | |
103 | u_int8_t bpbSecPerClust; /* sectors per cluster */ | |
104 | u_int16_t bpbResSectors; /* number of reserved sectors */ | |
105 | u_int8_t bpbFATs; /* number of FATs */ | |
106 | u_int16_t bpbRootDirEnts; /* number of root directory entries */ | |
107 | u_int16_t bpbSectors; /* total number of sectors */ | |
108 | u_int8_t bpbMedia; /* media descriptor */ | |
109 | u_int16_t bpbFATsecs; /* number of sectors per FAT */ | |
110 | u_int16_t bpbSecPerTrack; /* sectors per track */ | |
111 | u_int16_t bpbHeads; /* number of heads */ | |
112 | u_int16_t bpbHiddenSecs; /* number of hidden sectors */ | |
113 | } __attribute__((packed)); | |
114 | ||
115 | /* | |
116 | * BPB for DOS 5.0 The difference is bpbHiddenSecs is a short for DOS 3.3, | |
117 | * and bpbHugeSectors is not in the 3.3 bpb. | |
118 | */ | |
119 | struct bpb50 { | |
120 | u_int16_t bpbBytesPerSec; /* bytes per sector */ | |
121 | u_int8_t bpbSecPerClust; /* sectors per cluster */ | |
122 | u_int16_t bpbResSectors; /* number of reserved sectors */ | |
123 | u_int8_t bpbFATs; /* number of FATs */ | |
124 | u_int16_t bpbRootDirEnts; /* number of root directory entries */ | |
125 | u_int16_t bpbSectors; /* total number of sectors */ | |
126 | u_int8_t bpbMedia; /* media descriptor */ | |
127 | u_int16_t bpbFATsecs; /* number of sectors per FAT */ | |
128 | u_int16_t bpbSecPerTrack; /* sectors per track */ | |
129 | u_int16_t bpbHeads; /* number of heads */ | |
130 | u_int32_t bpbHiddenSecs; /* # of hidden sectors */ | |
131 | u_int32_t bpbHugeSectors; /* # of sectors if bpbSectors == 0 */ | |
132 | } __attribute__((packed)); | |
133 | ||
134 | /* | |
135 | * BPB for DOS 7.10 (FAT32). This one has a few extensions to bpb50. | |
136 | */ | |
137 | struct bpb710 { | |
138 | u_int16_t bpbBytesPerSec; /* bytes per sector */ | |
139 | u_int8_t bpbSecPerClust; /* sectors per cluster */ | |
140 | u_int16_t bpbResSectors; /* number of reserved sectors */ | |
141 | u_int8_t bpbFATs; /* number of FATs */ | |
142 | u_int16_t bpbRootDirEnts; /* number of root directory entries */ | |
143 | u_int16_t bpbSectors; /* total number of sectors */ | |
144 | u_int8_t bpbMedia; /* media descriptor */ | |
145 | u_int16_t bpbFATsecs; /* number of sectors per FAT */ | |
146 | u_int16_t bpbSecPerTrack; /* sectors per track */ | |
147 | u_int16_t bpbHeads; /* number of heads */ | |
148 | u_int32_t bpbHiddenSecs; /* # of hidden sectors */ | |
149 | u_int32_t bpbHugeSectors; /* # of sectors if bpbSectors == 0 */ | |
150 | u_int32_t bpbBigFATsecs; /* like bpbFATsecs for FAT32 */ | |
151 | u_int16_t bpbExtFlags; /* extended flags: */ | |
152 | #define FATNUM 0xf /* mask for numbering active FAT */ | |
153 | #define FATMIRROR 0x80 /* FAT is mirrored (like it always was) */ | |
154 | u_int16_t bpbFSVers; /* filesystem version */ | |
155 | #define FSVERS 0 /* currently only 0 is understood */ | |
156 | u_int32_t bpbRootClust; /* start cluster for root directory */ | |
157 | u_int16_t bpbFSInfo; /* filesystem info structure sector */ | |
158 | u_int16_t bpbBackup; /* backup boot sector */ | |
159 | /* There is a 12 byte filler here, but we ignore it */ | |
160 | } __attribute__((packed)); | |
161 | ||
162 | #if 0 | |
163 | /* | |
164 | * BIOS Parameter Block (BPB) for DOS 3.3 | |
165 | */ | |
166 | struct byte_bpb33 { | |
167 | int8_t bpbBytesPerSec[2]; /* bytes per sector */ | |
168 | int8_t bpbSecPerClust; /* sectors per cluster */ | |
169 | int8_t bpbResSectors[2]; /* number of reserved sectors */ | |
170 | int8_t bpbFATs; /* number of FATs */ | |
171 | int8_t bpbRootDirEnts[2]; /* number of root directory entries */ | |
172 | int8_t bpbSectors[2]; /* total number of sectors */ | |
173 | int8_t bpbMedia; /* media descriptor */ | |
174 | int8_t bpbFATsecs[2]; /* number of sectors per FAT */ | |
175 | int8_t bpbSecPerTrack[2]; /* sectors per track */ | |
176 | int8_t bpbHeads[2]; /* number of heads */ | |
177 | int8_t bpbHiddenSecs[2]; /* number of hidden sectors */ | |
178 | }; | |
179 | ||
180 | /* | |
181 | * BPB for DOS 5.0 The difference is bpbHiddenSecs is a short for DOS 3.3, | |
182 | * and bpbHugeSectors is not in the 3.3 bpb. | |
183 | */ | |
184 | struct byte_bpb50 { | |
185 | int8_t bpbBytesPerSec[2]; /* bytes per sector */ | |
186 | int8_t bpbSecPerClust; /* sectors per cluster */ | |
187 | int8_t bpbResSectors[2]; /* number of reserved sectors */ | |
188 | int8_t bpbFATs; /* number of FATs */ | |
189 | int8_t bpbRootDirEnts[2]; /* number of root directory entries */ | |
190 | int8_t bpbSectors[2]; /* total number of sectors */ | |
191 | int8_t bpbMedia; /* media descriptor */ | |
192 | int8_t bpbFATsecs[2]; /* number of sectors per FAT */ | |
193 | int8_t bpbSecPerTrack[2]; /* sectors per track */ | |
194 | int8_t bpbHeads[2]; /* number of heads */ | |
195 | int8_t bpbHiddenSecs[4]; /* number of hidden sectors */ | |
196 | int8_t bpbHugeSectors[4]; /* # of sectors if bpbSectors == 0 */ | |
197 | }; | |
198 | ||
199 | /* | |
200 | * BPB for DOS 7.10 (FAT32). This one has a few extensions to bpb50. | |
201 | */ | |
202 | struct byte_bpb710 { | |
203 | u_int8_t bpbBytesPerSec[2]; /* bytes per sector */ | |
204 | u_int8_t bpbSecPerClust; /* sectors per cluster */ | |
205 | u_int8_t bpbResSectors[2]; /* number of reserved sectors */ | |
206 | u_int8_t bpbFATs; /* number of FATs */ | |
207 | u_int8_t bpbRootDirEnts[2]; /* number of root directory entries */ | |
208 | u_int8_t bpbSectors[2]; /* total number of sectors */ | |
209 | u_int8_t bpbMedia; /* media descriptor */ | |
210 | u_int8_t bpbFATsecs[2]; /* number of sectors per FAT */ | |
211 | u_int8_t bpbSecPerTrack[2]; /* sectors per track */ | |
212 | u_int8_t bpbHeads[2]; /* number of heads */ | |
213 | u_int8_t bpbHiddenSecs[4]; /* # of hidden sectors */ | |
214 | u_int8_t bpbHugeSectors[4]; /* # of sectors if bpbSectors == 0 */ | |
215 | u_int8_t bpbBigFATsecs[4]; /* like bpbFATsecs for FAT32 */ | |
216 | u_int8_t bpbExtFlags[2]; /* extended flags: */ | |
217 | u_int8_t bpbFSVers[2]; /* filesystem version */ | |
218 | u_int8_t bpbRootClust[4]; /* start cluster for root directory */ | |
219 | u_int8_t bpbFSInfo[2]; /* filesystem info structure sector */ | |
220 | u_int8_t bpbBackup[2]; /* backup boot sector */ | |
221 | /* There is a 12 byte filler here, but we ignore it */ | |
222 | }; | |
223 | #endif | |
224 | ||
225 | /* | |
226 | * FAT32 FSInfo block. | |
227 | */ | |
228 | struct fsinfo { | |
229 | u_int8_t fsisig1[4]; | |
230 | u_int8_t fsifill1[480]; | |
231 | u_int8_t fsisig2[4]; | |
232 | u_int8_t fsinfree[4]; | |
233 | u_int8_t fsinxtfree[4]; | |
234 | u_int8_t fsifill2[12]; | |
235 | u_int8_t fsisig3[4]; | |
236 | }; | |
237 | ||
238 | ||
239 | /* direntry */ | |
240 | ||
241 | /*- | |
242 | * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank. | |
243 | * Copyright (C) 1994, 1995, 1997 TooLs GmbH. | |
244 | * All rights reserved. | |
245 | * Original code by Paul Popelka (paulp@uts.amdahl.com) (see above). | |
246 | * | |
247 | * Redistribution and use in source and binary forms, with or without | |
248 | * modification, are permitted provided that the following conditions | |
249 | * are met: | |
250 | * 1. Redistributions of source code must retain the above copyright | |
251 | * notice, this list of conditions and the following disclaimer. | |
252 | * 2. Redistributions in binary form must reproduce the above copyright | |
253 | * notice, this list of conditions and the following disclaimer in the | |
254 | * documentation and/or other materials provided with the distribution. | |
255 | * 3. All advertising materials mentioning features or use of this software | |
256 | * must display the following acknowledgement: | |
257 | * This product includes software developed by TooLs GmbH. | |
258 | * 4. The name of TooLs GmbH may not be used to endorse or promote products | |
259 | * derived from this software without specific prior written permission. | |
260 | * | |
261 | * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR | |
262 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
263 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
264 | * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
265 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
266 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | |
267 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |
268 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | |
269 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |
270 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
271 | */ | |
272 | ||
273 | /* | |
274 | * Structure of a dos directory entry. | |
275 | */ | |
276 | struct direntry { | |
277 | u_int8_t deName[8]; /* filename, blank filled */ | |
278 | #define SLOT_EMPTY 0x00 /* slot has never been used */ | |
279 | #define SLOT_E5 0x05 /* the real value is 0xe5 */ | |
280 | #define SLOT_DELETED 0xe5 /* file in this slot deleted */ | |
281 | u_int8_t deExtension[3]; /* extension, blank filled */ | |
282 | u_int8_t deAttributes; /* file attributes */ | |
283 | #define ATTR_NORMAL 0x00 /* normal file */ | |
284 | #define ATTR_READONLY 0x01 /* file is read-only (immutable) */ | |
285 | #define ATTR_HIDDEN 0x02 /* file is hidden */ | |
286 | #define ATTR_SYSTEM 0x04 /* file is a system file */ | |
287 | #define ATTR_VOLUME 0x08 /* entry is a volume label */ | |
288 | #define ATTR_DIRECTORY 0x10 /* entry is a directory name */ | |
289 | #define ATTR_ARCHIVE 0x20 /* file is new or modified */ | |
290 | u_int8_t deLowerCase; /* NT VFAT lower case flags */ | |
291 | #define LCASE_BASE 0x08 /* filename base in lower case */ | |
292 | #define LCASE_EXT 0x10 /* filename extension in lower case */ | |
293 | u_int8_t deCHundredth; /* hundredth of seconds in CTime */ | |
294 | u_int8_t deCTime[2]; /* create time */ | |
295 | u_int8_t deCDate[2]; /* create date */ | |
296 | u_int8_t deADate[2]; /* access date */ | |
297 | u_int8_t deHighClust[2]; /* high bytes of cluster number */ | |
298 | u_int8_t deMTime[2]; /* last update time */ | |
299 | u_int8_t deMDate[2]; /* last update date */ | |
300 | u_int8_t deStartCluster[2]; /* starting cluster of file */ | |
301 | u_int8_t deFileSize[4]; /* size of file in bytes */ | |
302 | }; | |
303 | ||
304 | /* | |
305 | * Structure of a Win95 long name directory entry | |
306 | */ | |
307 | struct winentry { | |
308 | u_int8_t weCnt; | |
309 | #define WIN_LAST 0x40 | |
310 | #define WIN_CNT 0x3f | |
311 | u_int8_t wePart1[10]; | |
312 | u_int8_t weAttributes; | |
313 | #define ATTR_WIN95 0x0f | |
314 | u_int8_t weReserved1; | |
315 | u_int8_t weChksum; | |
316 | u_int8_t wePart2[12]; | |
317 | u_int16_t weReserved2; | |
318 | u_int8_t wePart3[4]; | |
319 | }; | |
320 | #define WIN_CHARS 13 /* Number of chars per winentry */ | |
321 | ||
322 | /* | |
323 | * Maximum filename length in Win95 | |
324 | * Note: Must be < sizeof(dirent.d_name) | |
325 | */ | |
326 | #define WIN_MAXLEN 255 | |
327 | ||
328 | /* | |
329 | * This is the format of the contents of the deTime field in the direntry | |
330 | * structure. | |
331 | * We don't use bitfields because we don't know how compilers for | |
332 | * arbitrary machines will lay them out. | |
333 | */ | |
334 | #define DT_2SECONDS_MASK 0x1F /* seconds divided by 2 */ | |
335 | #define DT_2SECONDS_SHIFT 0 | |
336 | #define DT_MINUTES_MASK 0x7E0 /* minutes */ | |
337 | #define DT_MINUTES_SHIFT 5 | |
338 | #define DT_HOURS_MASK 0xF800 /* hours */ | |
339 | #define DT_HOURS_SHIFT 11 | |
340 | ||
341 | /* | |
342 | * This is the format of the contents of the deDate field in the direntry | |
343 | * structure. | |
344 | */ | |
345 | #define DD_DAY_MASK 0x1F /* day of month */ | |
346 | #define DD_DAY_SHIFT 0 | |
347 | #define DD_MONTH_MASK 0x1E0 /* month */ | |
348 | #define DD_MONTH_SHIFT 5 | |
349 | #define DD_YEAR_MASK 0xFE00 /* year - 1980 */ | |
350 | #define DD_YEAR_SHIFT 9 | |
351 |