summaryrefslogtreecommitdiff
path: root/msdos.h
diff options
context:
space:
mode:
Diffstat (limited to 'msdos.h')
-rw-r--r--msdos.h279
1 files changed, 279 insertions, 0 deletions
diff --git a/msdos.h b/msdos.h
new file mode 100644
index 0000000..c060455
--- /dev/null
+++ b/msdos.h
@@ -0,0 +1,279 @@
+#ifndef MTOOLS_MSDOS_H
+#define MTOOLS_MSDOS_H
+
+/* Copyright 1986-1992 Emmet P. Gray.
+ * Copyright 1996-1998,2000-2003,2006,2007,2009 Alain Knaff.
+ * This file is part of mtools.
+ *
+ * Mtools is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Mtools 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mtools. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * msdos common header file
+ */
+
+#define MAX_SECTOR 8192 /* largest sector size */
+#define MDIR_SIZE 32 /* MSDOS directory entry size in bytes*/
+#define MAX_CLUSTER 8192 /* largest cluster size */
+#ifndef MAX_PATH
+#define MAX_PATH 128 /* largest MSDOS path length */
+#endif
+#define MAX_DIR_SECS 64 /* largest directory (in sectors) */
+#define MSECTOR_SIZE msector_size
+
+#define NEW 1
+#define OLD 0
+
+#define _WORD(x) ((unsigned short)((unsigned char)(x)[0] + (((unsigned char)(x)[1]) << 8)))
+#define _DWORD(x) ((unsigned int)(_WORD(x) + (_WORD((x)+2) << 16)))
+
+#define DELMARK ((char) 0xe5)
+#define ENDMARK ((char) 0x00)
+
+struct directory {
+ char name[8]; /* 0 file name */
+ char ext[3]; /* 8 file extension */
+ unsigned char attr; /* 11 attribute byte */
+ unsigned char Case; /* 12 case of short filename */
+ unsigned char ctime_ms; /* 13 creation time, milliseconds (?) */
+ unsigned char ctime[2]; /* 14 creation time */
+ unsigned char cdate[2]; /* 16 creation date */
+ unsigned char adate[2]; /* 18 last access date */
+ unsigned char startHi[2]; /* 20 start cluster, Hi */
+ unsigned char time[2]; /* 22 time stamp */
+ unsigned char date[2]; /* 24 date stamp */
+ unsigned char start[2]; /* 26 starting cluster number */
+ unsigned char size[4]; /* 28 size of the file */
+};
+
+#define EXTCASE 0x10
+#define BASECASE 0x8
+
+#define MAX16 0xffff
+#define MAX32 0xffffffff
+#define MAX_SIZE 0x7fffffff
+
+#define FILE_SIZE(dir) (_DWORD((dir)->size))
+#define START(dir) (_WORD((dir)->start))
+#define STARTHI(dir) (_WORD((dir)->startHi))
+
+/* ASSUMPTION: long is at least 32 bits */
+UNUSED(static __inline__ void set_dword(unsigned char *data, unsigned long value))
+{
+ data[3] = (value >> 24) & 0xff;
+ data[2] = (value >> 16) & 0xff;
+ data[1] = (value >> 8) & 0xff;
+ data[0] = (value >> 0) & 0xff;
+}
+
+
+/* ASSUMPTION: short is at least 16 bits */
+UNUSED(static __inline__ void set_word(unsigned char *data, unsigned short value))
+{
+ data[1] = (value >> 8) & 0xff;
+ data[0] = (value >> 0) & 0xff;
+}
+
+
+/*
+ * hi byte | low byte
+ * |7|6|5|4|3|2|1|0|7|6|5|4|3|2|1|0|
+ * | | | | | | | | | | | | | | | | |
+ * \ 7 bits /\4 bits/\ 5 bits /
+ * year +80 month day
+ */
+#define DOS_YEAR(dir) (((dir)->date[1] >> 1) + 1980)
+#define DOS_MONTH(dir) (((((dir)->date[1]&0x1) << 3) + ((dir)->date[0] >> 5)))
+#define DOS_DAY(dir) ((dir)->date[0] & 0x1f)
+
+/*
+ * hi byte | low byte
+ * |7|6|5|4|3|2|1|0|7|6|5|4|3|2|1|0|
+ * | | | | | | | | | | | | | | | | |
+ * \ 5 bits /\ 6 bits /\ 5 bits /
+ * hour minutes sec*2
+ */
+#define DOS_HOUR(dir) ((dir)->time[1] >> 3)
+#define DOS_MINUTE(dir) (((((dir)->time[1]&0x7) << 3) + ((dir)->time[0] >> 5)))
+#define DOS_SEC(dir) (((dir)->time[0] & 0x1f) * 2)
+
+
+typedef struct InfoSector_t {
+ unsigned char signature1[4];
+ unsigned char filler1[0x1e0];
+ unsigned char signature2[4];
+ unsigned char count[4];
+ unsigned char pos[4];
+ unsigned char filler2[14];
+ unsigned char signature3[2];
+} InfoSector_t;
+
+#define INFOSECT_SIGNATURE1 0x41615252
+#define INFOSECT_SIGNATURE2 0x61417272
+
+
+typedef struct label_blk_t {
+ unsigned char physdrive; /* 36 physical drive ? */
+ unsigned char reserved; /* 37 reserved */
+ unsigned char dos4; /* 38 dos > 4.0 diskette */
+ unsigned char serial[4]; /* 39 serial number */
+ char label[11]; /* 43 disk label */
+ char fat_type[8]; /* 54 FAT type */
+} label_blk_t;
+
+/* FAT32 specific info in the bootsector */
+struct fat32_t {
+ unsigned char bigFat[4]; /* 36 nb of sectors per FAT */
+ unsigned char extFlags[2]; /* 40 extension flags */
+ unsigned char fsVersion[2]; /* 42 ? */
+ unsigned char rootCluster[4]; /* 44 start cluster of root dir */
+ unsigned char infoSector[2]; /* 48 changeable global info */
+ unsigned char backupBoot[2]; /* 50 back up boot sector */
+ unsigned char reserved[6]; /* 52 ? */
+ unsigned char reserved2[6]; /* 52 ? */
+ struct label_blk_t labelBlock;
+}; /* ends at 58 */
+
+typedef struct oldboot_t {
+ struct label_blk_t labelBlock;
+ unsigned char res_2m; /* 62 reserved by 2M */
+ unsigned char CheckSum; /* 63 2M checksum (not used) */
+ unsigned char fmt_2mf; /* 64 2MF format version */
+ unsigned char wt; /* 65 1 if write track after format */
+ unsigned char rate_0; /* 66 data transfer rate on track 0 */
+ unsigned char rate_any; /* 67 data transfer rate on track<>0 */
+ unsigned char BootP[2]; /* 68 offset to boot program */
+ unsigned char Infp0[2]; /* 70 T1: information for track 0 */
+ unsigned char InfpX[2]; /* 72 T2: information for track<>0 */
+ unsigned char InfTm[2]; /* 74 T3: track sectors size table */
+ unsigned char DateF[2]; /* 76 Format date */
+ unsigned char TimeF[2]; /* 78 Format time */
+ unsigned char junk[1024 - 80]; /* 80 remaining data */
+} oldboot_t;
+
+struct bootsector_s {
+ unsigned char jump[3]; /* 0 Jump to boot code */
+ char banner[8]; /* 3 OEM name & version */
+ unsigned char secsiz[2]; /* 11 Bytes per sector hopefully 512 */
+ unsigned char clsiz; /* 13 Cluster size in sectors */
+ unsigned char nrsvsect[2]; /* 14 Number of reserved (boot) sectors */
+ unsigned char nfat; /* 16 Number of FAT tables hopefully 2 */
+ unsigned char dirents[2]; /* 17 Number of directory slots */
+ unsigned char psect[2]; /* 19 Total sectors on disk */
+ unsigned char descr; /* 21 Media descriptor=first byte of FAT */
+ unsigned char fatlen[2]; /* 22 Sectors in FAT */
+ unsigned char nsect[2]; /* 24 Sectors/track */
+ unsigned char nheads[2]; /* 26 Heads */
+ unsigned char nhs[4]; /* 28 number of hidden sectors */
+ unsigned char bigsect[4]; /* 32 big total sectors */
+
+ union {
+ struct fat32_t fat32;
+ struct oldboot_t old;
+ } ext;
+};
+
+#define MAX_BOOT 4096
+
+union bootsector {
+ unsigned char bytes[MAX_BOOT];
+ char characters[MAX_BOOT];
+ struct bootsector_s boot;
+};
+
+#define CHAR(x) (boot->x[0])
+#define WORD(x) (_WORD(boot->boot.x))
+#define DWORD(x) (_DWORD(boot->boot.x))
+
+#define WORD_S(x) (_WORD(boot.boot.x))
+#define DWORD_S(x) (_DWORD(boot.boot.x))
+
+#define OFFSET(x) (((char *) (boot->x)) - ((char *)(boot->jump)))
+
+
+extern struct OldDos_t {
+ unsigned int tracks;
+ unsigned int sectors;
+ unsigned int heads;
+
+ unsigned int dir_len;
+ unsigned int cluster_size;
+ unsigned int fat_len;
+
+ int media;
+} old_dos[];
+
+/* max FAT12/FAT16 sizes, according to
+
+ http://www.microsoft.com/hwdev/download/hardware/fatgen103.pdf
+
+ interestingly enough, another Microsoft document
+ [http://support.microsoft.com/default.aspx?scid=kb%3ben-us%3b67321]
+ gives different values, but the first seems to be more sure about
+ itself, so we believe that one ;-)
+*/
+#define FAT12 4085 /* max. number of clusters described by a 12 bit FAT */
+#define FAT16 65525 /* max number of clusters for a 16 bit FAT */
+
+#define ATTR_ARCHIVE 0x20
+#define ATTR_DIR 0x10
+#define ATTR_LABEL 0x8
+#define ATTR_SYSTEM 0x4
+#define ATTR_HIDDEN 0x2
+#define ATTR_READONLY 0x1
+
+#define HAS_BIT(entry,x) ((entry)->dir.attr & (x))
+
+#define IS_ARCHIVE(entry) (HAS_BIT((entry),ATTR_ARCHIVE))
+#define IS_DIR(entry) (HAS_BIT((entry),ATTR_DIR))
+#define IS_LABEL(entry) (HAS_BIT((entry),ATTR_LABEL))
+#define IS_SYSTEM(entry) (HAS_BIT((entry),ATTR_SYSTEM))
+#define IS_HIDDEN(entry) (HAS_BIT((entry),ATTR_HIDDEN))
+#define IS_READONLY(entry) (HAS_BIT((entry),ATTR_READONLY))
+
+
+#define MAX_BYTES_PER_CLUSTER (32*1024)
+/* Experimentally, it turns out that DOS only accepts cluster sizes
+ * which are powers of two, and less than 128 sectors (else it gets a
+ * divide overflow) */
+
+
+#define FAT_SIZE(bits, sec_siz, clusters) \
+ ((((clusters)+2) * ((bits)/4) - 1) / 2 / (sec_siz) + 1)
+
+#define NEEDED_FAT_SIZE(x) FAT_SIZE((x)->fat_bits, (x)->sector_size, \
+ (x)->num_clus)
+
+/* disk size taken by FAT and clusters */
+#define DISK_SIZE(bits, sec_siz, clusters, n, cluster_size) \
+ ((n) * FAT_SIZE(bits, sec_siz, clusters) + \
+ (clusters) * (cluster_size))
+
+#define TOTAL_DISK_SIZE(bits, sec_siz, clusters, n, cluster_size) \
+ (DISK_SIZE(bits, sec_siz, clusters, n, cluster_size) + 2)
+/* approx. total disk size: assume 1 boot sector and one directory sector */
+
+extern const char *mversion;
+extern const char *mdate;
+extern const char *mformat_banner;
+
+extern char *Version;
+extern char *Date;
+
+
+int init(char drive, int mode);
+
+#define MT_READ 1
+#define MT_WRITE 2
+
+#endif
+