Updated files as per request.

Moved cookies etc from util.c to create.c, updated create* functions to use the cookies instead of hardcoded values.
Added docs/ folder with Microsoft VHD_CLEARBIT(x) specifications for completeness.
Fixed typos in Makefiles.
This commit is contained in:
waltje
2021-03-16 16:45:40 -04:00
parent 456fc88daf
commit 7acd0be766
10 changed files with 70 additions and 54 deletions

View File

@@ -8,7 +8,7 @@
#
# Makefile for Windows systems using the MinGW32 environment.
#
# Version: @(#)Makefile.MinGW 1.0.1 2021/03/16
# Version: @(#)Makefile.MinGW 1.0.2 2021/03/16
#
# Author: Fred N. van Kempen, <waltje@varcem.com>
#
@@ -55,7 +55,7 @@ ifndef X64
endif
PROGS := vhdcvt.exe
PROGS := vhdcvt
SYSOBJ :=

Binary file not shown.

BIN
docs/[MS-VHDX].pdf Normal file

Binary file not shown.

View File

@@ -3,9 +3,10 @@
*
* This file is part of the MiniVHD Project.
*
* Version: @(#)create.c 1.0.1 2021/03/16
* Version: @(#)create.c 1.0.2 2021/03/16
*
* Author: Sherman Perry, <shermperry@gmail.com>
* Authors: Sherman Perry, <shermperry@gmail.com>
* Fred N. van Kempen, <waltje@varcem.com>
*
* Copyright 2019-2021 Sherman Perry.
*
@@ -48,6 +49,12 @@
#include "xml2_encoding.h"
static const char MVHD_CONECTIX_COOKIE[] = "conectix";
static const char MVHD_CREATOR[] = "mVHD";
static const char MVHD_CREATOR_HOST_OS[] = "Wi2k";
static const char MVHD_CXSPARSE_COOKIE[] = "cxsparse";
/**
* \brief Populate a VHD footer
*
@@ -60,20 +67,22 @@
static void
gen_footer(MVHDFooter* footer, uint64_t size_in_bytes, MVHDGeom* geom, MVHDType type, uint64_t sparse_header_off)
{
memcpy(footer->cookie, "conectix", sizeof footer->cookie);
memcpy(footer->cookie, MVHD_CONECTIX_COOKIE, sizeof footer->cookie);
footer->features = 0x00000002;
footer->fi_fmt_vers = 0x00010000;
footer->data_offset = (type == MVHD_TYPE_DIFF || type == MVHD_TYPE_DYNAMIC) ? sparse_header_off : 0xffffffffffffffff;
footer->timestamp = vhd_calc_timestamp();
memcpy(footer->cr_app, "mvhd", sizeof footer->cr_app);
memcpy(footer->cr_app, MVHD_CREATOR, sizeof footer->cr_app);
footer->cr_vers = 0x000e0000;
memcpy(footer->cr_host_os, "Wi2k", sizeof footer->cr_host_os);
memcpy(footer->cr_host_os, MVHD_CREATOR_HOST_OS, sizeof footer->cr_host_os);
footer->orig_sz = footer->curr_sz = size_in_bytes;
footer->geom.cyl = geom->cyl;
footer->geom.heads = geom->heads;
footer->geom.spt = geom->spt;
footer->disk_type = type;
mvhd_generate_uuid(footer->uuid);
footer->checksum = mvhd_gen_footer_checksum(footer);
}
@@ -89,7 +98,7 @@ gen_footer(MVHDFooter* footer, uint64_t size_in_bytes, MVHDGeom* geom, MVHDType
static void
gen_sparse_header(MVHDSparseHeader* header, uint32_t num_blks, uint64_t bat_offset, uint32_t block_size_in_sectors)
{
memcpy(header->cookie, "cxsparse", sizeof header->cookie);
memcpy(header->cookie, MVHD_CXSPARSE_COOKIE, sizeof header->cookie);
header->data_offset = 0xffffffffffffffff;
header->bat_offset = bat_offset;
header->head_vers = 0x00010000;
@@ -422,17 +431,21 @@ create_sparse_diff(const char* path, const char* par_path, uint64_t size_in_byte
* */
if (par_vhdm != NULL) {
uint64_t curr_pos = (uint64_t)mvhd_ftello64(f);
/* Double check my sums... */
assert(curr_pos == par_loc_offset);
/* Fill the space required for location data with zero */
uint8_t empty_sect[MVHD_SECTOR_SIZE] = {0};
int i;
uint32_t j;
for (i = 0; i < 2; i++) {
for (j = 0; j < (vhdm->sparse.par_loc_entry[i].plat_data_space / MVHD_SECTOR_SIZE); j++) {
fwrite(empty_sect, sizeof empty_sect, 1, f);
}
}
/* Now write the location entries */
mvhd_fseeko64(f, vhdm->sparse.par_loc_entry[0].plat_data_offset, SEEK_SET);
fwrite(w2ku_path_buff, vhdm->sparse.par_loc_entry[0].plat_data_len, 1, f);
@@ -457,8 +470,9 @@ cleanup_vhdm:
vhdm = NULL;
cleanup_par_vhdm:
if (par_vhdm != NULL)
if (par_vhdm != NULL) {
mvhd_close(par_vhdm);
}
end:
free(w2ku_path_buff);
@@ -552,3 +566,14 @@ mvhd_create_ex(MVHDCreationOptions options, int* err)
return NULL; /* Make the compiler happy */
}
bool
mvhd_is_conectix_str(const void* buffer)
{
if (strncmp(buffer, MVHD_CONECTIX_COOKIE, strlen(MVHD_CONECTIX_COOKIE)) == 0) {
return true;
}
return false;
}

View File

@@ -1,13 +1,13 @@
/*
* MiniVHD Minimalist VHD implementation in C.
* libCWALK Path library for C/C++
*
* This file is part of the MiniVHD Project.
* Version: @(#)cwalk.c 1.0.2 2021/03/16
*
* Version: @(#)cwalk.c 1.0.1 2021/03/15
*
* Author: Sherman Perry, <shermperry@gmail.com>
* Authors: Sherman Perry, <shermperry@gmail.com>
* Leonard Iklé, <https://github.com/likle>
*
* Copyright 2019-2021 Sherman Perry.
* Copyright 2020 Leonard Iklé.
*
* MIT License
*

View File

@@ -1,13 +1,13 @@
/*
* MiniVHD Minimalist VHD implementation in C.
* libCWALK path library for C/C++
*
* This file is part of the MiniVHD Project.
* Version: @(#)cwalk.c 1.0.2 2021/03/16
*
* Version: @(#)cwalk.c 1.0.1 2021/03/15
*
* Author: Sherman Perry, <shermperry@gmail.com>
* Authors: Sherman Perry, <shermperry@gmail.com>
* Leonard Iklé, <https://github.com/likle>
*
* Copyright 2019-2021 Sherman Perry.
* Copyright 2020 Leonard Iklé.
*
* MIT License
*

View File

@@ -5,7 +5,7 @@
*
* Sector reading and writing implementations.
*
* Version: @(#)io.c 1.0.1 2021/03/16
* Version: @(#)io.c 1.0.2 2021/03/16
*
* Author: Sherman Perry, <shermperry@gmail.com>
*
@@ -83,6 +83,7 @@ mvhd_write_empty_sectors(FILE* f, int sector_count)
{
uint8_t zero_bytes[MVHD_SECTOR_SIZE] = {0};
int i;
for (i = 0; i < sector_count; i++) {
fwrite(zero_bytes, sizeof zero_bytes, 1, f);
}
@@ -104,8 +105,9 @@ read_sect_bitmap(MVHDMeta* vhdm, int blk)
if (vhdm->block_offset[blk] != MVHD_SPARSE_BLK) {
mvhd_fseeko64(vhdm->f, (uint64_t)vhdm->block_offset[blk] * MVHD_SECTOR_SIZE, SEEK_SET);
fread(vhdm->bitmap.curr_bitmap, vhdm->bitmap.sector_count * MVHD_SECTOR_SIZE, 1, vhdm->f);
} else
} else {
memset(vhdm->bitmap.curr_bitmap, 0, vhdm->bitmap.sector_count * MVHD_SECTOR_SIZE);
}
vhdm->bitmap.curr_block = blk;
}
@@ -167,6 +169,7 @@ create_block(MVHDMeta* vhdm, int blk)
mvhd_fseeko64(vhdm->f, -MVHD_FOOTER_SIZE, SEEK_END);
fread(footer, sizeof footer, 1, vhdm->f);
mvhd_fseeko64(vhdm->f, -MVHD_FOOTER_SIZE, SEEK_END);
if (!mvhd_is_conectix_str(footer)) {
/* Oh dear. We use the header instead, since something has gone wrong at the footer */
mvhd_fseeko64(vhdm->f, 0, SEEK_SET);

View File

@@ -5,7 +5,7 @@
*
* VHD management functions (open, close, read write etc)
*
* Version: @(#)manage.c 1.0.1 2021/03/16
* Version: @(#)manage.c 1.0.2 2021/03/16
*
* Author: Sherman Perry, <shermperry@gmail.com>
*
@@ -172,8 +172,9 @@ calc_sparse_values(MVHDMeta* vhdm)
int bm_bytes = vhdm->sect_per_block / 8;
vhdm->bitmap.sector_count = bm_bytes / MVHD_SECTOR_SIZE;
if (bm_bytes % MVHD_SECTOR_SIZE > 0)
if (bm_bytes % MVHD_SECTOR_SIZE > 0) {
vhdm->bitmap.sector_count++;
}
}
@@ -225,7 +226,8 @@ static bool
mvhd_parent_path_exists(struct MVHDPaths* paths, uint32_t plat_code)
{
FILE* f;
int cwk_ret, ferr;
int ferr;
size_t cwk_ret;
enum cwk_path_style style;
memset(paths->joined_path, 0, sizeof paths->joined_path);
@@ -234,15 +236,16 @@ mvhd_parent_path_exists(struct MVHDPaths* paths, uint32_t plat_code)
cwk_ret = 1;
if (plat_code == MVHD_DIF_LOC_W2RU && *paths->w2ru_path) {
cwk_ret = (int)cwk_path_join((const char*)paths->dir_path, (const char*)paths->w2ru_path, paths->joined_path, sizeof paths->joined_path);
cwk_ret = cwk_path_join((const char*)paths->dir_path, (const char*)paths->w2ru_path, paths->joined_path, sizeof paths->joined_path);
} else if (plat_code == MVHD_DIF_LOC_W2KU && *paths->w2ku_path) {
memcpy(paths->joined_path, paths->w2ku_path, (sizeof paths->joined_path) - 1);
cwk_ret = 0;
} else if (plat_code == 0) {
cwk_ret = (int)cwk_path_join((const char*)paths->dir_path, (const char*)paths->file_name, paths->joined_path, sizeof paths->joined_path);
cwk_ret = cwk_path_join((const char*)paths->dir_path, (const char*)paths->file_name, paths->joined_path, sizeof paths->joined_path);
}
if (cwk_ret > MVHD_MAX_PATH_BYTES)
if (cwk_ret > MVHD_MAX_PATH_BYTES) {
return false;
}
f = mvhd_fopen((const char*)paths->joined_path, "rb", &ferr);
if (f != NULL) {
@@ -318,8 +321,9 @@ get_diff_parent_path(MVHDMeta* vhdm, int* err)
loc_path = (unsigned char*)paths->w2ru_path;
} else if (vhdm->sparse.par_loc_entry[i].plat_code == MVHD_DIF_LOC_W2KU) {
loc_path = (unsigned char*)paths->w2ku_path;
} else
} else {
continue;
}
utf_inlen = vhdm->sparse.par_loc_entry[i].plat_data_len;
if (utf_inlen > MVHD_MAX_PATH_BYTES) {
@@ -437,13 +441,15 @@ mvhd_file_is_vhd(FILE* f)
{
uint8_t con_str[8];
if (f == NULL)
if (f == NULL) {
return 0;
}
mvhd_fseeko64(f, -MVHD_FOOTER_SIZE, SEEK_END);
fread(con_str, sizeof con_str, 1, f);
if (mvhd_is_conectix_str(con_str))
if (mvhd_is_conectix_str(con_str)) {
return 1;
}
return 0;
}
@@ -511,10 +517,11 @@ mvhd_open(const char* path, int readonly, int* err)
//This is safe, as we've just checked for potential overflow above
strcpy(vhdm->filename, path);
if (readonly)
if (readonly) {
vhdm->f = mvhd_fopen((const char*)vhdm->filename, "rb", err);
else
} else {
vhdm->f = mvhd_fopen((const char*)vhdm->filename, "rb+", err);
}
if (vhdm->f == NULL) {
/* note, mvhd_fopen sets err for us */
goto cleanup_vhdm;

View File

@@ -5,7 +5,7 @@
*
* Utility functions.
*
* Version: @(#)util.c 1.0.1 2021/03/16
* Version: @(#)util.c 1.0.2 2021/03/16
*
* Author: Sherman Perry, <shermperry@gmail.com>
*
@@ -52,14 +52,6 @@
#include "xml2_encoding.h"
static const char MVHD_CONECTIX_COOKIE[] = "conectix";
#if 0 //NOT_USED
static const char MVHD_CREATOR[] = "MiniVHD";
static const char MVHD_CREATOR_HOST_OS[] = "Wi2k";
static const char MVHD_CXSPARSE_COOKIE[] = "cxsparse";
#endif
uint16_t
mvhd_from_be16(uint16_t val)
{
@@ -154,17 +146,6 @@ mvhd_to_be64(uint64_t val)
}
bool
mvhd_is_conectix_str(const void* buffer)
{
if (strncmp(buffer, MVHD_CONECTIX_COOKIE, strlen(MVHD_CONECTIX_COOKIE)) == 0) {
return true;
}
return false;
}
void
mvhd_generate_uuid(uint8_t* uuid)
{

View File

@@ -10,7 +10,7 @@
#
# Makefile for Windows systems using the MinGW32 environment.
#
# Version: @(#)Makefile.MinGW 1.0.1 2021/03/16
# Version: @(#)Makefile.MinGW 1.0.2 2021/03/16
#
# Author: Fred N. van Kempen, <waltje@varcem.com>
#
@@ -170,7 +170,7 @@ SYSLIBS += -static -lgcc
# Final versions of the toolchain flags.
CFLAGS := $(OPTS) $(DFLAGS) $(COPTIM) $(AOPTIM) -I. \
$(AFLAGS) -fomit-frame-pointer -mstackrealign
$(AFLAGS) -fomit-frame-pointer -mstackrealign \
-Wall -Wundef -Wshadow -Wunused-parameter \
-Wmissing-declarations
LFLAGS := -L.