1 /////////////////////////////////////////////////////////////////////////
2 // $Id: hdimage.h 14181 2021-03-11 21:46:25Z vruppert $
3 /////////////////////////////////////////////////////////////////////////
4 //
5 //  Copyright (C) 2005-2021  The Bochs Project
6 //
7 //  This library is free software; you can redistribute it and/or
8 //  modify it under the terms of the GNU Lesser General Public
9 //  License as published by the Free Software Foundation; either
10 //  version 2 of the License, or (at your option) any later version.
11 //
12 //  This library is distributed in the hope that it will be useful,
13 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 //  Lesser General Public License for more details.
16 //
17 //  You should have received a copy of the GNU Lesser General Public
18 //  License along with this library; if not, write to the Free Software
19 //  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
20 
21 #ifndef BX_HDIMAGE_H
22 #define BX_HDIMAGE_H
23 
24 // required for access() checks
25 #ifndef F_OK
26 #define F_OK 0
27 #endif
28 
29 // hdimage capabilities
30 #define HDIMAGE_READONLY      1
31 #define HDIMAGE_HAS_GEOMETRY  2
32 #define HDIMAGE_AUTO_GEOMETRY 4
33 
34 // hdimage format check return values
35 #define HDIMAGE_FORMAT_OK      0
36 #define HDIMAGE_SIZE_ERROR    -1
37 #define HDIMAGE_READ_ERROR    -2
38 #define HDIMAGE_NO_SIGNATURE  -3
39 #define HDIMAGE_TYPE_ERROR    -4
40 #define HDIMAGE_VERSION_ERROR -5
41 
42 // SPARSE IMAGES HEADER
43 #define SPARSE_HEADER_MAGIC  (0x02468ace)
44 #define SPARSE_HEADER_VERSION  2
45 #define SPARSE_HEADER_V1       1
46 #define SPARSE_HEADER_SIZE        (256) // Plenty of room for later
47 #define SPARSE_PAGE_NOT_ALLOCATED (0xffffffff)
48 
49  typedef struct
50  {
51    Bit32u  magic;
52    Bit32u  version;
53    Bit32u  pagesize;
54    Bit32u  numpages;
55    Bit64u  disk;
56 
57    Bit32u  padding[58];
58  } sparse_header_t;
59 
60 #define STANDARD_HEADER_MAGIC     "Bochs Virtual HD Image"
61 #define STANDARD_HEADER_V1        (0x00010000)
62 #define STANDARD_HEADER_VERSION   (0x00020000)
63 #define STANDARD_HEADER_SIZE      (512)
64 
65 
66  // WARNING : headers are kept in x86 (little) endianness
67  typedef struct
68  {
69    Bit8u   magic[32];
70    Bit8u   type[16];
71    Bit8u   subtype[16];
72    Bit32u  version;
73    Bit32u  header;
74  } standard_header_t;
75 
76 #define REDOLOG_TYPE "Redolog"
77 #define REDOLOG_SUBTYPE_UNDOABLE "Undoable"
78 #define REDOLOG_SUBTYPE_VOLATILE "Volatile"
79 #define REDOLOG_SUBTYPE_GROWING  "Growing"
80 
81 #define REDOLOG_PAGE_NOT_ALLOCATED (0xffffffff)
82 
83 #define UNDOABLE_REDOLOG_EXTENSION ".redolog"
84 #define UNDOABLE_REDOLOG_EXTENSION_LENGTH (strlen(UNDOABLE_REDOLOG_EXTENSION))
85 #define VOLATILE_REDOLOG_EXTENSION ".XXXXXX"
86 #define VOLATILE_REDOLOG_EXTENSION_LENGTH (strlen(VOLATILE_REDOLOG_EXTENSION))
87 
88  typedef struct
89  {
90    // the fields in the header are kept in little endian
91    Bit32u  catalog;    // #entries in the catalog
92    Bit32u  bitmap;     // bitmap size in bytes
93    Bit32u  extent;     // extent size in bytes
94    Bit32u  timestamp;  // modification time in FAT format (subtype 'undoable' only)
95    Bit64u  disk;       // disk size in bytes
96  } redolog_specific_header_t;
97 
98  typedef struct
99  {
100    // the fields in the header are kept in little endian
101    Bit32u  catalog;    // #entries in the catalog
102    Bit32u  bitmap;     // bitmap size in bytes
103    Bit32u  extent;     // extent size in bytes
104    Bit64u  disk;       // disk size in bytes
105  } redolog_specific_header_v1_t;
106 
107  typedef struct
108  {
109    standard_header_t standard;
110    redolog_specific_header_t specific;
111 
112    Bit8u padding[STANDARD_HEADER_SIZE - (sizeof (standard_header_t) + sizeof (redolog_specific_header_t))];
113  } redolog_header_t;
114 
115  typedef struct
116  {
117    standard_header_t standard;
118    redolog_specific_header_v1_t specific;
119 
120    Bit8u padding[STANDARD_HEADER_SIZE - (sizeof (standard_header_t) + sizeof (redolog_specific_header_v1_t))];
121  } redolog_header_v1_t;
122 
123 // htod : convert host to disk (little) endianness
124 // dtoh : convert disk (little) to host endianness
125 #if defined (BX_LITTLE_ENDIAN)
126 #define htod16(val) (val)
127 #define dtoh16(val) (val)
128 #define htod32(val) (val)
129 #define dtoh32(val) (val)
130 #define htod64(val) (val)
131 #define dtoh64(val) (val)
132 #else
133 #define htod16(val) ((((val)&0xff00)>>8) | (((val)&0xff)<<8))
134 #define dtoh16(val) htod16(val)
135 #define htod32(val) bx_bswap32(val)
136 #define dtoh32(val) htod32(val)
137 #define htod64(val) bx_bswap64(val)
138 #define dtoh64(val) htod64(val)
139 #endif
140 
141 class device_image_t;
142 class redolog_t;
143 class cdrom_base_c;
144 
145 #ifdef BXIMAGE
146 int bx_create_image_file(const char *filename);
147 #endif
148 BOCHSAPI_MSVCONLY int bx_read_image(int fd, Bit64s offset, void *buf, int count);
149 BOCHSAPI_MSVCONLY int bx_write_image(int fd, Bit64s offset, void *buf, int count);
150 BOCHSAPI_MSVCONLY int bx_close_image(int fd, const char *pathname);
151 #ifndef WIN32
152 int hdimage_open_file(const char *pathname, int flags, Bit64u *fsize, time_t *mtime);
153 #else
154 BOCHSAPI_MSVCONLY int hdimage_open_file(const char *pathname, int flags, Bit64u *fsize, FILETIME *mtime);
155 #endif
156 bool hdimage_detect_image_mode(const char *pathname, const char **image_mode);
157 BOCHSAPI_MSVCONLY bool hdimage_backup_file(int fd, const char *backup_fname);
158 BOCHSAPI_MSVCONLY bool hdimage_copy_file(const char *src, const char *dst);
159 bool coherency_check(device_image_t *ro_disk, redolog_t *redolog);
160 #ifndef WIN32
161 Bit16u fat_datetime(time_t time, int return_time);
162 #else
163 Bit16u BOCHSAPI_MSVCONLY fat_datetime(FILETIME time, int return_time);
164 #endif
165 
166 // base class
167 class BOCHSAPI_MSVCONLY device_image_t
168 {
169   public:
170       // Default constructor
171       device_image_t();
~device_image_t()172       virtual ~device_image_t() {}
173 
174       // Open a image. Returns non-negative if successful.
175       virtual int open(const char* pathname);
176 
177       // Open an image with specific flags. Returns non-negative if successful.
178       virtual int open(const char* pathname, int flags) = 0;
179 
180       // Close the image.
181       virtual void close() = 0;
182 
183       // Position ourselves. Return the resulting offset from the
184       // beginning of the file.
185       virtual Bit64s lseek(Bit64s offset, int whence) = 0;
186 
187       // Read count bytes to the buffer buf. Return the number of
188       // bytes read (count).
189       virtual ssize_t read(void* buf, size_t count) = 0;
190 
191       // Write count bytes from buf. Return the number of bytes
192       // written (count).
193       virtual ssize_t write(const void* buf, size_t count) = 0;
194 
195       // Get image capabilities
196       virtual Bit32u get_capabilities();
197 
198       // Get modification time in FAT format
199       virtual Bit32u get_timestamp();
200 
201       // Check image format
check_format(int fd,Bit64u imgsize)202       static int check_format(int fd, Bit64u imgsize) {return HDIMAGE_NO_SIGNATURE;}
203 
204 #ifdef BXIMAGE
205       // Create new image file
create_image(const char * pathname,Bit64u size)206       virtual int create_image(const char *pathname, Bit64u size) {return 0;}
207 #else
208       // Save/restore support
209       virtual void register_state(bx_list_c *parent);
save_state(const char * backup_fname)210       virtual bool save_state(const char *backup_fname) {return 0;}
restore_state(const char * backup_fname)211       virtual void restore_state(const char *backup_fname) {}
212 #endif
213 
214       unsigned cylinders;
215       unsigned heads;
216       unsigned spt;
217       unsigned sect_size;
218       Bit64u   hd_size;
219   protected:
220 #ifndef WIN32
221       time_t mtime;
222 #else
223       FILETIME mtime;
224 #endif
225 };
226 
227 // FLAT MODE
228 class flat_image_t : public device_image_t
229 {
230   public:
231       // Open an image with specific flags. Returns non-negative if successful.
232       int open(const char* pathname, int flags);
233 
234       // Close the image.
235       void close();
236 
237       // Position ourselves. Return the resulting offset from the
238       // beginning of the file.
239       Bit64s lseek(Bit64s offset, int whence);
240 
241       // Read count bytes to the buffer buf. Return the number of
242       // bytes read (count).
243       ssize_t read(void* buf, size_t count);
244 
245       // Write count bytes from buf. Return the number of bytes
246       // written (count).
247       ssize_t write(const void* buf, size_t count);
248 
249       // Check image format
250       static int check_format(int fd, Bit64u imgsize);
251 
252 #ifndef BXIMAGE
253       // Save/restore support
254       bool save_state(const char *backup_fname);
255       void restore_state(const char *backup_fname);
256 #endif
257 
258   private:
259       int fd;
260       const char *pathname;
261 };
262 
263 // CONCAT MODE
264 class concat_image_t : public device_image_t
265 {
266   public:
267       // Default constructor
268       concat_image_t();
269 
270       // Open an image with specific flags. Returns non-negative if successful.
271       int open(const char* pathname, int flags);
272 
273       // Close the image.
274       void close();
275 
276       // Position ourselves. Return the resulting offset from the
277       // beginning of the file.
278       Bit64s lseek(Bit64s offset, int whence);
279 
280       // Read count bytes to the buffer buf. Return the number of
281       // bytes read (count).
282       ssize_t read(void* buf, size_t count);
283 
284       // Write count bytes from buf. Return the number of bytes
285       // written (count).
286       ssize_t write(const void* buf, size_t count);
287 
288 #ifndef BXIMAGE
289       // Save/restore support
290       bool save_state(const char *backup_fname);
291       void restore_state(const char *backup_fname);
292 #endif
293 
294   private:
295 #define BX_CONCAT_MAX_IMAGES 8
296       int fd_table[BX_CONCAT_MAX_IMAGES];
297       Bit64u start_offset_table[BX_CONCAT_MAX_IMAGES];
298       Bit64u length_table[BX_CONCAT_MAX_IMAGES];
299       void increment_string(char *str);
300       int maxfd;  // number of entries in tables that are valid
301 
302       // notice if anyone does sequential read or write without seek in between.
303       // This can be supported pretty easily, but needs additional checks.
304       // 0=something other than seek was last operation
305       // 1=seek was last operation
306       //int seek_was_last_op;
307 
308       // the following variables tell which partial image file to use for
309       // the next read and write.
310       int index;  // index into table
311       int curr_fd;     // fd to use for reads and writes
312       Bit64u curr_min, curr_max; // byte offset boundary of this image
313       Bit64u total_offset;     // current byte offset
314       const char *pathname0;
315 };
316 
317 // SPARSE MODE
318 class sparse_image_t : public device_image_t
319 {
320 
321 // Format of a sparse file:
322 // 256 byte header, containing details such as page size and number of pages
323 // Page indirection table, mapping virtual pages to physical pages within file
324 // Physical pages till end of file
325 
326   public:
327     // Default constructor
328     sparse_image_t();
329 
330     // Open an image with specific flags. Returns non-negative if successful.
331     int open(const char* pathname, int flags);
332 
333     // Close the image.
334     void close();
335 
336     // Position ourselves. Return the resulting offset from the
337     // beginning of the file.
338     Bit64s lseek(Bit64s offset, int whence);
339 
340     // Read count bytes to the buffer buf. Return the number of
341     // bytes read (count).
342     ssize_t read(void* buf, size_t count);
343 
344     // Write count bytes from buf. Return the number of bytes
345     // written (count).
346     ssize_t write(const void* buf, size_t count);
347 
348     // Check image format
349     static int check_format(int fd, Bit64u imgsize);
350 
351 #ifdef BXIMAGE
352     // Create new image file
353     int create_image(const char *pathname, Bit64u size);
354 #else
355     // Save/restore support
356     bool save_state(const char *backup_fname);
357     void restore_state(const char *backup_fname);
358 #endif
359 
360   private:
361     int fd;
362 
363 #ifdef _POSIX_MAPPED_FILES
364     void *  mmap_header;
365     size_t  mmap_length;
366     size_t  system_pagesize_mask;
367 #endif
368     Bit32u *pagetable;
369 
370     // Header is written to disk in little-endian (x86) format
371     // Thus needs to be converted on big-endian systems before read
372     // The pagetable is also kept little endian
373 
374     sparse_header_t header;
375 
376     Bit32u pagesize;
377     int    pagesize_shift;
378     Bit32u pagesize_mask;
379 
380     Bit64s data_start;
381     Bit64u underlying_filesize;
382 
383     char *pathname;
384 
385     //Bit64s position;
386 
387     Bit32u position_virtual_page;
388     Bit32u position_physical_page;
389     Bit32u position_page_offset;
390 
391     Bit64s underlying_current_filepos;
392 
393     Bit64s total_size;
394 
395     void panic(const char * message);
396     Bit64s get_physical_offset();
397     void set_virtual_page(Bit32u new_virtual_page);
398     int read_header();
399     ssize_t read_page_fragment(Bit32u read_virtual_page, Bit32u read_page_offset, size_t read_size, void * buf);
400 
401     sparse_image_t *parent_image;
402 };
403 
404 #ifdef WIN32
405 class dll_image_t : public device_image_t
406 {
407   public:
408       dll_image_t();
409 
410       // Open an image with specific flags. Returns non-negative if successful.
411       int open(const char* pathname, int flags);
412 
413       // Close the image.
414       void close();
415 
416       // Position ourselves. Return the resulting offset from the
417       // beginning of the file.
418       Bit64s lseek(Bit64s offset, int whence);
419 
420       // Read count bytes to the buffer buf. Return the number of
421       // bytes read (count).
422       ssize_t read(void* buf, size_t count);
423 
424       // Write count bytes from buf. Return the number of bytes
425       // written (count).
426       ssize_t write(const void* buf, size_t count);
427 
428   private:
429       int vunit;
430       Bit64s vblk;
431 };
432 #endif
433 
434 // REDOLOG class
435 class BOCHSAPI_MSVCONLY redolog_t
436 {
437   public:
438       redolog_t();
439       int make_header(const char* type, Bit64u size);
440       int create(const char* filename, const char* type, Bit64u size);
441       int create(int filedes, const char* type, Bit64u size);
442       int open(const char* filename, const char* type);
443       int open(const char* filename, const char* type, int flags);
444       void close();
445       Bit64u get_size();
446       Bit32u get_timestamp();
447       bool set_timestamp(Bit32u timestamp);
448 
449       Bit64s lseek(Bit64s offset, int whence);
450       ssize_t read(void* buf, size_t count);
451       ssize_t write(const void* buf, size_t count);
452 
453       static int check_format(int fd, const char *subtype);
454 
455 #ifdef BXIMAGE
456       int commit(device_image_t *base_image);
457 #else
458       bool save_state(const char *backup_fname);
459 #endif
460 
461   private:
462       void             print_header();
463       char            *pathname;
464       int              fd;
465       redolog_header_t header;     // Header is kept in x86 (little) endianness
466       Bit32u          *catalog;
467       Bit8u           *bitmap;
468       bool             bitmap_update;
469       Bit32u           extent_index;
470       Bit32u           extent_offset;
471       Bit32u           extent_next;
472 
473       Bit32u           bitmap_blocks;
474       Bit32u           extent_blocks;
475 
476       Bit64s           imagepos;
477 };
478 
479 // GROWING MODE
480 class growing_image_t : public device_image_t
481 {
482   public:
483       // Contructor
484       growing_image_t();
485       virtual ~growing_image_t();
486 
487       // Open an image with specific flags. Returns non-negative if successful.
488       int open(const char* pathname, int flags);
489 
490       // Close the image.
491       void close();
492 
493       // Position ourselves. Return the resulting offset from the
494       // beginning of the file.
495       Bit64s lseek(Bit64s offset, int whence);
496 
497       // Read count bytes to the buffer buf. Return the number of
498       // bytes read (count).
499       ssize_t read(void* buf, size_t count);
500 
501       // Write count bytes from buf. Return the number of bytes
502       // written (count).
503       ssize_t write(const void* buf, size_t count);
504 
505       // Get modification time in FAT format
506       virtual Bit32u get_timestamp();
507 
508       // Check image format
509       static int check_format(int fd, Bit64u imgsize);
510 
511 #ifdef BXIMAGE
512       // Create new image file
513       int create_image(const char *pathname, Bit64u size);
514 #else
515       // Save/restore support
516       bool save_state(const char *backup_fname);
517       void restore_state(const char *backup_fname);
518 #endif
519 
520   private:
521       redolog_t *redolog;
522       const char *pathname;
523 };
524 
525 // UNDOABLE MODE
526 class undoable_image_t : public device_image_t
527 {
528   public:
529       // Contructor
530       undoable_image_t(const char* redolog_name);
531       virtual ~undoable_image_t();
532 
533       // Open an image with specific flags. Returns non-negative if successful.
534       int open(const char* pathname, int flags);
535 
536       // Close the image.
537       void close();
538 
539       // Position ourselves. Return the resulting offset from the
540       // beginning of the file.
541       Bit64s lseek(Bit64s offset, int whence);
542 
543       // Read count bytes to the buffer buf. Return the number of
544       // bytes read (count).
545       ssize_t read(void* buf, size_t count);
546 
547       // Write count bytes from buf. Return the number of bytes
548       // written (count).
549       ssize_t write(const void* buf, size_t count);
550 
551       // Get image capabilities
get_capabilities()552       virtual Bit32u get_capabilities() {return caps;}
553 
554 #ifndef BXIMAGE
555       // Save/restore support
556       bool save_state(const char *backup_fname);
557       void restore_state(const char *backup_fname);
558 #endif
559 
560   private:
561       redolog_t       *redolog;       // Redolog instance
562       device_image_t  *ro_disk;       // Read-only base disk instance
563       char            *redolog_name;  // Redolog name
564       Bit32u          caps;
565 };
566 
567 
568 // VOLATILE MODE
569 class volatile_image_t : public device_image_t
570 {
571   public:
572       // Contructor
573       volatile_image_t(const char* redolog_name);
574       virtual ~volatile_image_t();
575 
576       // Open an image with specific flags. Returns non-negative if successful.
577       int open(const char* pathname, int flags);
578 
579       // Close the image.
580       void close();
581 
582       // Position ourselves. Return the resulting offset from the
583       // beginning of the file.
584       Bit64s lseek(Bit64s offset, int whence);
585 
586       // Read count bytes to the buffer buf. Return the number of
587       // bytes read (count).
588       ssize_t read(void* buf, size_t count);
589 
590       // Write count bytes from buf. Return the number of bytes
591       // written (count).
592       ssize_t write(const void* buf, size_t count);
593 
594       // Get image capabilities
get_capabilities()595       virtual Bit32u get_capabilities() {return caps;}
596 
597 #ifndef BXIMAGE
598       // Save/restore support
599       bool save_state(const char *backup_fname);
600       void restore_state(const char *backup_fname);
601 #endif
602 
603   private:
604       redolog_t       *redolog;       // Redolog instance
605       device_image_t  *ro_disk;       // Read-only base disk instance
606       char            *redolog_name;  // Redolog name
607       char            *redolog_temp;  // Redolog temporary file name
608       Bit32u          caps;
609 };
610 
611 
612 #ifndef BXIMAGE
613 
614 #define DEV_hdimage_init_image(a,b,c) bx_hdimage_ctl.init_image(a,b,c)
615 #define DEV_hdimage_init_cdrom(a)     bx_hdimage_ctl.init_cdrom(a)
616 
617 class BOCHSAPI bx_hdimage_ctl_c : public logfunctions {
618 public:
619   bx_hdimage_ctl_c();
~bx_hdimage_ctl_c()620   virtual ~bx_hdimage_ctl_c() {}
621   void init(void);
622   const char **get_mode_names();
623   int get_mode_id(const char *mode);
624   void list_modules(void);
625   void exit(void);
626   device_image_t *init_image(const char *image_mode, Bit64u disk_size, const char *journal);
627   cdrom_base_c *init_cdrom(const char *dev);
628 };
629 
630 BOCHSAPI extern bx_hdimage_ctl_c bx_hdimage_ctl;
631 
632 #endif // ifndef BXIMAGE
633 
634 //
635 // The hdimage_locator class is used by device_image_t classes to register
636 // their name. The common hdimage code uses the static 'create' method
637 // to locate and instantiate a device_image_t class.
638 //
639 class BOCHSAPI_MSVCONLY hdimage_locator_c {
640 public:
641   static bool module_present(const char *mode);
642   static void cleanup(void);
643   static device_image_t *create(const char *mode, Bit64u disk_size, const char *journal);
644   static bool detect_image_mode(int fd, Bit64u disk_size, const char **image_mode);
645 protected:
646   hdimage_locator_c(const char *mode);
647   virtual ~hdimage_locator_c();
648   virtual device_image_t *allocate(Bit64u disk_size, const char *journal) = 0;
check_format(int fd,Bit64u disk_size)649   virtual int check_format(int fd, Bit64u disk_size) {return -1;}
650 private:
651   static hdimage_locator_c *all;
652   hdimage_locator_c *next;
653   const char *mode;
654 };
655 
656 #endif
657