DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
include/qcow2_disk.h
00001 /*
00002  *  Copyright (C) 2016  Michael Greger
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with this program; if not, write to the Free Software
00016  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017  */
00018 
00019 
00020 #ifndef DOSBOX_QCOW2_DISK_H
00021 #define DOSBOX_QCOW2_DISK_H
00022 
00023 
00024 #include <iostream>
00025 #include <fstream>
00026 #include <iomanip>
00027 #include <stdint.h>
00028 #include "config.h"
00029 #include "bios_disk.h"
00030 
00031 class QCow2Image{
00032 
00033 public:
00034 
00035         static const Bit32u magic;
00036         
00037         typedef struct QCow2Header {
00038                 Bit32u magic;
00039                 Bit32u version;
00040                 Bit64u backing_file_offset;
00041                 Bit32u backing_file_size;
00042                 Bit32u cluster_bits;
00043                 Bit64u size; /* in bytes */
00044                 Bit32u crypt_method;
00045                 Bit32u l1_size;
00046                 Bit64u l1_table_offset;
00047                 Bit64u refcount_table_offset;
00048                 Bit32u refcount_table_clusters;
00049                 Bit32u nb_snapshots;
00050                 Bit64u snapshots_offset;
00051         } QCow2Header;
00052         
00053         static QCow2Header read_header(FILE* qcow2File);
00054 
00055         QCow2Image(QCow2Header qcow2Header, FILE *qcow2File, const char* imageName, Bit32u sectorSizeBytes);
00056 
00057         virtual ~QCow2Image();
00058         
00059         Bit8u read_sector(Bit32u sectnum, Bit8u* data);
00060 
00061         Bit8u write_sector(Bit32u sectnum, Bit8u* data);
00062         
00063 private:
00064 
00065         FILE* file;
00066         QCow2Header header;
00067         static const Bit64u copy_flag;
00068         static const Bit64u empty_mask;
00069         static const Bit64u table_entry_mask;
00070         Bit32u sector_size;
00071         Bit64u cluster_mask;
00072         Bit64u cluster_size;
00073         Bit64u sectors_per_cluster;
00074         Bit64u l2_mask;
00075         Bit64u l2_bits;
00076         Bit64u l1_bits;
00077         Bit64u refcount_mask;
00078         Bit64u refcount_bits;
00079         QCow2Image* backing_image;
00080 
00081         static Bit16u host_read16(Bit16u buffer);
00082 
00083         static Bit32u host_read32(Bit32u buffer);
00084 
00085         static Bit64u host_read64(Bit64u buffer);
00086 
00087         static Bit64u mask64(Bit64u bits);
00088         
00089         Bit8u pad_file(Bit64u& new_file_length);
00090 
00091         Bit8u read_allocated_data(Bit64u file_offset, Bit8u* data, Bit64u data_size);
00092 
00093         Bit8u read_cluster(Bit64u data_cluster_number, Bit8u* data);
00094 
00095         Bit8u read_l1_table(Bit64u address, Bit64u& l2_table_offset);
00096 
00097         Bit8u read_l2_table(Bit64u l2_table_offset, Bit64u address, Bit64u& data_cluster_offset);
00098 
00099         Bit8u read_refcount_table(Bit64u data_cluster_offset, Bit64u& refcount_cluster_offset);
00100 
00101         Bit8u read_table(Bit64u entry_offset, Bit64u entry_mask, Bit64u& entry_value);
00102 
00103         Bit8u read_unallocated_cluster(Bit64u data_cluster_number, Bit8u* data);
00104 
00105         Bit8u read_unallocated_sector(Bit32u sectnum, Bit8u* data);
00106 
00107         Bit8u update_reference_count(Bit64u cluster_offset, Bit8u* cluster_buffer);
00108 
00109         Bit8u write_data(Bit64u file_offset, Bit8u* data, Bit64u data_size);
00110 
00111         Bit8u write_l1_table_entry(Bit64u address, Bit64u l2_table_offset);
00112 
00113         Bit8u write_l2_table_entry(Bit64u l2_table_offset, Bit64u address, Bit64u data_cluster_offset);
00114 
00115         Bit8u write_refcount(Bit64u cluster_offset, Bit64u refcount_cluster_offset, Bit16u refcount);
00116 
00117         Bit8u write_refcount_table_entry(Bit64u cluster_offset, Bit64u refcount_cluster_offset);
00118 
00119         Bit8u write_table_entry(Bit64u entry_offset, Bit64u entry_value);
00120 };
00121 
00122 class QCow2Disk : public imageDisk{
00123 
00124 public:
00125         
00126         QCow2Disk(QCow2Image::QCow2Header qcow2Header, FILE *qcow2File, Bit8u *imgName, Bit32u imgSizeK, Bit32u sectorSizeBytes, bool isHardDisk);
00127 
00128         virtual ~QCow2Disk();
00129         
00130         virtual Bit8u Read_AbsoluteSector(Bit32u sectnum, void* data);
00131 
00132         virtual Bit8u Write_AbsoluteSector(Bit32u sectnum, const void* data);
00133 
00134 private:
00135 
00136         QCow2Image qcowImage;
00137 };
00138 
00139 #endif