/* * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * The contents of this file constitute Original Code as defined in and * are subject to the Apple Public Source License Version 2.0 (the * "License"). You may not use this file except in compliance with the * License. Please obtain a copy of the License at * http://www.apple.com/publicsource and read it before using this file. * * This Original Code and all software distributed under the License are * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the * License for the specific language governing rights and limitations * under the License. * * @APPLE_LICENSE_HEADER_END@ */ /* * Written by Paul Popelka (paulp@uts.amdahl.com) * * You can do anything you want with this software, just don't say you wrote * it, and don't remove this notice. * * This software is provided "as is". * * The author supplies this software to be publicly redistributed on the * understanding that the author is not responsible for the correct * functioning of this software in any circumstances and is not liable for * any damages caused by this software. * * October 1992 */ /* * Format of a boot sector. This is the first sector on a DOS floppy disk * or the fist sector of a partition on a hard disk. But, it is not the * first sector of a partitioned hard disk. */ struct bootsector33 { u_int8_t bsJump[3]; /* jump inst E9xxxx or EBxx90 */ int8_t bsOemName[8]; /* OEM name and version */ int8_t bsBPB[19]; /* BIOS parameter block */ int8_t bsDriveNumber; /* drive number (0x80) */ int8_t bsBootCode[479]; /* pad so struct is 512b */ u_int8_t bsBootSectSig0; u_int8_t bsBootSectSig1; #define BOOTSIG0 0x55 #define BOOTSIG1 0xaa }; struct extboot { int8_t exDriveNumber; /* drive number (0x80) */ int8_t exReserved1; /* reserved */ int8_t exBootSignature; /* ext. boot signature (0x29) */ #define EXBOOTSIG 0x29 int8_t exVolumeID[4]; /* volume ID number */ int8_t exVolumeLabel[11]; /* volume label */ int8_t exFileSysType[8]; /* fs type (FAT12 or FAT16) */ }; struct bootsector50 { u_int8_t bsJump[3]; /* jump inst E9xxxx or EBxx90 */ int8_t bsOemName[8]; /* OEM name and version */ int8_t bsBPB[25]; /* BIOS parameter block */ int8_t bsExt[26]; /* Bootsector Extension */ int8_t bsBootCode[448]; /* pad so structure is 512b */ u_int8_t bsBootSectSig0; u_int8_t bsBootSectSig1; #define BOOTSIG0 0x55 #define BOOTSIG1 0xaa }; struct bootsector710 { u_int8_t bsJump[3]; /* jump inst E9xxxx or EBxx90 */ int8_t bsOEMName[8]; /* OEM name and version */ int8_t bsBPB[53]; /* BIOS parameter block */ int8_t bsExt[26]; /* Bootsector Extension */ int8_t bsBootCode[420]; /* pad so structure is 512b */ u_int8_t bsBootSectSig0; u_int8_t bsBootSectSig1; #define BOOTSIG0 0x55 #define BOOTSIG1 0xaa }; union bootsector { struct bootsector33 bs33; struct bootsector50 bs50; struct bootsector710 bs710; }; /* BPB */ /* * BIOS Parameter Block (BPB) for DOS 3.3 */ struct bpb33 { u_int16_t bpbBytesPerSec; /* bytes per sector */ u_int8_t bpbSecPerClust; /* sectors per cluster */ u_int16_t bpbResSectors; /* number of reserved sectors */ u_int8_t bpbFATs; /* number of FATs */ u_int16_t bpbRootDirEnts; /* number of root directory entries */ u_int16_t bpbSectors; /* total number of sectors */ u_int8_t bpbMedia; /* media descriptor */ u_int16_t bpbFATsecs; /* number of sectors per FAT */ u_int16_t bpbSecPerTrack; /* sectors per track */ u_int16_t bpbHeads; /* number of heads */ u_int16_t bpbHiddenSecs; /* number of hidden sectors */ } __attribute__((packed)); /* * BPB for DOS 5.0 The difference is bpbHiddenSecs is a short for DOS 3.3, * and bpbHugeSectors is not in the 3.3 bpb. */ struct bpb50 { u_int16_t bpbBytesPerSec; /* bytes per sector */ u_int8_t bpbSecPerClust; /* sectors per cluster */ u_int16_t bpbResSectors; /* number of reserved sectors */ u_int8_t bpbFATs; /* number of FATs */ u_int16_t bpbRootDirEnts; /* number of root directory entries */ u_int16_t bpbSectors; /* total number of sectors */ u_int8_t bpbMedia; /* media descriptor */ u_int16_t bpbFATsecs; /* number of sectors per FAT */ u_int16_t bpbSecPerTrack; /* sectors per track */ u_int16_t bpbHeads; /* number of heads */ u_int32_t bpbHiddenSecs; /* # of hidden sectors */ u_int32_t bpbHugeSectors; /* # of sectors if bpbSectors == 0 */ } __attribute__((packed)); /* * BPB for DOS 7.10 (FAT32). This one has a few extensions to bpb50. */ struct bpb710 { u_int16_t bpbBytesPerSec; /* bytes per sector */ u_int8_t bpbSecPerClust; /* sectors per cluster */ u_int16_t bpbResSectors; /* number of reserved sectors */ u_int8_t bpbFATs; /* number of FATs */ u_int16_t bpbRootDirEnts; /* number of root directory entries */ u_int16_t bpbSectors; /* total number of sectors */ u_int8_t bpbMedia; /* media descriptor */ u_int16_t bpbFATsecs; /* number of sectors per FAT */ u_int16_t bpbSecPerTrack; /* sectors per track */ u_int16_t bpbHeads; /* number of heads */ u_int32_t bpbHiddenSecs; /* # of hidden sectors */ u_int32_t bpbHugeSectors; /* # of sectors if bpbSectors == 0 */ u_int32_t bpbBigFATsecs; /* like bpbFATsecs for FAT32 */ u_int16_t bpbExtFlags; /* extended flags: */ #define FATNUM 0xf /* mask for numbering active FAT */ #define FATMIRROR 0x80 /* FAT is mirrored (like it always was) */ u_int16_t bpbFSVers; /* filesystem version */ #define FSVERS 0 /* currently only 0 is understood */ u_int32_t bpbRootClust; /* start cluster for root directory */ u_int16_t bpbFSInfo; /* filesystem info structure sector */ u_int16_t bpbBackup; /* backup boot sector */ /* There is a 12 byte filler here, but we ignore it */ } __attribute__((packed)); #if 0 /* * BIOS Parameter Block (BPB) for DOS 3.3 */ struct byte_bpb33 { int8_t bpbBytesPerSec[2]; /* bytes per sector */ int8_t bpbSecPerClust; /* sectors per cluster */ int8_t bpbResSectors[2]; /* number of reserved sectors */ int8_t bpbFATs; /* number of FATs */ int8_t bpbRootDirEnts[2]; /* number of root directory entries */ int8_t bpbSectors[2]; /* total number of sectors */ int8_t bpbMedia; /* media descriptor */ int8_t bpbFATsecs[2]; /* number of sectors per FAT */ int8_t bpbSecPerTrack[2]; /* sectors per track */ int8_t bpbHeads[2]; /* number of heads */ int8_t bpbHiddenSecs[2]; /* number of hidden sectors */ }; /* * BPB for DOS 5.0 The difference is bpbHiddenSecs is a short for DOS 3.3, * and bpbHugeSectors is not in the 3.3 bpb. */ struct byte_bpb50 { int8_t bpbBytesPerSec[2]; /* bytes per sector */ int8_t bpbSecPerClust; /* sectors per cluster */ int8_t bpbResSectors[2]; /* number of reserved sectors */ int8_t bpbFATs; /* number of FATs */ int8_t bpbRootDirEnts[2]; /* number of root directory entries */ int8_t bpbSectors[2]; /* total number of sectors */ int8_t bpbMedia; /* media descriptor */ int8_t bpbFATsecs[2]; /* number of sectors per FAT */ int8_t bpbSecPerTrack[2]; /* sectors per track */ int8_t bpbHeads[2]; /* number of heads */ int8_t bpbHiddenSecs[4]; /* number of hidden sectors */ int8_t bpbHugeSectors[4]; /* # of sectors if bpbSectors == 0 */ }; /* * BPB for DOS 7.10 (FAT32). This one has a few extensions to bpb50. */ struct byte_bpb710 { u_int8_t bpbBytesPerSec[2]; /* bytes per sector */ u_int8_t bpbSecPerClust; /* sectors per cluster */ u_int8_t bpbResSectors[2]; /* number of reserved sectors */ u_int8_t bpbFATs; /* number of FATs */ u_int8_t bpbRootDirEnts[2]; /* number of root directory entries */ u_int8_t bpbSectors[2]; /* total number of sectors */ u_int8_t bpbMedia; /* media descriptor */ u_int8_t bpbFATsecs[2]; /* number of sectors per FAT */ u_int8_t bpbSecPerTrack[2]; /* sectors per track */ u_int8_t bpbHeads[2]; /* number of heads */ u_int8_t bpbHiddenSecs[4]; /* # of hidden sectors */ u_int8_t bpbHugeSectors[4]; /* # of sectors if bpbSectors == 0 */ u_int8_t bpbBigFATsecs[4]; /* like bpbFATsecs for FAT32 */ u_int8_t bpbExtFlags[2]; /* extended flags: */ u_int8_t bpbFSVers[2]; /* filesystem version */ u_int8_t bpbRootClust[4]; /* start cluster for root directory */ u_int8_t bpbFSInfo[2]; /* filesystem info structure sector */ u_int8_t bpbBackup[2]; /* backup boot sector */ /* There is a 12 byte filler here, but we ignore it */ }; #endif /* * FAT32 FSInfo block. */ struct fsinfo { u_int8_t fsisig1[4]; u_int8_t fsifill1[480]; u_int8_t fsisig2[4]; u_int8_t fsinfree[4]; u_int8_t fsinxtfree[4]; u_int8_t fsifill2[12]; u_int8_t fsisig3[4]; }; /* direntry */ /*- * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank. * Copyright (C) 1994, 1995, 1997 TooLs GmbH. * All rights reserved. * Original code by Paul Popelka (paulp@uts.amdahl.com) (see above). * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by TooLs GmbH. * 4. The name of TooLs GmbH may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Structure of a dos directory entry. */ struct direntry { u_int8_t deName[8]; /* filename, blank filled */ #define SLOT_EMPTY 0x00 /* slot has never been used */ #define SLOT_E5 0x05 /* the real value is 0xe5 */ #define SLOT_DELETED 0xe5 /* file in this slot deleted */ u_int8_t deExtension[3]; /* extension, blank filled */ u_int8_t deAttributes; /* file attributes */ #define ATTR_NORMAL 0x00 /* normal file */ #define ATTR_READONLY 0x01 /* file is read-only (immutable) */ #define ATTR_HIDDEN 0x02 /* file is hidden */ #define ATTR_SYSTEM 0x04 /* file is a system file */ #define ATTR_VOLUME 0x08 /* entry is a volume label */ #define ATTR_DIRECTORY 0x10 /* entry is a directory name */ #define ATTR_ARCHIVE 0x20 /* file is new or modified */ u_int8_t deLowerCase; /* NT VFAT lower case flags */ #define LCASE_BASE 0x08 /* filename base in lower case */ #define LCASE_EXT 0x10 /* filename extension in lower case */ u_int8_t deCHundredth; /* hundredth of seconds in CTime */ u_int8_t deCTime[2]; /* create time */ u_int8_t deCDate[2]; /* create date */ u_int8_t deADate[2]; /* access date */ u_int8_t deHighClust[2]; /* high bytes of cluster number */ u_int8_t deMTime[2]; /* last update time */ u_int8_t deMDate[2]; /* last update date */ u_int8_t deStartCluster[2]; /* starting cluster of file */ u_int8_t deFileSize[4]; /* size of file in bytes */ }; /* * Structure of a Win95 long name directory entry */ struct winentry { u_int8_t weCnt; #define WIN_LAST 0x40 #define WIN_CNT 0x3f u_int8_t wePart1[10]; u_int8_t weAttributes; #define ATTR_WIN95 0x0f u_int8_t weReserved1; u_int8_t weChksum; u_int8_t wePart2[12]; u_int16_t weReserved2; u_int8_t wePart3[4]; }; #define WIN_CHARS 13 /* Number of chars per winentry */ /* * Maximum filename length in Win95 * Note: Must be < sizeof(dirent.d_name) */ #define WIN_MAXLEN 255 /* * This is the format of the contents of the deTime field in the direntry * structure. * We don't use bitfields because we don't know how compilers for * arbitrary machines will lay them out. */ #define DT_2SECONDS_MASK 0x1F /* seconds divided by 2 */ #define DT_2SECONDS_SHIFT 0 #define DT_MINUTES_MASK 0x7E0 /* minutes */ #define DT_MINUTES_SHIFT 5 #define DT_HOURS_MASK 0xF800 /* hours */ #define DT_HOURS_SHIFT 11 /* * This is the format of the contents of the deDate field in the direntry * structure. */ #define DD_DAY_MASK 0x1F /* day of month */ #define DD_DAY_SHIFT 0 #define DD_MONTH_MASK 0x1E0 /* month */ #define DD_MONTH_SHIFT 5 #define DD_YEAR_MASK 0xFE00 /* year - 1980 */ #define DD_YEAR_SHIFT 9