Update Red Hat Copyright Notices
[nbdkit.git] / plugins / floppy / virtual-floppy.h
blobb3b7e6c8fb3644bc2230092d23a2faa4f6f98acf
1 /* nbdkit
2 * Copyright Red Hat
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * * Neither the name of Red Hat nor the names of its contributors may be
16 * used to endorse or promote products derived from this software without
17 * specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
29 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
33 #ifndef NBDKIT_VIRTUAL_FLOPPY_H
34 #define NBDKIT_VIRTUAL_FLOPPY_H
36 #include <sys/types.h>
37 #include <sys/stat.h>
39 #include "regions.h"
40 #include "vector.h"
42 DEFINE_VECTOR_TYPE (idxs, size_t);
44 struct partition_entry {
45 uint8_t bootable; /* 0x00 or 0x80 if bootable */
46 uint8_t chs[3]; /* always set to chs_too_large */
47 uint8_t part_type; /* partition type byte - 0x0C = FAT32 with LBA*/
48 uint8_t chs2[3]; /* always set to chs_too_large */
49 uint32_t start_sector; /* 2048 */
50 uint32_t num_sectors;
51 } __attribute__ ((packed));
53 struct bootsector {
54 uint8_t jmp_insn[3];
55 uint8_t oem_name[8]; /* 0x0003 */
57 /* BIOS Parameter Block, only required for first sector of FAT. */
58 uint16_t bytes_per_sector; /* 0x000B */
59 uint8_t sectors_per_cluster; /* 0x000D */
60 uint16_t reserved_sectors; /* 0x000E */
61 uint8_t nr_fats; /* 0x0010 */
62 uint16_t nr_root_dir_entries; /* 0x0011 - always 0 for FAT32 */
63 uint16_t old_nr_sectors; /* 0x0013 - always 0 */
64 uint8_t media_descriptor; /* 0x0015 - always 0xF8 */
65 uint16_t old_sectors_per_fat; /* 0x0016 */
66 uint16_t sectors_per_track; /* 0x0018 - always 0 for LBA */
67 uint16_t nr_heads; /* 0x001A - always 0 for LBA */
68 uint32_t nr_hidden_sectors; /* 0x001C */
69 uint32_t nr_sectors; /* 0x0020 */
71 /* FAT32 Extended BIOS Parameter Block. */
72 uint32_t sectors_per_fat; /* 0x0024 */
73 uint16_t mirroring; /* 0x0028 */
74 uint16_t fat_version; /* 0x002A */
75 uint32_t root_directory_cluster; /* 0x002C */
76 uint16_t fsinfo_sector; /* 0x0030 */
77 uint16_t backup_bootsect; /* 0x0032 */
78 uint8_t reserved[12]; /* 0x0034 */
79 uint8_t physical_drive_number; /* 0x0040 */
80 uint8_t unused; /* 0x0041 */
81 uint8_t extended_boot_signature; /* 0x0042 */
82 uint32_t volume_id; /* 0x0043 */
83 uint8_t volume_label[11]; /* 0x0047 */
84 uint8_t fstype[8]; /* 0x0052 - "FAT32 " */
86 uint8_t unused2[350];
88 /* Partition table. Not present in first sector of filesystem. */
89 uint32_t disk_signature; /* 0x01B8 */
90 uint16_t zero; /* 0x01BC - 0x00 0x00 */
91 struct partition_entry partition[4]; /* 0x01BE - partition table */
93 uint8_t boot_signature[2]; /* 0x01FE - 0x55 0xAA */
94 } __attribute__ ((packed));
96 struct fsinfo {
97 uint8_t signature[4]; /* 0x52 0x52 0x61 0x41 "RRaA" */
98 uint8_t reserved[480];
99 uint8_t signature2[4]; /* 0x72 0x72 0x41 0x61 "rrAa" */
100 uint32_t free_data_clusters;
101 uint32_t last_free_cluster;
102 uint8_t reserved2[12];
103 uint8_t signature3[4]; /* 0x00 0x00 0x55 0xAA */
104 } __attribute__ ((packed));
106 struct file {
107 char *name; /* Filename. */
108 char *host_path; /* Path of file on the host. */
109 struct stat statbuf; /* stat(2) information, including size. */
110 uint32_t first_cluster; /* First cluster containing this file. */
111 uint32_t nr_clusters; /* Number of clusters. */
114 DEFINE_VECTOR_TYPE (files, struct file);
116 /* On disk directory entry (non-LFN). */
117 struct dir_entry {
118 uint8_t name[8 + 3];
119 uint8_t attributes; /* 0x0B */
120 #define DIR_ENTRY_READONLY 0x01
121 #define DIR_ENTRY_HIDDEN 0x02
122 #define DIR_ENTRY_SYSTEM 0x04
123 #define DIR_ENTRY_VOLUME_LABEL 0x08
124 #define DIR_ENTRY_SUBDIRECTORY 0x10
125 #define DIR_ENTRY_ARCHIVE 0x20
126 uint8_t unused; /* 0x0C */
127 uint8_t ctime_10ms; /* 0x0D - ctime seconds in 10ms units */
128 uint16_t ctime; /* 0x0E */
129 uint16_t cdate; /* 0x10 */
130 uint16_t adate; /* 0x12 */
131 uint16_t cluster_hi; /* 0x14 - first cluster (high word) */
132 uint16_t mtime; /* 0x16 */
133 uint16_t mdate; /* 0x18 */
134 uint16_t cluster_lo; /* 0x1A - first cluster (low word) */
135 uint32_t size; /* 0x1C - file size */
136 } __attribute__ ((packed));
138 DEFINE_VECTOR_TYPE (dir_entries, struct dir_entry);
140 /* On disk directory entry (LFN). */
141 struct lfn_entry {
142 uint8_t seq; /* sequence number */
143 uint16_t name1[5]; /* first five UTF-16LE characters */
144 uint8_t attributes; /* 0x0B - always 0x0F */
145 uint8_t type; /* 0x0C - always 0x00 */
146 uint8_t checksum; /* 0x0D - DOS file name checksum */
147 uint16_t name2[6]; /* next six UTF-16LE characters */
148 uint16_t cluster_lo; /* 0x1A - always 0x0000 */
149 uint16_t name3[2]; /* last two UTF-16LE characters */
150 } __attribute__ ((packed));
152 struct dir {
153 size_t pdi; /* Link to parent directory (for root, 0). */
154 char *name; /* Directory name (for root, NULL). */
155 struct stat statbuf; /* stat(2) information (for root, zeroes). */
156 uint32_t first_cluster; /* First cluster containing this dir. */
157 uint32_t nr_clusters; /* Number of clusters. */
159 /* List of subdirectories. This is actually a list of indexes
160 * into the floppy->dirs array.
162 idxs subdirs;
164 /* List of files in this directory. This is actually a list of
165 * indexes into the floppy->files array.
167 idxs fileidxs;
169 /* On disk directory table. */
170 dir_entries table;
173 DEFINE_VECTOR_TYPE (dirs, struct dir);
175 struct virtual_floppy {
176 /* Virtual disk layout. */
177 struct regions regions;
179 /* Disk MBR. */
180 struct bootsector mbr;
182 /* Partition boot/first sector (also used for backup copy). */
183 struct bootsector bootsect;
185 /* Filesystem information sector. */
186 struct fsinfo fsinfo;
188 /* File Allocation Table (also used for second copy). */
189 uint32_t *fat;
191 /* All regular files found. */
192 files files;
194 /* Directories. dirs[0] == root directory. */
195 dirs dirs;
197 uint64_t fat_entries; /* Size of FAT (number of 32 bit entries). */
198 uint64_t fat_clusters; /* Size of FAT (clusters on disk). */
199 uint64_t data_size; /* Size of data region (bytes). */
200 uint64_t data_clusters; /* Size of data region (clusters). */
201 uint64_t data_used_clusters; /* Size of the used part of the data region. */
203 /* The disk layout:
204 * sector 0: MBR
205 * sector 2048: partition first sector
206 * sector 2049: filesystem information sector
207 * sector 2050-2053: unused (reserved sectors 2-5)
208 * sector 2054: backup first sector
209 * sector 2055-2079: unused (reserved sectors 7-31)
210 * sector 2080: FAT
211 * fat2_start_sector FAT (second copy)
212 * data_start_sector data region (first cluster is always 2)
213 * data_last_sector last sector of data region
215 uint32_t fat2_start_sector;
216 uint32_t data_start_sector;
217 uint32_t data_last_sector;
220 #define SECTOR_SIZE 512
222 /* Don't change SECTORS_PER_CLUSTER without also considering the disk
223 * layout. It shouldn't be necessary to change this since this
224 * supports the maximum possible disk size, and only wastes virtual
225 * space.
227 #define SECTORS_PER_CLUSTER 32
228 #define CLUSTER_SIZE (SECTOR_SIZE * SECTORS_PER_CLUSTER)
230 extern void init_virtual_floppy (struct virtual_floppy *floppy)
231 __attribute__ ((__nonnull__ (1)));
232 extern int create_virtual_floppy (const char *dir, const char *label,
233 uint64_t size,
234 struct virtual_floppy *floppy)
235 __attribute__ ((__nonnull__ (1, 2, 4)));
236 extern void free_virtual_floppy (struct virtual_floppy *floppy)
237 __attribute__ ((__nonnull__ (1)));
238 extern int create_directory (size_t di, const char *label,
239 struct virtual_floppy *floppy)
240 __attribute__ ((__nonnull__ (2, 3)));
241 extern int update_directory_first_cluster (size_t di,
242 struct virtual_floppy *floppy)
243 __attribute__ ((__nonnull__ (2)));
244 extern void pad_string (const char *label, size_t n, uint8_t *out)
245 __attribute__ ((__nonnull__ (1, 3)));
247 #endif /* NBDKIT_VIRTUAL_FLOPPY_H */