mirror of
https://github.com/open-simh/simtools.git
synced 2026-03-03 01:58:59 +00:00
Windows support for libvhd and vhd-util
Added windows support for libvhd and vhd-util. Includes bug fixes as well. See the README for details.
This commit is contained in:
200
extracters/libvhd/include/blk_uuid.h
Normal file
200
extracters/libvhd/include/blk_uuid.h
Normal file
@@ -0,0 +1,200 @@
|
||||
/* Copyright (c) 2008, XenSource Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of XenSource Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/* Modified March 2016 Timothe Litt to work under windows.
|
||||
* Copyright (C) 2016 Timothe Litt
|
||||
* Modifications subject to the same license terms as above,
|
||||
* substituting "Timothe Litt" for "XenSource Inc."
|
||||
*/
|
||||
|
||||
#ifndef __BLKTAP2_UUID_H__
|
||||
#define __BLKTAP2_UUID_H__
|
||||
|
||||
#if defined(__linux__)
|
||||
|
||||
#include <uuid/uuid.h>
|
||||
|
||||
typedef struct {
|
||||
uuid_t uuid;
|
||||
} blk_uuid_t;
|
||||
|
||||
static inline int blk_uuid_is_nil(blk_uuid_t *uuid)
|
||||
{
|
||||
return uuid_is_null(uuid->uuid);
|
||||
}
|
||||
|
||||
static inline void blk_uuid_generate(blk_uuid_t *uuid)
|
||||
{
|
||||
uuid_generate(uuid->uuid);
|
||||
}
|
||||
|
||||
static inline void blk_uuid_to_string(blk_uuid_t *uuid, char *out, size_t size)
|
||||
{
|
||||
(void) size;
|
||||
uuid_unparse(uuid->uuid, out);
|
||||
}
|
||||
|
||||
static inline void blk_uuid_from_string(blk_uuid_t *uuid, const char *in)
|
||||
{
|
||||
uuid_parse(in, uuid->uuid);
|
||||
}
|
||||
|
||||
static inline void blk_uuid_copy(blk_uuid_t *dst, blk_uuid_t *src)
|
||||
{
|
||||
uuid_copy(dst->uuid, src->uuid);
|
||||
}
|
||||
|
||||
static inline void blk_uuid_clear(blk_uuid_t *uuid)
|
||||
{
|
||||
uuid_clear(uuid->uuid);
|
||||
}
|
||||
|
||||
static inline int blk_uuid_compare(blk_uuid_t *uuid1, blk_uuid_t *uuid2)
|
||||
{
|
||||
return uuid_compare(uuid1->uuid, uuid2->uuid);
|
||||
}
|
||||
|
||||
#elif defined(__NetBSD__)
|
||||
|
||||
#include <uuid.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef uuid_t blk_uuid_t;
|
||||
|
||||
static inline int blk_uuid_is_nil(blk_uuid_t *uuid)
|
||||
{
|
||||
uint32_t status;
|
||||
return uuid_is_nil((uuid_t *)uuid, &status);
|
||||
}
|
||||
|
||||
static inline void blk_uuid_generate(blk_uuid_t *uuid)
|
||||
{
|
||||
uint32_t status;
|
||||
uuid_create((uuid_t *)uuid, &status);
|
||||
}
|
||||
|
||||
static inline void blk_uuid_to_string(blk_uuid_t *uuid, char *out, size_t size)
|
||||
{
|
||||
uint32_t status;
|
||||
char *_out = NULL;
|
||||
uuid_to_string((uuid_t *)uuid, &_out, &status);
|
||||
strlcpy(out, _out, size);
|
||||
free(_out);
|
||||
}
|
||||
|
||||
static inline void blk_uuid_from_string(blk_uuid_t *uuid, const char *in)
|
||||
{
|
||||
uint32_t status;
|
||||
uuid_from_string(in, (uuid_t *)uuid, &status);
|
||||
}
|
||||
|
||||
static inline void blk_uuid_copy(blk_uuid_t *dst, blk_uuid_t *src)
|
||||
{
|
||||
memcpy((uuid_t *)dst, (uuid_t *)src, sizeof(uuid_t));
|
||||
}
|
||||
|
||||
static inline void blk_uuid_clear(blk_uuid_t *uuid)
|
||||
{
|
||||
memset((uuid_t *)uuid, 0, sizeof(uuid_t));
|
||||
}
|
||||
|
||||
static inline int blk_uuid_compare(blk_uuid_t *uuid1, blk_uuid_t *uuid2)
|
||||
{
|
||||
uint32_t status;
|
||||
return uuid_compare((uuid_t *)uuid1, (uuid_t *)uuid2, &status);
|
||||
}
|
||||
|
||||
#elif defined(_WIN32)
|
||||
#include <Rpc.h>
|
||||
typedef UUID blk_uuid_t;
|
||||
|
||||
static size_t strlcpy( char *dst, const char *src, size_t size ) {
|
||||
size_t srclen;
|
||||
|
||||
size--;
|
||||
srclen = strlen( src );
|
||||
|
||||
if( srclen > size )
|
||||
srclen = size;
|
||||
|
||||
memcpy( dst, src, srclen );
|
||||
dst[srclen] = '\0';
|
||||
|
||||
return (srclen);
|
||||
}
|
||||
static inline int blk_uuid_is_nil( blk_uuid_t *uuid )
|
||||
{
|
||||
RPC_STATUS status;
|
||||
return UuidIsNil( (uuid_t *)uuid, &status );
|
||||
}
|
||||
|
||||
static inline void blk_uuid_generate( blk_uuid_t *uuid )
|
||||
{
|
||||
RPC_STATUS status;
|
||||
status = UuidCreate( (uuid_t *)uuid );
|
||||
if( status == RPC_S_OK || status == RPC_S_UUID_LOCAL_ONLY )
|
||||
return;
|
||||
abort();
|
||||
}
|
||||
|
||||
static inline void blk_uuid_to_string( blk_uuid_t *uuid, char *out, size_t size )
|
||||
{
|
||||
RPC_CSTR _out = NULL;
|
||||
if( UuidToString( (uuid_t *)uuid, &_out ) != RPC_S_OK )
|
||||
return;
|
||||
strlcpy( out, (const char *)_out, size );
|
||||
RpcStringFree( &_out );
|
||||
return;
|
||||
}
|
||||
|
||||
static inline void blk_uuid_from_string( blk_uuid_t *uuid, const char *in )
|
||||
{
|
||||
UuidFromString( (RPC_CSTR)in, (uuid_t *)uuid );
|
||||
}
|
||||
|
||||
static inline void blk_uuid_copy( blk_uuid_t *dst, blk_uuid_t *src )
|
||||
{
|
||||
memcpy( (uuid_t *)dst, (uuid_t *)src, sizeof( uuid_t ) );
|
||||
}
|
||||
|
||||
static inline void blk_uuid_clear( blk_uuid_t *uuid )
|
||||
{
|
||||
memset( (uuid_t *)uuid, 0, sizeof( uuid_t ) );
|
||||
}
|
||||
|
||||
static inline int blk_uuid_compare( blk_uuid_t *uuid1, blk_uuid_t *uuid2 )
|
||||
{
|
||||
RPC_STATUS status;
|
||||
return UuidCompare( (uuid_t *)uuid1, (uuid_t *)uuid2, &status );
|
||||
}
|
||||
#else
|
||||
|
||||
#error "Please update blk_uuid.h for your OS"
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __BLKTAP2_UUID_H__ */
|
||||
363
extracters/libvhd/include/libvhd.h
Normal file
363
extracters/libvhd/include/libvhd.h
Normal file
@@ -0,0 +1,363 @@
|
||||
/* Copyright (c) 2008, XenSource Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of XenSource Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/* Modified March 2016 Timothe Litt to work under windows.
|
||||
* Copyright (C) 2016 Timothe Litt
|
||||
* Modifications subject to the same license terms as above,
|
||||
* substituting "Timothe Litt" for "XenSource Inc."
|
||||
*/
|
||||
|
||||
#ifndef _VHD_LIB_H_
|
||||
#define _VHD_LIB_H_
|
||||
|
||||
#define _CRT_SECURE_NO_WARNINGS 1
|
||||
|
||||
#include <string.h>
|
||||
#if defined(__linux__)
|
||||
#include <endian.h>
|
||||
#include <byteswap.h>
|
||||
#elif defined(__NetBSD__)
|
||||
#include <sys/endian.h>
|
||||
#include <sys/bswap.h>
|
||||
#elif defined(_WIN32)
|
||||
#undef BYTE_ORDER
|
||||
#undef LITTLE_ENDIAN
|
||||
#define BYTE_ORDER 1234
|
||||
#define LITTLE_ENDIAN 1234
|
||||
#define bswap_16(val) _byteswap_ushort(val)
|
||||
#define bswap_32(val) _byteswap_ulong(val)
|
||||
#define bswap_64(val) _byteswap_uint64(val)
|
||||
#endif
|
||||
|
||||
#include "blk_uuid.h"
|
||||
#include "vhd.h"
|
||||
|
||||
#ifndef O_LARGEFILE
|
||||
#define O_LARGEFILE 0
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && defined(LIBVHD_DLL)
|
||||
#ifdef LIBVHD_EXPORTS
|
||||
#define LIBVHD_API __declspec(dllexport)
|
||||
#else
|
||||
#define LIBVHD_API __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define LIBVHD_API
|
||||
#endif
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
#if defined(__linux__) || defined(_WIN32)
|
||||
#define BE16_IN(foo) (*(foo)) = bswap_16(*(foo))
|
||||
#define BE32_IN(foo) (*(foo)) = bswap_32(*(foo))
|
||||
#define BE64_IN(foo) (*(foo)) = bswap_64(*(foo))
|
||||
#define BE16_OUT(foo) (*(foo)) = bswap_16(*(foo))
|
||||
#define BE32_OUT(foo) (*(foo)) = bswap_32(*(foo))
|
||||
#define BE64_OUT(foo) (*(foo)) = bswap_64(*(foo))
|
||||
#elif defined(__NetBSD__)
|
||||
#define BE16_IN(foo) (*(foo)) = bswap16(*(foo))
|
||||
#define BE32_IN(foo) (*(foo)) = bswap32(*(foo))
|
||||
#define BE64_IN(foo) (*(foo)) = bswap64(*(foo))
|
||||
#define BE16_OUT(foo) (*(foo)) = bswap16(*(foo))
|
||||
#define BE32_OUT(foo) (*(foo)) = bswap32(*(foo))
|
||||
#define BE64_OUT(foo) (*(foo)) = bswap64(*(foo))
|
||||
#endif
|
||||
#else
|
||||
#define BE16_IN(foo)
|
||||
#define BE32_IN(foo)
|
||||
#define BE64_IN(foo)
|
||||
#define BE32_OUT(foo)
|
||||
#define BE32_OUT(foo)
|
||||
#define BE64_OUT(foo)
|
||||
#endif
|
||||
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
#define VHD_MAX_NAME_LEN 1024
|
||||
|
||||
#define VHD_BLOCK_SHIFT 21
|
||||
#define VHD_BLOCK_SIZE (1ULL << VHD_BLOCK_SHIFT)
|
||||
|
||||
#define UTF_16 "UTF-16"
|
||||
#define UTF_16LE "UTF-16LE"
|
||||
#define UTF_16BE "UTF-16BE"
|
||||
|
||||
#define VHD_OPEN_RDONLY 0x00001
|
||||
#define VHD_OPEN_RDWR 0x00002
|
||||
#define VHD_OPEN_FAST 0x00004
|
||||
#define VHD_OPEN_STRICT 0x00008
|
||||
#define VHD_OPEN_IGNORE_DISABLED 0x00010
|
||||
|
||||
#define VHD_FLAG_CREAT_PARENT_RAW 0x00001
|
||||
|
||||
#define vhd_flag_set(word, flag) ((word) |= (flag))
|
||||
#define vhd_flag_clear(word, flag) ((word) &= ~(flag))
|
||||
#define vhd_flag_test(word, flag) ((word) & (flag))
|
||||
|
||||
|
||||
#ifndef _WIN32x
|
||||
#define ENABLE_FAILURE_TESTING 1
|
||||
#endif
|
||||
#define FAIL_REPARENT_BEGIN 0
|
||||
#define FAIL_REPARENT_LOCATOR 1
|
||||
#define FAIL_REPARENT_END 2
|
||||
#define FAIL_RESIZE_BEGIN 3
|
||||
#define FAIL_RESIZE_DATA_MOVED 4
|
||||
#define FAIL_RESIZE_METADATA_MOVED 5
|
||||
#define FAIL_RESIZE_END 6
|
||||
#define NUM_FAIL_TESTS 7
|
||||
|
||||
#ifdef ENABLE_FAILURE_TESTING
|
||||
#define TEST_FAIL_AT(point) \
|
||||
if (TEST_FAIL[point]) { \
|
||||
printf("Failing at %s\n", ENV_VAR_FAIL[point]); exit(EINVAL); }
|
||||
#ifdef _WIN32
|
||||
#define TEST_FAIL_EXTERN_VARS \
|
||||
LIBVHD_API extern const char* ENV_VAR_FAIL[]; \
|
||||
LIBVHD_API extern int TEST_FAIL[];
|
||||
#else
|
||||
#define TEST_FAIL_EXTERN_VARS \
|
||||
extern const char* ENV_VAR_FAIL[]; \
|
||||
extern int TEST_FAIL[];
|
||||
#endif
|
||||
#else
|
||||
#define TEST_FAIL_AT(point)
|
||||
#define TEST_FAIL_EXTERN_VARS
|
||||
#endif /* ENABLE_FAILURE_TESTING */
|
||||
|
||||
|
||||
static const char VHD_POISON_COOKIE[] = "v_poison";
|
||||
|
||||
typedef struct hd_ftr vhd_footer_t;
|
||||
typedef struct dd_hdr vhd_header_t;
|
||||
typedef struct vhd_bat vhd_bat_t;
|
||||
typedef struct vhd_batmap vhd_batmap_t;
|
||||
typedef struct dd_batmap_hdr vhd_batmap_header_t;
|
||||
typedef struct prt_loc vhd_parent_locator_t;
|
||||
typedef struct vhd_context vhd_context_t;
|
||||
typedef uint32_t vhd_flag_creat_t;
|
||||
|
||||
struct vhd_bat {
|
||||
uint32_t spb;
|
||||
uint32_t entries;
|
||||
uint32_t *bat;
|
||||
};
|
||||
|
||||
struct vhd_batmap {
|
||||
vhd_batmap_header_t header;
|
||||
char *map;
|
||||
};
|
||||
|
||||
struct vhd_context {
|
||||
int fd;
|
||||
char *file;
|
||||
int oflags;
|
||||
int is_block;
|
||||
|
||||
uint32_t spb;
|
||||
uint32_t bm_secs;
|
||||
|
||||
vhd_header_t header;
|
||||
vhd_footer_t footer;
|
||||
vhd_bat_t bat;
|
||||
vhd_batmap_t batmap;
|
||||
};
|
||||
|
||||
static inline uint32_t
|
||||
secs_round_up(uint64_t bytes)
|
||||
{
|
||||
return (uint32_t)((bytes + (VHD_SECTOR_SIZE - 1)) >> VHD_SECTOR_SHIFT);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
secs_round_up_no_zero(uint64_t bytes)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
result = secs_round_up(bytes);
|
||||
return ( result? result : 1);
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
vhd_sectors_to_bytes(uint64_t sectors)
|
||||
{
|
||||
return sectors << VHD_SECTOR_SHIFT;
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
vhd_bytes_padded(uint64_t bytes)
|
||||
{
|
||||
return vhd_sectors_to_bytes(secs_round_up_no_zero(bytes));
|
||||
}
|
||||
|
||||
static inline int
|
||||
vhd_type_dynamic(vhd_context_t *ctx)
|
||||
{
|
||||
return (ctx->footer.type == HD_TYPE_DYNAMIC ||
|
||||
ctx->footer.type == HD_TYPE_DIFF);
|
||||
}
|
||||
|
||||
static inline int
|
||||
vhd_creator_tapdisk(vhd_context_t *ctx)
|
||||
{
|
||||
return !strncmp(ctx->footer.crtr_app, "tap", 3);
|
||||
}
|
||||
|
||||
static inline int
|
||||
vhd_disabled(vhd_context_t *ctx)
|
||||
{
|
||||
return (!memcmp(ctx->footer.cookie,
|
||||
VHD_POISON_COOKIE, sizeof(ctx->footer.cookie)));
|
||||
}
|
||||
|
||||
static inline size_t
|
||||
vhd_parent_locator_size(vhd_parent_locator_t *loc)
|
||||
{
|
||||
/*
|
||||
* MICROSOFT_COMPAT
|
||||
* data_space *should* be in sectors,
|
||||
* but sometimes we find it in bytes
|
||||
*/
|
||||
if (loc->data_space < 512)
|
||||
return (size_t)vhd_sectors_to_bytes(loc->data_space);
|
||||
else if (loc->data_space % 512 == 0)
|
||||
return loc->data_space;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
vhd_parent_raw(vhd_context_t *ctx)
|
||||
{
|
||||
return blk_uuid_is_nil(&ctx->header.prt_uuid);
|
||||
}
|
||||
|
||||
LIBVHD_API void libvhd_set_log_level(int);
|
||||
|
||||
LIBVHD_API int vhd_test_file_fixed(const char *, int *);
|
||||
|
||||
LIBVHD_API uint32_t vhd_time(time_t time);
|
||||
LIBVHD_API size_t vhd_time_to_string(uint32_t timestamp, char *target);
|
||||
LIBVHD_API uint32_t vhd_chs(uint64_t size);
|
||||
|
||||
LIBVHD_API uint32_t vhd_checksum_footer(vhd_footer_t *);
|
||||
LIBVHD_API uint32_t vhd_checksum_header(vhd_header_t *);
|
||||
LIBVHD_API uint32_t vhd_checksum_batmap(vhd_batmap_t *);
|
||||
|
||||
LIBVHD_API void vhd_footer_in(vhd_footer_t *);
|
||||
LIBVHD_API void vhd_footer_out(vhd_footer_t *);
|
||||
LIBVHD_API void vhd_header_in(vhd_header_t *);
|
||||
LIBVHD_API void vhd_header_out(vhd_header_t *);
|
||||
LIBVHD_API void vhd_bat_in(vhd_bat_t *);
|
||||
LIBVHD_API void vhd_bat_out(vhd_bat_t *);
|
||||
LIBVHD_API void vhd_batmap_header_in(vhd_batmap_t *);
|
||||
LIBVHD_API void vhd_batmap_header_out(vhd_batmap_t *);
|
||||
|
||||
LIBVHD_API int vhd_validate_footer(vhd_footer_t *footer);
|
||||
LIBVHD_API int vhd_validate_header(vhd_header_t *header);
|
||||
LIBVHD_API int vhd_validate_batmap_header(vhd_batmap_t *batmap);
|
||||
LIBVHD_API int vhd_validate_batmap(vhd_batmap_t *batmap);
|
||||
LIBVHD_API int vhd_validate_platform_code(uint32_t code);
|
||||
|
||||
LIBVHD_API int vhd_open(vhd_context_t *, const char *file, int flags);
|
||||
LIBVHD_API void vhd_close(vhd_context_t *);
|
||||
LIBVHD_API int vhd_create(const char *name, uint64_t bytes, int type, vhd_flag_creat_t);
|
||||
/* vhd_snapshot: the bytes parameter is optional and can be 0 if the snapshot
|
||||
* is to have the same size as the (first non-empty) parent */
|
||||
LIBVHD_API int vhd_snapshot(const char *snapshot, uint64_t bytes, const char *parent,
|
||||
vhd_flag_creat_t);
|
||||
|
||||
LIBVHD_API int vhd_hidden(vhd_context_t *, int *);
|
||||
LIBVHD_API int vhd_chain_depth(vhd_context_t *, int *);
|
||||
|
||||
LIBVHD_API off_t vhd_position(vhd_context_t *);
|
||||
LIBVHD_API int vhd_seek(vhd_context_t *, off_t, int);
|
||||
LIBVHD_API int vhd_read(vhd_context_t *, void *, size_t);
|
||||
LIBVHD_API int vhd_write(vhd_context_t *, void *, size_t);
|
||||
|
||||
LIBVHD_API int vhd_offset(vhd_context_t *, uint32_t, uint32_t *);
|
||||
|
||||
LIBVHD_API int vhd_end_of_headers(vhd_context_t *ctx, off_t *off);
|
||||
LIBVHD_API int vhd_end_of_data(vhd_context_t *ctx, off_t *off);
|
||||
LIBVHD_API int vhd_batmap_header_offset(vhd_context_t *ctx, off_t *off);
|
||||
|
||||
LIBVHD_API int vhd_get_header(vhd_context_t *);
|
||||
LIBVHD_API int vhd_get_footer(vhd_context_t *);
|
||||
LIBVHD_API int vhd_get_bat(vhd_context_t *);
|
||||
LIBVHD_API int vhd_get_batmap(vhd_context_t *);
|
||||
|
||||
LIBVHD_API void vhd_put_header(vhd_context_t *);
|
||||
LIBVHD_API void vhd_put_footer(vhd_context_t *);
|
||||
LIBVHD_API void vhd_put_bat(vhd_context_t *);
|
||||
LIBVHD_API void vhd_put_batmap(vhd_context_t *);
|
||||
|
||||
LIBVHD_API int vhd_has_batmap(vhd_context_t *);
|
||||
LIBVHD_API int vhd_batmap_test(vhd_context_t *, vhd_batmap_t *, uint32_t);
|
||||
LIBVHD_API void vhd_batmap_set(vhd_context_t *, vhd_batmap_t *, uint32_t);
|
||||
LIBVHD_API void vhd_batmap_clear(vhd_context_t *, vhd_batmap_t *, uint32_t);
|
||||
|
||||
LIBVHD_API int vhd_get_phys_size(vhd_context_t *, off_t *);
|
||||
LIBVHD_API int vhd_set_phys_size(vhd_context_t *, off_t);
|
||||
|
||||
LIBVHD_API int vhd_bitmap_test(vhd_context_t *, char *, uint32_t);
|
||||
LIBVHD_API void vhd_bitmap_set(vhd_context_t *, char *, uint32_t);
|
||||
LIBVHD_API void vhd_bitmap_clear(vhd_context_t *, char *, uint32_t);
|
||||
|
||||
LIBVHD_API int vhd_parent_locator_count(vhd_context_t *);
|
||||
LIBVHD_API int vhd_parent_locator_get(vhd_context_t *, char **);
|
||||
LIBVHD_API int vhd_parent_locator_read(vhd_context_t *, vhd_parent_locator_t *, char **);
|
||||
LIBVHD_API int vhd_find_parent(vhd_context_t *, const char *, char **);
|
||||
LIBVHD_API int vhd_parent_locator_write_at(vhd_context_t *, const char *,
|
||||
off_t, uint32_t, size_t,
|
||||
vhd_parent_locator_t *);
|
||||
|
||||
LIBVHD_API int vhd_header_decode_parent(vhd_context_t *, vhd_header_t *, char **);
|
||||
LIBVHD_API int vhd_change_parent(vhd_context_t *, char *parent_path, int raw);
|
||||
|
||||
LIBVHD_API int vhd_read_footer(vhd_context_t *, vhd_footer_t *);
|
||||
LIBVHD_API int vhd_read_footer_at(vhd_context_t *, vhd_footer_t *, off_t);
|
||||
LIBVHD_API int vhd_read_footer_strict(vhd_context_t *, vhd_footer_t *);
|
||||
LIBVHD_API int vhd_read_header(vhd_context_t *, vhd_header_t *);
|
||||
LIBVHD_API int vhd_read_header_at(vhd_context_t *, vhd_header_t *, off_t);
|
||||
LIBVHD_API int vhd_read_bat(vhd_context_t *, vhd_bat_t *);
|
||||
LIBVHD_API int vhd_read_batmap(vhd_context_t *, vhd_batmap_t *);
|
||||
LIBVHD_API int vhd_read_bitmap(vhd_context_t *, uint32_t block, char **bufp);
|
||||
LIBVHD_API int vhd_read_block(vhd_context_t *, uint32_t block, char **bufp);
|
||||
|
||||
LIBVHD_API int vhd_write_footer(vhd_context_t *, vhd_footer_t *);
|
||||
LIBVHD_API int vhd_write_footer_at(vhd_context_t *, vhd_footer_t *, off_t);
|
||||
LIBVHD_API int vhd_write_header(vhd_context_t *, vhd_header_t *);
|
||||
LIBVHD_API int vhd_write_header_at(vhd_context_t *, vhd_header_t *, off_t);
|
||||
LIBVHD_API int vhd_write_bat(vhd_context_t *, vhd_bat_t *);
|
||||
LIBVHD_API int vhd_write_batmap(vhd_context_t *, vhd_batmap_t *);
|
||||
LIBVHD_API int vhd_write_bitmap(vhd_context_t *, uint32_t block, char *bitmap);
|
||||
LIBVHD_API int vhd_write_block(vhd_context_t *, uint32_t block, char *data);
|
||||
|
||||
LIBVHD_API int vhd_io_read(vhd_context_t *, char *, uint64_t, uint32_t);
|
||||
LIBVHD_API int vhd_io_write(vhd_context_t *, char *, uint64_t, uint32_t);
|
||||
|
||||
#endif
|
||||
59
extracters/libvhd/include/relative-path.h
Normal file
59
extracters/libvhd/include/relative-path.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/* Copyright (c) 2008, XenSource Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of XenSource Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/* Modified March 2016 Timothe Litt to work under windows.
|
||||
* Copyright (C) 2016 Timothe Litt
|
||||
* Modifications subject to the same license terms as above,
|
||||
* substituting "Timothe Litt" for "XenSource Inc."
|
||||
*/
|
||||
|
||||
#ifndef _RELATIVE_PATH_H_
|
||||
#define _RELATIVE_PATH_H_
|
||||
|
||||
#define MAX_NAME_LEN 1000
|
||||
|
||||
#if defined(_WIN32) && defined(LIBVHD_DLL)
|
||||
#ifdef LIBVHD_EXPORTS
|
||||
#define LIBVHD_API __declspec(dllexport)
|
||||
#else
|
||||
#define LIBVHD_API __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define LIBVHD_API
|
||||
#endif
|
||||
|
||||
/*
|
||||
* returns a relative path from @src to @dest
|
||||
* result should be freed
|
||||
*/
|
||||
LIBVHD_API char *relative_path_to(char *src, char *dest, int *err);
|
||||
|
||||
#ifdef _WIN32
|
||||
LIBVHD_API char *realpath( const char *path, char *resolved );
|
||||
LIBVHD_API int asprintf( char **result, const char *fmt, ... );
|
||||
#endif
|
||||
|
||||
#endif
|
||||
228
extracters/libvhd/include/vhd.h
Normal file
228
extracters/libvhd/include/vhd.h
Normal file
@@ -0,0 +1,228 @@
|
||||
/* Copyright (c) 2008, XenSource Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of XenSource Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/* Modified March 2016 Timothe Litt to work under windows.
|
||||
* Copyright (C) 2016 Timothe Litt
|
||||
* Modifications subject to the same license terms as above,
|
||||
* substituting "Timothe Litt" for "XenSource Inc."
|
||||
*/
|
||||
#ifndef __VHD_H__
|
||||
#define __VHD_H__
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
typedef uint32_t u32;
|
||||
typedef uint64_t u64;
|
||||
|
||||
/* #define DEBUG 1 */
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* General definitions. */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#define VHD_SECTOR_SIZE 512
|
||||
#define VHD_SECTOR_SHIFT 9
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* This is the generic disk footer, used by all disks. */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
struct hd_ftr {
|
||||
char cookie[8]; /* Identifies original creator of the disk */
|
||||
u32 features; /* Feature Support -- see below */
|
||||
u32 ff_version; /* (major,minor) version of disk file */
|
||||
u64 data_offset; /* Abs. offset from SOF to next structure */
|
||||
u32 timestamp; /* Creation time. secs since 1/1/2000GMT */
|
||||
char crtr_app[4]; /* Creator application */
|
||||
u32 crtr_ver; /* Creator version (major,minor) */
|
||||
u32 crtr_os; /* Creator host OS */
|
||||
u64 orig_size; /* Size at creation (bytes) */
|
||||
u64 curr_size; /* Current size of disk (bytes) */
|
||||
u32 geometry; /* Disk geometry */
|
||||
u32 type; /* Disk type */
|
||||
u32 checksum; /* 1's comp sum of this struct. */
|
||||
blk_uuid_t uuid; /* Unique disk ID, used for naming parents */
|
||||
char saved; /* one-bit -- is this disk/VM in a saved state? */
|
||||
char hidden; /* tapdisk-specific field: is this vdi hidden? */
|
||||
char reserved[426]; /* padding */
|
||||
};
|
||||
|
||||
/* VHD cookie string. */
|
||||
static const char HD_COOKIE[9] = "conectix";
|
||||
|
||||
/* Feature fields in hd_ftr */
|
||||
#define HD_NO_FEATURES 0x00000000
|
||||
#define HD_TEMPORARY 0x00000001 /* disk can be deleted on shutdown */
|
||||
#define HD_RESERVED 0x00000002 /* NOTE: must always be set */
|
||||
|
||||
/* Version field in hd_ftr */
|
||||
#define HD_FF_VERSION 0x00010000
|
||||
|
||||
/* Known creator OS type fields in hd_ftr.crtr_os */
|
||||
#define HD_CR_OS_WINDOWS 0x5769326B /* (Wi2k) */
|
||||
#define HD_CR_OS_MACINTOSH 0x4D616320 /* (Mac ) */
|
||||
#define HD_CR_OS_UNIX 0x556E6978 /* (Unix) */
|
||||
#define HD_CR_OS_VMS 0x4F564D53 /* (OVMS) */
|
||||
/*
|
||||
* version 0.1: little endian bitmaps
|
||||
* version 1.1: big endian bitmaps; batmap
|
||||
* version 1.2: libvhd
|
||||
* version 1.3: batmap version bump to 1.2
|
||||
*/
|
||||
#define VHD_VERSION(major, minor) (((major) << 16) | ((minor) & 0x0000FFFF))
|
||||
#define VHD_CURRENT_VERSION VHD_VERSION(1, 3)
|
||||
|
||||
/* Disk geometry accessor macros. */
|
||||
/* Geometry is a triple of (cylinders (2 bytes), tracks (1 byte), and
|
||||
* secotrs-per-track (1 byte))
|
||||
*/
|
||||
#define GEOM_GET_CYLS(_g) (((_g) >> 16) & 0xffff)
|
||||
#define GEOM_GET_HEADS(_g) (((_g) >> 8) & 0xff)
|
||||
#define GEOM_GET_SPT(_g) ((_g) & 0xff)
|
||||
|
||||
#define GEOM_ENCODE(_c, _h, _s) (((_c) << 16) | ((_h) << 8) | (_s))
|
||||
|
||||
/* type field in hd_ftr */
|
||||
#define HD_TYPE_NONE 0
|
||||
#define HD_TYPE_FIXED 2 /* fixed-allocation disk */
|
||||
#define HD_TYPE_DYNAMIC 3 /* dynamic disk */
|
||||
#define HD_TYPE_DIFF 4 /* differencing disk */
|
||||
|
||||
/* String table for hd.type */
|
||||
#ifdef __GNUC__
|
||||
__attribute__((unused))
|
||||
#endif
|
||||
static const char *HD_TYPE_STR[7] = {
|
||||
"None", /* 0 */
|
||||
"Reserved (deprecated)", /* 1 */
|
||||
"Fixed hard disk", /* 2 */
|
||||
"Dynamic hard disk", /* 3 */
|
||||
"Differencing hard disk", /* 4 */
|
||||
"Reserved (deprecated)", /* 5 */
|
||||
"Reserved (deprecated)" /* 6 */
|
||||
};
|
||||
|
||||
#define HD_TYPE_MAX 6
|
||||
|
||||
struct prt_loc {
|
||||
u32 code; /* Platform code -- see defines below. */
|
||||
u32 data_space; /* Number of 512-byte sectors to store locator */
|
||||
u32 data_len; /* Actual length of parent locator in bytes */
|
||||
u32 res; /* Must be zero */
|
||||
u64 data_offset; /* Absolute offset of locator data (bytes) */
|
||||
};
|
||||
|
||||
/* Platform Codes */
|
||||
#define PLAT_CODE_NONE 0x0
|
||||
#define PLAT_CODE_WI2R 0x57693272 /* deprecated */
|
||||
#define PLAT_CODE_WI2K 0x5769326B /* deprecated */
|
||||
#define PLAT_CODE_W2RU 0x57327275 /* Windows relative path (UTF-16) */
|
||||
#define PLAT_CODE_W2KU 0x57326B75 /* Windows absolute path (UTF-16) */
|
||||
#define PLAT_CODE_MAC 0x4D616320 /* MacOS alias stored as a blob. */
|
||||
#define PLAT_CODE_MACX 0x4D616358 /* File URL (UTF-8), see RFC 2396. */
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* This is the dynamic disk header. */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
struct dd_hdr {
|
||||
char cookie[8]; /* Should contain "cxsparse" */
|
||||
u64 data_offset; /* Byte offset of next record. (Unused) 0xffs */
|
||||
u64 table_offset; /* Absolute offset to the BAT. */
|
||||
u32 hdr_ver; /* Version of the dd_hdr (major,minor) */
|
||||
u32 max_bat_size; /* Maximum number of entries in the BAT */
|
||||
u32 block_size; /* Block size in bytes. Must be power of 2. */
|
||||
u32 checksum; /* Header checksum. 1's comp of all fields. */
|
||||
blk_uuid_t prt_uuid; /* ID of the parent disk. */
|
||||
u32 prt_ts; /* Modification time of the parent disk */
|
||||
u32 res1; /* Reserved. */
|
||||
char prt_name[512]; /* Parent unicode name. */
|
||||
struct prt_loc loc[8]; /* Parent locator entries. */
|
||||
char res2[256]; /* Reserved. */
|
||||
};
|
||||
|
||||
/* VHD cookie string. */
|
||||
static const char DD_COOKIE[9] = "cxsparse";
|
||||
|
||||
/* Version field in hd_ftr */
|
||||
#define DD_VERSION 0x00010000
|
||||
|
||||
/* Default blocksize is 2 meg. */
|
||||
#define DD_BLOCKSIZE_DEFAULT 0x00200000
|
||||
|
||||
#define DD_BLK_UNUSED 0xFFFFFFFF
|
||||
|
||||
struct dd_batmap_hdr {
|
||||
char cookie[8]; /* should contain "tdbatmap" */
|
||||
u64 batmap_offset; /* byte offset to batmap */
|
||||
u32 batmap_size; /* batmap size in sectors */
|
||||
u32 batmap_version; /* version of batmap */
|
||||
u32 checksum; /* batmap checksum -- 1's complement of batmap */
|
||||
};
|
||||
|
||||
static const char VHD_BATMAP_COOKIE[9] = "tdbatmap";
|
||||
|
||||
/*
|
||||
* version 1.1: signed char checksum
|
||||
*/
|
||||
#define VHD_BATMAP_VERSION(major, minor) (((major) << 16) | ((minor) & 0x0000FFFF))
|
||||
#define VHD_BATMAP_CURRENT_VERSION VHD_BATMAP_VERSION(1, 2)
|
||||
|
||||
/* Layout of a dynamic disk:
|
||||
*
|
||||
* +-------------------------------------------------+
|
||||
* | Mirror image of HD footer (hd_ftr) (512 bytes) |
|
||||
* +-------------------------------------------------+
|
||||
* | Sparse drive header (dd_hdr) (1024 bytes) |
|
||||
* +-------------------------------------------------+
|
||||
* | BAT (Block allocation table) |
|
||||
* | - Array of absolute sector offsets into the |
|
||||
* | file (u32). |
|
||||
* | - Rounded up to a sector boundary. |
|
||||
* | - Unused entries are marked as 0xFFFFFFFF |
|
||||
* | - max entries in dd_hdr->max_bat_size |
|
||||
* +-------------------------------------------------+
|
||||
* | Data Block 0 |
|
||||
* | Bitmap (padded to 512 byte sector boundary) |
|
||||
* | - each bit indicates whether the associated |
|
||||
* | sector within this block is used. |
|
||||
* | Data |
|
||||
* | - power-of-two multiple of sectors. |
|
||||
* | - default 2MB (4096 * 512) |
|
||||
* | - Any entries with zero in bitmap should be |
|
||||
* | zero on disk |
|
||||
* +-------------------------------------------------+
|
||||
* | Data Block 1 |
|
||||
* +-------------------------------------------------+
|
||||
* | ... |
|
||||
* +-------------------------------------------------+
|
||||
* | Data Block n |
|
||||
* +-------------------------------------------------+
|
||||
* | HD Footer (511 bytes) |
|
||||
* +-------------------------------------------------+
|
||||
*/
|
||||
|
||||
#endif
|
||||
4190
extracters/libvhd/libvhd.c
Normal file
4190
extracters/libvhd/libvhd.c
Normal file
File diff suppressed because it is too large
Load Diff
41
extracters/libvhd/libvhd.sln
Normal file
41
extracters/libvhd/libvhd.sln
Normal file
@@ -0,0 +1,41 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.24720.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libvhd", "libvhd.vcxproj", "{695E504C-32F4-43AF-8AD6-761DE66D0EAB}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vhd-util", "..\vhd-util\vhd-util.vcxproj", "{CC5FB437-0C01-4ECF-A75F-10C37B607AC6}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{695E504C-32F4-43AF-8AD6-761DE66D0EAB} = {695E504C-32F4-43AF-8AD6-761DE66D0EAB}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{695E504C-32F4-43AF-8AD6-761DE66D0EAB}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{695E504C-32F4-43AF-8AD6-761DE66D0EAB}.Debug|x64.Build.0 = Debug|x64
|
||||
{695E504C-32F4-43AF-8AD6-761DE66D0EAB}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{695E504C-32F4-43AF-8AD6-761DE66D0EAB}.Debug|x86.Build.0 = Debug|Win32
|
||||
{695E504C-32F4-43AF-8AD6-761DE66D0EAB}.Release|x64.ActiveCfg = Release|x64
|
||||
{695E504C-32F4-43AF-8AD6-761DE66D0EAB}.Release|x64.Build.0 = Release|x64
|
||||
{695E504C-32F4-43AF-8AD6-761DE66D0EAB}.Release|x86.ActiveCfg = Release|Win32
|
||||
{695E504C-32F4-43AF-8AD6-761DE66D0EAB}.Release|x86.Build.0 = Release|Win32
|
||||
{CC5FB437-0C01-4ECF-A75F-10C37B607AC6}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{CC5FB437-0C01-4ECF-A75F-10C37B607AC6}.Debug|x64.Build.0 = Debug|x64
|
||||
{CC5FB437-0C01-4ECF-A75F-10C37B607AC6}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{CC5FB437-0C01-4ECF-A75F-10C37B607AC6}.Debug|x86.Build.0 = Debug|Win32
|
||||
{CC5FB437-0C01-4ECF-A75F-10C37B607AC6}.Release|x64.ActiveCfg = Release|x64
|
||||
{CC5FB437-0C01-4ECF-A75F-10C37B607AC6}.Release|x64.Build.0 = Release|x64
|
||||
{CC5FB437-0C01-4ECF-A75F-10C37B607AC6}.Release|x86.ActiveCfg = Release|Win32
|
||||
{CC5FB437-0C01-4ECF-A75F-10C37B607AC6}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
125
extracters/libvhd/libvhd.vcxproj
Normal file
125
extracters/libvhd/libvhd.vcxproj
Normal file
@@ -0,0 +1,125 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{695E504C-32F4-43AF-8AD6-761DE66D0EAB}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<AdditionalDependencies>Rpcrt4.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateMapFile>false</GenerateMapFile>
|
||||
<MapExports>true</MapExports>
|
||||
</Link>
|
||||
<Lib>
|
||||
<AdditionalLibraryDirectories />
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<AdditionalIncludeDirectories>include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>Rpcrt4.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<Lib>
|
||||
<AdditionalLibraryDirectories />
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="libvhd.c" />
|
||||
<ClCompile Include="relative-path.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="include\blk_uuid.h" />
|
||||
<ClInclude Include="include\libvhd.h" />
|
||||
<ClInclude Include="include\relative-path.h" />
|
||||
<ClInclude Include="include\vhd.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
39
extracters/libvhd/libvhd.vcxproj.filters
Normal file
39
extracters/libvhd/libvhd.vcxproj.filters
Normal file
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="libvhd.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="relative-path.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="include\blk_uuid.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\libvhd.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\relative-path.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\vhd.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
442
extracters/libvhd/relative-path.c
Normal file
442
extracters/libvhd/relative-path.c
Normal file
@@ -0,0 +1,442 @@
|
||||
/* Copyright (c) 2008, XenSource Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of XenSource Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/* Modified March 2016 Timothe Litt to work under windows.
|
||||
* Copyright (C) 2016 Timothe Litt
|
||||
* Modifications subject to the same license terms as above,
|
||||
* substituting "Timothe Litt" for "XenSource Inc."
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
#define _CRT_SECURE_NO_WARNINGS 1
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "relative-path.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include <Shlwapi.h>
|
||||
#define strdup _strdup
|
||||
#else
|
||||
#include <syslog.h>
|
||||
#endif
|
||||
|
||||
#define DELIMITER '/'
|
||||
|
||||
#define FN __func__
|
||||
|
||||
#define EPRINTF(a) rpath_log_error a
|
||||
|
||||
static void rpath_log_error( const char *func, const char *fmt, ... )
|
||||
#ifdef __GNUC__
|
||||
__attribute__((format(printf,2,3)));
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
|
||||
#ifndef LIBVHD_HAS_SYSLOG
|
||||
#ifdef _WIN32
|
||||
#define LIBVHD_HAS_SYSLOG 0
|
||||
#else
|
||||
#define LIBVHD_HAS_SYSLOG 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define sfree(ptr) \
|
||||
do { \
|
||||
free(ptr); \
|
||||
ptr = NULL; \
|
||||
} while (0)
|
||||
|
||||
#ifdef _WIN32
|
||||
LIBVHD_API char *realpath( const char *path, char *resolved ) {
|
||||
char *p;
|
||||
DWORD len;
|
||||
|
||||
p = resolved;
|
||||
if( resolved == NULL ) {
|
||||
resolved = malloc( 1+ MAX_PATH + 1 );
|
||||
if( resolved == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if( (len = GetFullPathName( path[0] == '/'? path+1:path, MAX_PATH + 1, resolved, NULL )) == 0 ) {
|
||||
if( p == NULL )
|
||||
free( resolved );
|
||||
return NULL;
|
||||
}
|
||||
if( len > MAX_PATH ) {
|
||||
if( p != NULL )
|
||||
return NULL;
|
||||
if( (p = realloc( resolved, len )) == NULL ) {
|
||||
free( resolved );
|
||||
return NULL;
|
||||
}
|
||||
resolved = p;
|
||||
len = GetFullPathName( path, MAX_PATH + 1, resolved, NULL );
|
||||
if( len > MAX_PATH || len == 0 ) {
|
||||
free( resolved );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for( p = resolved; *p; p++ ) {
|
||||
if( *p == '\\')
|
||||
*p = '/';
|
||||
}
|
||||
for( p = resolved; isalpha( *p ); p++ )
|
||||
;
|
||||
if( *p == ':' ) { /* Hide drive under '/' for callers. */
|
||||
memmove( resolved + 1, resolved, strlen( resolved ) +1 );
|
||||
resolved[0] = '/'; /* Callers must skip '/' when touching filesystem. */
|
||||
}
|
||||
return resolved;
|
||||
}
|
||||
LIBVHD_API int asprintf( char **result, const char *fmt, ... ) {
|
||||
int len;
|
||||
va_list ap;
|
||||
char *np;
|
||||
|
||||
/* It would be better to va_copy() the list and do a prescan,
|
||||
* but va_copy apparently has issues with versions of MS C
|
||||
* still in the field. This approach is ugly and wasteful, but
|
||||
* should work. (A KB just isn't what it used to be...)
|
||||
*/
|
||||
if( (*result = malloc( 1 * 100 * 1000 + 1 )) == NULL )
|
||||
return -1;
|
||||
va_start( ap, fmt );
|
||||
len = vsprintf( *result, fmt, ap );
|
||||
np = realloc( *result, len + 1 );
|
||||
if( np != NULL )
|
||||
*result = np;
|
||||
return len;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* count number of tokens between DELIMITER characters
|
||||
*/
|
||||
|
||||
int count_nodes(char *path)
|
||||
{
|
||||
int i;
|
||||
char *tmp;
|
||||
|
||||
if (!path)
|
||||
return 0;
|
||||
|
||||
for (i = 0, tmp = path; *tmp != '\0'; tmp++)
|
||||
if (*tmp == DELIMITER)
|
||||
i++;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* return copy of next node in @path, or NULL
|
||||
* @path is moved to the end of the next node
|
||||
* @err is set to -errno on failure
|
||||
* copy should be freed
|
||||
*/
|
||||
static char *
|
||||
next_node(char **path, int *err)
|
||||
{
|
||||
int ret;
|
||||
char *tmp, *start;
|
||||
|
||||
if (!path || !*path) {
|
||||
*err = -EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*err = 0;
|
||||
start = *path;
|
||||
|
||||
for (tmp = *path; *tmp != '\0'; tmp++)
|
||||
if (*tmp == DELIMITER) {
|
||||
int size;
|
||||
char *node;
|
||||
|
||||
size = tmp - start + 1;
|
||||
node = malloc(size);
|
||||
if (!node) {
|
||||
*err = -ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = snprintf(node, size, "%s", start);
|
||||
if (ret < 0) {
|
||||
free(node);
|
||||
*err = -EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*path = tmp;
|
||||
return node;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* count number of nodes in common betwee @to and @from
|
||||
* returns number of common nodes, or -errno on failure
|
||||
*/
|
||||
static int
|
||||
count_common_nodes(char *to, char *from)
|
||||
{
|
||||
int err, common;
|
||||
char *to_node, *from_node;
|
||||
|
||||
if (!to || !from)
|
||||
return -EINVAL;
|
||||
|
||||
err = 0;
|
||||
common = 0;
|
||||
to_node = NULL;
|
||||
from_node = NULL;
|
||||
|
||||
do {
|
||||
to_node = next_node(&to, &err);
|
||||
if (err || !to_node)
|
||||
break;
|
||||
|
||||
from_node = next_node(&from, &err);
|
||||
if (err || !from_node)
|
||||
break;
|
||||
|
||||
if (strncmp(to_node, from_node, MAX_NAME_LEN))
|
||||
break;
|
||||
|
||||
++to;
|
||||
++from;
|
||||
++common;
|
||||
sfree(to_node);
|
||||
sfree(from_node);
|
||||
|
||||
} while (1);
|
||||
|
||||
sfree(to_node);
|
||||
sfree(from_node);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return common;
|
||||
}
|
||||
|
||||
/*
|
||||
* construct path of @count '../', './' if @count is zero, or NULL on error
|
||||
* result should be freed
|
||||
*/
|
||||
static char *
|
||||
up_nodes(int count)
|
||||
{
|
||||
char *path, *tmp;
|
||||
int i, ret, len, size;
|
||||
|
||||
if (!count)
|
||||
return strdup("./");
|
||||
|
||||
len = strlen("../");
|
||||
size = len * count;
|
||||
if (size >= MAX_NAME_LEN)
|
||||
return NULL;
|
||||
|
||||
path = malloc(size + 1);
|
||||
if (!path)
|
||||
return NULL;
|
||||
|
||||
tmp = path;
|
||||
for (i = 0; i < count; i++) {
|
||||
ret = sprintf(tmp, "../");
|
||||
if (ret < 0 || ret != len) {
|
||||
free(path);
|
||||
return NULL;
|
||||
}
|
||||
tmp += ret;
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
/*
|
||||
* return pointer to @offset'th node of path or NULL on error
|
||||
*/
|
||||
static char *
|
||||
node_offset(char *from, int offset)
|
||||
{
|
||||
char *path;
|
||||
|
||||
if (!from || !offset)
|
||||
return NULL;
|
||||
|
||||
for (path = from; *path != '\0'; path++) {
|
||||
if (*path == DELIMITER)
|
||||
if (--offset == 0)
|
||||
return path + 1;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* return a relative path from @from to @to
|
||||
* result should be freed
|
||||
*/
|
||||
LIBVHD_API
|
||||
char *
|
||||
relative_path_to(char *from, char *to, int *err)
|
||||
{
|
||||
int from_nodes, common;
|
||||
char *to_absolute, *from_absolute;
|
||||
char *up, *common_target_path, *relative_path;
|
||||
|
||||
*err = 0;
|
||||
up = NULL;
|
||||
to_absolute = NULL;
|
||||
from_absolute = NULL;
|
||||
relative_path = NULL;
|
||||
|
||||
if (strnlen(to, MAX_NAME_LEN) == MAX_NAME_LEN ||
|
||||
strnlen(from, MAX_NAME_LEN) == MAX_NAME_LEN) {
|
||||
EPRINTF((FN,"invalid input; max path length is %d\n",
|
||||
MAX_NAME_LEN));
|
||||
*err = -ENAMETOOLONG;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
to_absolute = realpath(to, NULL);
|
||||
if (!to_absolute) {
|
||||
EPRINTF((FN,"failed to get absolute path of %s\n", to));
|
||||
*err = -errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
from_absolute = realpath(from, NULL);
|
||||
if (!from_absolute) {
|
||||
EPRINTF((FN,"failed to get absolute path of %s\n", from));
|
||||
*err = -errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (strnlen(to_absolute, MAX_NAME_LEN) == MAX_NAME_LEN ||
|
||||
strnlen(from_absolute, MAX_NAME_LEN) == MAX_NAME_LEN) {
|
||||
EPRINTF((FN,"invalid input; max path length is %d\n",
|
||||
MAX_NAME_LEN));
|
||||
*err = -ENAMETOOLONG;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* count nodes in source path */
|
||||
from_nodes = count_nodes(from_absolute);
|
||||
|
||||
/* count nodes in common */
|
||||
common = count_common_nodes(to_absolute + 1, from_absolute + 1);
|
||||
if (common < 0) {
|
||||
EPRINTF((FN,"failed to count common nodes of %s and %s: %d\n",
|
||||
to_absolute, from_absolute, common));
|
||||
*err = common;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* move up to common node */
|
||||
up = up_nodes(from_nodes - common - 1);
|
||||
if (!up) {
|
||||
EPRINTF((FN,"failed to allocate relative path for %s: %d\n",
|
||||
from_absolute, -ENOMEM));
|
||||
*err = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* get path from common node to target */
|
||||
common_target_path = node_offset(to_absolute, common + 1);
|
||||
if (!common_target_path) {
|
||||
EPRINTF((FN,"failed to find common target path to %s: %d\n",
|
||||
to_absolute, -EINVAL));
|
||||
*err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* get relative path */
|
||||
if (asprintf(&relative_path, "%s%s", up, common_target_path) == -1) {
|
||||
EPRINTF((FN,"failed to construct final path %s%s: %d\n",
|
||||
up, common_target_path, -ENOMEM));
|
||||
relative_path = NULL;
|
||||
*err = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
sfree(up);
|
||||
sfree(to_absolute);
|
||||
sfree(from_absolute);
|
||||
|
||||
return relative_path;
|
||||
}
|
||||
static void rpath_log_error( const char *func, const char *fmt, ... )
|
||||
{
|
||||
char *buf, nilbuf;
|
||||
size_t ilen, len;
|
||||
va_list ap;
|
||||
|
||||
ilen = sizeof( "tap-err:%s: " ) + strlen( func ) -2;
|
||||
va_start(ap, fmt );
|
||||
len = vsnprintf( &nilbuf, 1, fmt, ap );
|
||||
va_end( ap );
|
||||
|
||||
if( (buf = malloc( ilen + len + 1 )) == NULL ) {
|
||||
#if LIBVHD_HAS_SYSLOG
|
||||
syslog( LOG_INFO, "tap-err:%s: Out of memory", func );
|
||||
#else
|
||||
fprintf( stderr, "tap-err%s: Out of memory for %s\n", func, fmt );
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
va_start(ap, fmt);
|
||||
(void) snprintf( buf, ilen, "tap-err:%s: ", func );
|
||||
(void) vsnprintf( buf + ilen -1, len+1, fmt, ap );
|
||||
va_end( ap );
|
||||
len += ilen -1;
|
||||
if( buf[ len -1 ] != '\n' )
|
||||
buf[len++] = '\n';
|
||||
buf[len] = '\0';
|
||||
#if LIBVHD_HAS_SYSLOG
|
||||
syslog(LOG_INFO, buf);
|
||||
#else
|
||||
fputs( buf, stderr );
|
||||
#endif
|
||||
free( buf );
|
||||
|
||||
return;
|
||||
}
|
||||
33
extracters/vhd-util/COPYING
Normal file
33
extracters/vhd-util/COPYING
Normal file
@@ -0,0 +1,33 @@
|
||||
* Copyright (c) 2008, XenSource Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of XenSource Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
The Windows version uses a stripped version of the GNU C library's getopt,
|
||||
and hence is covered by the GPL.
|
||||
|
||||
The modifications made by Timothe Litt are Copyright (C) 2016 by Timothe Litt.
|
||||
They may be used under the same terms as the XenSource license above (substituting "Timothe Litt" for "Xensource Inc" as appropriate.
|
||||
|
||||
31
extracters/vhd-util/INSTALL
Normal file
31
extracters/vhd-util/INSTALL
Normal file
@@ -0,0 +1,31 @@
|
||||
This is a port of the Xen vhd-util tool and the libvhd library to windows.
|
||||
|
||||
It still works (with minor enhancements) on Unix.
|
||||
|
||||
The distribution kit includes prebuilt executables for Linux and Windows.
|
||||
|
||||
There are two components:
|
||||
libvhd - library for VHD file access
|
||||
vhd-util - tool for managing VHD files.
|
||||
|
||||
Each has a directory, which should be at the same level.
|
||||
|
||||
On Unix:
|
||||
cd vhd-util && make && make install
|
||||
|
||||
cd vhd-util && make PREFIX=/usr && make PREFIX=/usr
|
||||
To place somewhere else.
|
||||
|
||||
This creates a sharable library (libvhd) and the vhd-util command.
|
||||
|
||||
On Windows:
|
||||
Builds under microsoft Visual Studio (2015), free edition.
|
||||
|
||||
Open libvhd/libvhd.sln and build it.
|
||||
|
||||
On Windows, a DLL is NOT created as the API doesn't support it.
|
||||
(The DLL allocates memory that the client must free, but doesn't
|
||||
provide routines to do this. On windows, the pools are different.)
|
||||
|
||||
Licensing is described in COPYING.
|
||||
|
||||
115
extracters/vhd-util/Makefile
Normal file
115
extracters/vhd-util/Makefile
Normal file
@@ -0,0 +1,115 @@
|
||||
# -*- Makefile -*-
|
||||
|
||||
# Builds vhd-util and the libvhd shared library.
|
||||
|
||||
PREFIX = /usr/local
|
||||
LIBDIR = $(PREFIX)/lib
|
||||
BINDIR = $(PREFIX)/bin
|
||||
|
||||
CPPFLAGS = -D_GNU_SOURCE -I include -I $(LIBVHD)/include
|
||||
CFLAGS = -O4
|
||||
LDFLAGS = -L. -L $(LIBVHD)
|
||||
LDLIBS = -lvhd-util -luuid -lvhd
|
||||
|
||||
LDCONFIG_D = /etc/ld.so.conf.d/vhd-util
|
||||
|
||||
LIBVHD = ../libvhd
|
||||
|
||||
SRCS = atomicio.c \
|
||||
libvhd-journal.c \
|
||||
vhd-util-check.c \
|
||||
vhd-util-coalesce.c \
|
||||
vhd-util-create.c \
|
||||
vhd-util-fill.c \
|
||||
lvm-util.c \
|
||||
vhd-util-modify.c \
|
||||
vhd-util-query.c \
|
||||
vhd-util-read.c \
|
||||
vhd-util-repair.c \
|
||||
vhd-util-resize.c \
|
||||
vhd-util-revert.c \
|
||||
vhd-util-scan.c \
|
||||
vhd-util-set-field.c \
|
||||
vhd-util-snapshot.c
|
||||
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
|
||||
LIBVHDSO = libvhd.so
|
||||
LIBVHDSONAME = $(LIBVHDSO).2
|
||||
LIBVHDSOFILE = $(LIBVHDSONAME).1.0
|
||||
|
||||
all: vhd-util $(LIBVHD)/$(LIBVHDSO)
|
||||
|
||||
# The utility
|
||||
|
||||
libvhd-util.a : $(OBJS)
|
||||
$(AR) -rs libvhd-util.a $(OBJS)
|
||||
|
||||
vhd-util : vhd-util.o libvhd-util.a $(LIBVHD)/$(LIBVHDSO)
|
||||
$(CC) $(LDFLAGS) -Wl,-rpath,$(LIBDIR) -o vhd-util vhd-util.o $(LDLIBS)
|
||||
|
||||
# The sharable library
|
||||
|
||||
$(LIBVHD)/$(LIBVHDSOFILE) : $(LIBVHD)/libvhd.c $(LIBVHD)/relative-path.c
|
||||
$(CC) -shared -o $(LIBVHD)/$(LIBVHDSOFILE) -Wl,-soname,$(LIBVHDSONAME) $(CPPFLAGS) $(CFLAGS) -fPIC $(LIBVHD)/libvhd.c $(LIBVHD)/relative-path.c -luuid
|
||||
|
||||
# The symlinks in the local directory necessary for linking
|
||||
|
||||
$(LIBVHD)/$(LIBVHDSO) : $(LIBVHD)/$(LIBVHDSOFILE)
|
||||
ldconfig -n $(LIBVHD)
|
||||
ln -sf $(LIBVHD)/$(LIBVHDSOFILE) $(LIBVHD)/$(LIBVHDSO)
|
||||
|
||||
# Install (note that to run the utility before installation, you must set
|
||||
# LD_LOAD_LIBRARY to $(VLDLIB)
|
||||
|
||||
install: all
|
||||
cp -p $(LIBVHD)/$(LIBVHDSOFILE) $(LIBDIR)/
|
||||
cp -p vhd-util $(BINDIR)/
|
||||
echo "$(LIBDIR)" >$(LDCONFIG_D)
|
||||
ldconfig
|
||||
ln -sf $(LIBVHDSONAME) $(LIBDIR)/$(LIBVHDSO)
|
||||
|
||||
# Un-install
|
||||
|
||||
uninstall:
|
||||
rm -f $(BINDIR)/vhd-util $(LIBDIR)/$(LIBVHDSOFILE) $(LIBDIR)/$(LIBVHDSONAME) $(LIBDIR)/$(LIBVHDSO)
|
||||
ldconfig
|
||||
rm -f $(LDCONFIG_D)
|
||||
|
||||
# Clean working area
|
||||
|
||||
clean: tidy
|
||||
rm -f vhd-util vhd-util.exe $(LIBVHD)/$(LIBVHDSOFILE) $(LIBVHD)/$(LIBVHDSONAME) $(LIBVHD)/$(LIBVHDSO)
|
||||
|
||||
# Clean intermediate files only, leaving outputs
|
||||
|
||||
tidy:
|
||||
rm -f $(OBJS) libvhd-util.a vhd-util.o
|
||||
|
||||
KITFILES = \
|
||||
vhd-util/README \
|
||||
vhd-util/INSTALL \
|
||||
vhd-util/COPYING \
|
||||
vhd-util/*.c \
|
||||
vhd-util/include/*.h \
|
||||
vhd-util/vhd-util \
|
||||
vhd-util/vhd-util.exe \
|
||||
vhd-util/Makefile \
|
||||
vhd-util/vhd-util.vcxproj \
|
||||
vhd-util/vhd-util.vcxproj.filters \
|
||||
\
|
||||
libvhd/*.c \
|
||||
libvhd/libvhd.so* \
|
||||
libvhd/libvhd.sln \
|
||||
libvhd/libvhd.vcxproj \
|
||||
libvhd/libvhd.vcxproj.filters \
|
||||
libvhd/include/*.h \
|
||||
|
||||
KITEXES = \
|
||||
vhd-util/vhd-util \
|
||||
vhd-util/vhd-util.exe \
|
||||
libvhd/libvhd.so*
|
||||
|
||||
kit: all
|
||||
cd .. && chown -h $(USER).$(USER) $(KITFILES) && chmod -x $(KITFILES) && chmod +x $(KITEXES) && tar -czf vhd-tools.tgz $(KITFILES)
|
||||
|
||||
229
extracters/vhd-util/README
Normal file
229
extracters/vhd-util/README
Normal file
@@ -0,0 +1,229 @@
|
||||
vhd-util is originally an unsupported tool provided with the Xen emulator
|
||||
family. It was not designed as a user tool, but it does have some
|
||||
functions that can be used without internals knowledge.
|
||||
|
||||
It is a "sharp" tool - you can do irreversible damage with it.
|
||||
Use at your own risk.
|
||||
|
||||
This version has been modified to:
|
||||
|
||||
o Work on Windows as well as Unix
|
||||
o Resolve a number of compiler-detected issues
|
||||
o Identify the creator OS
|
||||
o Fix some bugs.
|
||||
o The 'scan' command, which operates on LVM volumes, was
|
||||
not ported to Windows. All other commands (should) work.
|
||||
o An error message is generated when a command fails.
|
||||
o Some safeguards have been added to the 'modify' command.
|
||||
o read -P summarizes file and its parents.
|
||||
|
||||
The tool is undocumentd by Xen, except for a few cryptic comments
|
||||
in the README that assume the Xen environment.
|
||||
|
||||
The following should be more useful as a stand-alone tool.
|
||||
|
||||
This document is the result of reverse-engineering the vhd-util code,
|
||||
and may contain errors. As with the tool, use with caution and at
|
||||
your own risk.
|
||||
|
||||
vhd-util is a command-line utility with the following general syntax:
|
||||
|
||||
vhd-util COMMAND OPTIONS
|
||||
|
||||
Most commands produce a cryptic usage with the -h option.
|
||||
The target of a command is specified with the (required) -n "option".
|
||||
|
||||
Commands tend to fail when they don't make sense - e.g. asking about
|
||||
difference disk data structures on a fixed-size disk.
|
||||
|
||||
Some terminology:
|
||||
Sector - Address on virtual disk. Always 512 bytes.
|
||||
Block - Allocation unit in sparse disks. Default 4096 sectors
|
||||
(2 MB).
|
||||
Fixed disk - Virtual disk of fixed size = maximum size + small header.
|
||||
Dynamic disk - (Sparse disk) Virtual disk that grows as data is
|
||||
written. Simulator sees it as fixed (max) size.
|
||||
Diff disk - (Snapshot) Dynamic disk that contains (only) changes
|
||||
to a parent Dynamic (or Diff) disk. Used for
|
||||
backups, or to experiment with easy rollback.
|
||||
BAT - "Block allocation table": map of virtual blocks to
|
||||
physical sectors in a dynamic/diff disk.
|
||||
Bitmap - Bits associated with each Block indicating which
|
||||
sectors within the block have been written.
|
||||
|
||||
vhd-util create
|
||||
Create a new disk image file.
|
||||
|
||||
-n filename File to create
|
||||
-s size Specify file size (MB)
|
||||
-r Create a fixed size image file (default is sparse)
|
||||
|
||||
vhd-util snapshot
|
||||
Create a new snapshot (difference image) of a sparse file.
|
||||
Any subsequent modification to the parent file invalidates
|
||||
the snapshot. The parent filename is stored in the snapshot.
|
||||
Snapshots can be chained to arbitrary depth, at perfomance cost.
|
||||
|
||||
-n filename File to create
|
||||
-p filename Filename of parent disk
|
||||
-l limit Maximum depth of snapshot chain
|
||||
-m Parent disk is raw (physical). Not supported on windows.
|
||||
|
||||
vhd-util check
|
||||
Check metadata of VHD file for consistency and reports any errors
|
||||
detected.
|
||||
|
||||
-n filename File to check
|
||||
-p Check parents as well
|
||||
-i Ignore missing primary footer (repair can fix)
|
||||
|
||||
vhd-util read
|
||||
Read and format the metadata of a sparse (dynamic) disk.
|
||||
|
||||
-n filename File to query
|
||||
-p Print formatted header and footer.
|
||||
-P Print formatted summary of file and its parents
|
||||
|
||||
The following options are used for debugging.
|
||||
|
||||
-t sector# Translate logical sector to VHD location
|
||||
-b block# Print BAT directory for block
|
||||
-m block# Print BINARY bitmap. (Pipe to a hex editor or file)
|
||||
-i sec# Print block/sector address and written status
|
||||
-a Print BINARY BAT map entries
|
||||
-j block# Print allocation status of block
|
||||
-d block# Print BINARY content of block data
|
||||
-c # Repeat command # times for consecutivie blocks/sectors.
|
||||
-r sector# Print BINARY content of sector(s)
|
||||
-x Print (some) values in hex.
|
||||
|
||||
vhd-util query
|
||||
Print key fields from the metadata. Mostly unlabeled, suitable for
|
||||
consumption by a script.
|
||||
|
||||
-n filename File to query
|
||||
-v Print virtual size (MB)
|
||||
-p Print filename of parent
|
||||
-s Print physical size (bytes) Includes metadata.
|
||||
-f Print Xen's "hidden" state field. (Non-standard)
|
||||
-d Print chain depth (# files from -n to ultimate parent)
|
||||
|
||||
vhd-util coalesce
|
||||
Merges a snapshot (differencing) disk into its parent.
|
||||
|
||||
-n filename File to merge (parent is found automagically)
|
||||
|
||||
vhd-util repair
|
||||
Attempt to repair a damaged volume.
|
||||
Copies redundant copy of metadata to correct place at the
|
||||
end of the file. N.B. OS level data may still be corrupt...
|
||||
|
||||
-n filename File to repair
|
||||
|
||||
vhd-util resize
|
||||
Change the size of an image file. Can expand, or if
|
||||
unwritten space at end, shrink. N.B. Does NOT tell the
|
||||
OS filesystem, nor respect it. Restricted to files created
|
||||
by Xen (including vhd-util).
|
||||
|
||||
Shrink currently aborts with "partially implemented" for
|
||||
dynamic disks...
|
||||
|
||||
-n filename File to resize
|
||||
-j filename Journal file (Must not exist,deleted at end.)
|
||||
-s size (MB) New size
|
||||
|
||||
vhd-util fill
|
||||
Reads and rewrites (with the same data) every block of the disk.
|
||||
Effect is to allocate zero blocks for every page of a dynamic
|
||||
(sparse) disk.
|
||||
|
||||
-n filename File to process
|
||||
|
||||
vhd-util modify
|
||||
Modify file metadata
|
||||
|
||||
-n filename File to modify
|
||||
-P filename (Extension) change parent only after verifying
|
||||
that the UUID of the parent matches the old one.
|
||||
Safer alternative for case where parent has been
|
||||
renamed or moved.
|
||||
|
||||
The following **dangerous** options are used for debugging.
|
||||
|
||||
-p filename Change parent to this file. Actually changing
|
||||
to a different file will corrupt data. Think
|
||||
at least three times before using!
|
||||
-s byteaddress Move the file footer. Can be used for changing
|
||||
physical size of file, but it's tricky. Xen "
|
||||
Change the size of the file containing the VHD
|
||||
image. This does NOT affect the VHD disk capacity,
|
||||
only the physical size of the file containing
|
||||
the VHD. Naturally, it is not possible to set the
|
||||
file size to be less than what the VHD utilizes.
|
||||
The operation doesn't actually change the file
|
||||
size, but it writes the footer in the right
|
||||
location such that resizing the file (manually, as
|
||||
a separate step) will produce the correct results.
|
||||
|
||||
If the new file size is greater than the current
|
||||
file size, the file must first be expanded and
|
||||
then altered with this operation.
|
||||
|
||||
If the new size is smaller than the current size,
|
||||
the VHD must first be altered with this operation
|
||||
and then the file must be shrunk.
|
||||
|
||||
Failing to resize the file will result in a
|
||||
corrupted VHD."
|
||||
-P is an extension to the Xen tool.
|
||||
For protection against typos, -p must be specified twice.
|
||||
|
||||
vhd-util revert
|
||||
Applies a journal file to recover from a failed operation.
|
||||
Resize can fail with VHD in an inconsistent state; the journal file
|
||||
records the changes made so that they can (hopefully) be reversed.
|
||||
|
||||
A VHD file in this state has a special 'poisoned' cookie to prevent
|
||||
it from being accessed normally.
|
||||
|
||||
-n filename The file to be recovered
|
||||
-j filename The journal file (specified with -j on the resize)
|
||||
|
||||
vhd-util set
|
||||
Set the (Xen-specifix) hidden flag.
|
||||
|
||||
-n filename File to modify
|
||||
-f hidden Only "hidden" supported.
|
||||
-v value Decimal value for field.
|
||||
|
||||
vhd-util scan
|
||||
Scan LVM volumes for VHD files and report capacity, size and parent.
|
||||
Unix only.
|
||||
|
||||
-m filter Select files to consider (match name)
|
||||
-f Do a 'fast' scan
|
||||
-c Continue on errors
|
||||
-l volume Scan LVM volume
|
||||
-p Pretty-print results
|
||||
-a Scan parents
|
||||
-v Verbose
|
||||
|
||||
For example, to create a sparse image -
|
||||
vhd-util create -n MyVHDFile -s 1024
|
||||
|
||||
This creates a sparse 1GB file named "MyVHDFile" that can be mounted
|
||||
and populated with data.
|
||||
|
||||
One can also base the image on an existing file -
|
||||
vhd-util snapshot -n MyVHDFile -p SomeFile
|
||||
|
||||
This creates a sparse VHD file named "MyVHDFile" using "SomeFile"
|
||||
as a parent image. Copy-on-write semantics ensure that writes will be
|
||||
stored in "MyVHDFile" while reads will be directed to the most
|
||||
recently written version of the data, either in "MyVHDFile" or
|
||||
"SomeFile" as is appropriate.
|
||||
|
||||
This document is Copyright (C) 2016 Timothe Litt.
|
||||
|
||||
See the COPYING file for license.
|
||||
62
extracters/vhd-util/atomicio.c
Normal file
62
extracters/vhd-util/atomicio.c
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2005 Anil Madhavapeddy. All rights reserved.
|
||||
* Copyright (c) 1995,1999 Theo de Raadt. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include "atomicio.h"
|
||||
|
||||
/*
|
||||
* ensure all of data on socket comes through. f==read || f==vwrite
|
||||
*/
|
||||
size_t
|
||||
atomicio(f, fd, _s, n)
|
||||
ssize_t (*f) (int, void *, size_t);
|
||||
int fd;
|
||||
void *_s;
|
||||
size_t n;
|
||||
{
|
||||
char *s = _s;
|
||||
size_t pos = 0;
|
||||
ssize_t res;
|
||||
|
||||
while (n > pos) {
|
||||
res = (f) (fd, s + pos, n - pos);
|
||||
switch (res) {
|
||||
case -1:
|
||||
if (errno == EINTR || errno == EAGAIN)
|
||||
continue;
|
||||
return 0;
|
||||
case 0:
|
||||
errno = EPIPE;
|
||||
return pos;
|
||||
default:
|
||||
pos += (size_t)res;
|
||||
}
|
||||
}
|
||||
return (pos);
|
||||
}
|
||||
|
||||
506
extracters/vhd-util/gnugetopt.c
Normal file
506
extracters/vhd-util/gnugetopt.c
Normal file
@@ -0,0 +1,506 @@
|
||||
/* This is GNU's getopt.c */
|
||||
|
||||
char *optarg;
|
||||
|
||||
int optind = 1;
|
||||
|
||||
int __getopt_initialized;
|
||||
|
||||
static char *nextchar;
|
||||
|
||||
int opterr = 1;
|
||||
|
||||
int optopt = '?';
|
||||
|
||||
static enum
|
||||
{
|
||||
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
|
||||
} ordering;
|
||||
|
||||
static char *posixly_correct = 0;
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define _(x) x
|
||||
|
||||
static char *
|
||||
my_index (str, chr)
|
||||
const char *str;
|
||||
int chr;
|
||||
{
|
||||
while (*str)
|
||||
{
|
||||
if (*str == chr)
|
||||
return (char *) str;
|
||||
str++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int first_nonopt;
|
||||
static int last_nonopt;
|
||||
|
||||
# define SWAP_FLAGS(ch1, ch2)
|
||||
|
||||
#if defined __STDC__ && __STDC__
|
||||
static void exchange (char **);
|
||||
#endif
|
||||
|
||||
static void
|
||||
exchange (argv)
|
||||
char **argv;
|
||||
{
|
||||
int bottom = first_nonopt;
|
||||
int middle = last_nonopt;
|
||||
int top = optind;
|
||||
char *tem;
|
||||
|
||||
while (top > middle && middle > bottom)
|
||||
{
|
||||
if (top - middle > middle - bottom)
|
||||
{
|
||||
int len = middle - bottom;
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
tem = argv[bottom + i];
|
||||
argv[bottom + i] = argv[top - (middle - bottom) + i];
|
||||
argv[top - (middle - bottom) + i] = tem;
|
||||
SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
|
||||
}
|
||||
top -= len;
|
||||
}
|
||||
else
|
||||
{
|
||||
int len = top - middle;
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
tem = argv[bottom + i];
|
||||
argv[bottom + i] = argv[middle + i];
|
||||
argv[middle + i] = tem;
|
||||
SWAP_FLAGS (bottom + i, middle + i);
|
||||
}
|
||||
bottom += len;
|
||||
}
|
||||
}
|
||||
|
||||
first_nonopt += (optind - last_nonopt);
|
||||
last_nonopt = optind;
|
||||
}
|
||||
|
||||
#if defined __STDC__ && __STDC__
|
||||
static const char *_getopt_initialize (int, char *const *, const char *);
|
||||
#endif
|
||||
static const char *
|
||||
_getopt_initialize (argc, argv, optstring)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *optstring;
|
||||
{
|
||||
first_nonopt = last_nonopt = optind;
|
||||
|
||||
nextchar = NULL;
|
||||
|
||||
if (optstring[0] == '-')
|
||||
{
|
||||
ordering = RETURN_IN_ORDER;
|
||||
++optstring;
|
||||
}
|
||||
else if (optstring[0] == '+')
|
||||
{
|
||||
ordering = REQUIRE_ORDER;
|
||||
++optstring;
|
||||
}
|
||||
else if (posixly_correct != NULL)
|
||||
ordering = REQUIRE_ORDER;
|
||||
else
|
||||
ordering = PERMUTE;
|
||||
|
||||
return optstring;
|
||||
}
|
||||
|
||||
int
|
||||
_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *optstring;
|
||||
const struct option *longopts;
|
||||
int *longind;
|
||||
int long_only;
|
||||
{
|
||||
int print_errors = opterr;
|
||||
if (optstring[0] == ':')
|
||||
print_errors = 0;
|
||||
|
||||
optarg = NULL;
|
||||
|
||||
if (optind == 0 || !__getopt_initialized)
|
||||
{
|
||||
if (optind == 0)
|
||||
optind = 1; /* Don't scan ARGV[0], the program name. */
|
||||
optstring = _getopt_initialize (argc, argv, optstring);
|
||||
__getopt_initialized = 1;
|
||||
}
|
||||
|
||||
# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
|
||||
|
||||
if (nextchar == NULL || *nextchar == '\0')
|
||||
{
|
||||
if (last_nonopt > optind)
|
||||
last_nonopt = optind;
|
||||
if (first_nonopt > optind)
|
||||
first_nonopt = optind;
|
||||
|
||||
if (ordering == PERMUTE)
|
||||
{
|
||||
if (first_nonopt != last_nonopt && last_nonopt != optind)
|
||||
exchange ((char **) argv);
|
||||
else if (last_nonopt != optind)
|
||||
first_nonopt = optind;
|
||||
|
||||
while (optind < argc && NONOPTION_P)
|
||||
optind++;
|
||||
last_nonopt = optind;
|
||||
}
|
||||
|
||||
|
||||
if (optind != argc && !strcmp (argv[optind], "--"))
|
||||
{
|
||||
optind++;
|
||||
|
||||
if (first_nonopt != last_nonopt && last_nonopt != optind)
|
||||
exchange ((char **) argv);
|
||||
else if (first_nonopt == last_nonopt)
|
||||
first_nonopt = optind;
|
||||
last_nonopt = argc;
|
||||
|
||||
optind = argc;
|
||||
}
|
||||
|
||||
if (optind == argc)
|
||||
{
|
||||
if (first_nonopt != last_nonopt)
|
||||
optind = first_nonopt;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NONOPTION_P)
|
||||
{
|
||||
if (ordering == REQUIRE_ORDER)
|
||||
return -1;
|
||||
optarg = argv[optind++];
|
||||
return 1;
|
||||
}
|
||||
|
||||
nextchar = (argv[optind] + 1
|
||||
+ (longopts != NULL && argv[optind][1] == '-'));
|
||||
}
|
||||
|
||||
|
||||
if (longopts != NULL
|
||||
&& (argv[optind][1] == '-'
|
||||
|| (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
|
||||
{
|
||||
char *nameend;
|
||||
const struct option *p;
|
||||
const struct option *pfound = NULL;
|
||||
int exact = 0;
|
||||
int ambig = 0;
|
||||
int indfound = -1;
|
||||
int option_index;
|
||||
|
||||
for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
|
||||
/* Do nothing. */ ;
|
||||
|
||||
for (p = longopts, option_index = 0; p->name; p++, option_index++)
|
||||
if (!strncmp (p->name, nextchar, nameend - nextchar))
|
||||
{
|
||||
if ((unsigned int) (nameend - nextchar)
|
||||
== (unsigned int) strlen (p->name))
|
||||
{
|
||||
pfound = p;
|
||||
indfound = option_index;
|
||||
exact = 1;
|
||||
break;
|
||||
}
|
||||
else if (pfound == NULL)
|
||||
{
|
||||
pfound = p;
|
||||
indfound = option_index;
|
||||
}
|
||||
else
|
||||
ambig = 1;
|
||||
}
|
||||
|
||||
if (ambig && !exact)
|
||||
{
|
||||
if (print_errors)
|
||||
fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
|
||||
argv[0], argv[optind]);
|
||||
nextchar += strlen (nextchar);
|
||||
optind++;
|
||||
optopt = 0;
|
||||
return '?';
|
||||
}
|
||||
|
||||
if (pfound != NULL)
|
||||
{
|
||||
option_index = indfound;
|
||||
optind++;
|
||||
if (*nameend)
|
||||
{
|
||||
if (pfound->has_arg)
|
||||
optarg = nameend + 1;
|
||||
else
|
||||
{
|
||||
if (print_errors)
|
||||
{
|
||||
if (argv[optind - 1][1] == '-')
|
||||
fprintf (stderr,
|
||||
_("%s: option `--%s' doesn't allow an argument\n"),
|
||||
argv[0], pfound->name);
|
||||
else
|
||||
fprintf (stderr,
|
||||
_("%s: option `%c%s' doesn't allow an argument\n"),
|
||||
argv[0], argv[optind - 1][0], pfound->name);
|
||||
}
|
||||
|
||||
nextchar += strlen (nextchar);
|
||||
|
||||
optopt = pfound->val;
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
else if (pfound->has_arg == 1)
|
||||
{
|
||||
if (optind < argc)
|
||||
optarg = argv[optind++];
|
||||
else
|
||||
{
|
||||
if (print_errors)
|
||||
fprintf (stderr,
|
||||
_("%s: option `%s' requires an argument\n"),
|
||||
argv[0], argv[optind - 1]);
|
||||
nextchar += strlen (nextchar);
|
||||
optopt = pfound->val;
|
||||
return optstring[0] == ':' ? ':' : '?';
|
||||
}
|
||||
}
|
||||
nextchar += strlen (nextchar);
|
||||
if (longind != NULL)
|
||||
*longind = option_index;
|
||||
if (pfound->flag)
|
||||
{
|
||||
*(pfound->flag) = pfound->val;
|
||||
return 0;
|
||||
}
|
||||
return pfound->val;
|
||||
}
|
||||
|
||||
if (!long_only || argv[optind][1] == '-'
|
||||
|| my_index (optstring, *nextchar) == NULL)
|
||||
{
|
||||
if (print_errors)
|
||||
{
|
||||
if (argv[optind][1] == '-')
|
||||
fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
|
||||
argv[0], nextchar);
|
||||
else
|
||||
/* +option or -option */
|
||||
fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
|
||||
argv[0], argv[optind][0], nextchar);
|
||||
}
|
||||
nextchar = (char *) "";
|
||||
optind++;
|
||||
optopt = 0;
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
{
|
||||
char c = *nextchar++;
|
||||
char *temp = my_index (optstring, c);
|
||||
|
||||
if (*nextchar == '\0')
|
||||
++optind;
|
||||
|
||||
if (temp == NULL || c == ':')
|
||||
{
|
||||
if (print_errors)
|
||||
{
|
||||
if (posixly_correct)
|
||||
fprintf (stderr, _("%s: illegal option -- %c\n"),
|
||||
argv[0], c);
|
||||
else
|
||||
fprintf (stderr, _("%s: invalid option -- %c\n"),
|
||||
argv[0], c);
|
||||
}
|
||||
optopt = c;
|
||||
return '?';
|
||||
}
|
||||
if (temp[0] == 'W' && temp[1] == ';')
|
||||
{
|
||||
char *nameend;
|
||||
const struct option *p;
|
||||
const struct option *pfound = NULL;
|
||||
int exact = 0;
|
||||
int ambig = 0;
|
||||
int indfound = 0;
|
||||
int option_index;
|
||||
|
||||
if (*nextchar != '\0')
|
||||
{
|
||||
optarg = nextchar;
|
||||
optind++;
|
||||
}
|
||||
else if (optind == argc)
|
||||
{
|
||||
if (print_errors)
|
||||
{
|
||||
fprintf (stderr, _("%s: option requires an argument -- %c\n"),
|
||||
argv[0], c);
|
||||
}
|
||||
optopt = c;
|
||||
if (optstring[0] == ':')
|
||||
c = ':';
|
||||
else
|
||||
c = '?';
|
||||
return c;
|
||||
}
|
||||
else
|
||||
optarg = argv[optind++];
|
||||
|
||||
for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
|
||||
/* Do nothing. */ ;
|
||||
|
||||
for (p = longopts, option_index = 0; p->name; p++, option_index++)
|
||||
if (!strncmp (p->name, nextchar, nameend - nextchar))
|
||||
{
|
||||
if ((unsigned int) (nameend - nextchar) == strlen (p->name))
|
||||
{
|
||||
pfound = p;
|
||||
indfound = option_index;
|
||||
exact = 1;
|
||||
break;
|
||||
}
|
||||
else if (pfound == NULL)
|
||||
{
|
||||
pfound = p;
|
||||
indfound = option_index;
|
||||
}
|
||||
else
|
||||
ambig = 1;
|
||||
}
|
||||
if (ambig && !exact)
|
||||
{
|
||||
if (print_errors)
|
||||
fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
|
||||
argv[0], argv[optind]);
|
||||
nextchar += strlen (nextchar);
|
||||
optind++;
|
||||
return '?';
|
||||
}
|
||||
if (pfound != NULL)
|
||||
{
|
||||
option_index = indfound;
|
||||
if (*nameend)
|
||||
{
|
||||
if (pfound->has_arg)
|
||||
optarg = nameend + 1;
|
||||
else
|
||||
{
|
||||
if (print_errors)
|
||||
fprintf (stderr, _("\
|
||||
%s: option `-W %s' doesn't allow an argument\n"),
|
||||
argv[0], pfound->name);
|
||||
|
||||
nextchar += strlen (nextchar);
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
else if (pfound->has_arg == 1)
|
||||
{
|
||||
if (optind < argc)
|
||||
optarg = argv[optind++];
|
||||
else
|
||||
{
|
||||
if (print_errors)
|
||||
fprintf (stderr,
|
||||
_("%s: option `%s' requires an argument\n"),
|
||||
argv[0], argv[optind - 1]);
|
||||
nextchar += strlen (nextchar);
|
||||
return optstring[0] == ':' ? ':' : '?';
|
||||
}
|
||||
}
|
||||
nextchar += strlen (nextchar);
|
||||
if (longind != NULL)
|
||||
*longind = option_index;
|
||||
if (pfound->flag)
|
||||
{
|
||||
*(pfound->flag) = pfound->val;
|
||||
return 0;
|
||||
}
|
||||
return pfound->val;
|
||||
}
|
||||
nextchar = NULL;
|
||||
return 'W'; /* Let the application handle it. */
|
||||
}
|
||||
if (temp[1] == ':')
|
||||
{
|
||||
if (temp[2] == ':')
|
||||
{
|
||||
if (*nextchar != '\0')
|
||||
{
|
||||
optarg = nextchar;
|
||||
optind++;
|
||||
}
|
||||
else
|
||||
optarg = NULL;
|
||||
nextchar = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*nextchar != '\0')
|
||||
{
|
||||
optarg = nextchar;
|
||||
optind++;
|
||||
}
|
||||
else if (optind == argc)
|
||||
{
|
||||
if (print_errors)
|
||||
{
|
||||
fprintf (stderr,
|
||||
_("%s: option requires an argument -- %c\n"),
|
||||
argv[0], c);
|
||||
}
|
||||
optopt = c;
|
||||
if (optstring[0] == ':')
|
||||
c = ':';
|
||||
else
|
||||
c = '?';
|
||||
}
|
||||
else
|
||||
optarg = argv[optind++];
|
||||
nextchar = NULL;
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
getopt (argc, argv, optstring)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *optstring;
|
||||
{
|
||||
return _getopt_internal (argc, argv, optstring,
|
||||
(const struct option *) 0,
|
||||
(int *) 0,
|
||||
0);
|
||||
}
|
||||
|
||||
33
extracters/vhd-util/include/atomicio.h
Normal file
33
extracters/vhd-util/include/atomicio.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/* $OpenBSD: atomicio.h,v 1.6 2005/05/24 17:32:43 avsm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995,1999 Theo de Raadt. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Ensure all of data on socket comes through. f==read || f==vwrite
|
||||
*/
|
||||
size_t atomicio(ssize_t (*)(int, void *, size_t), int, void *, size_t);
|
||||
|
||||
#define vwrite (ssize_t (*)(int, void *, size_t))write
|
||||
68
extracters/vhd-util/include/libvhd-journal.h
Normal file
68
extracters/vhd-util/include/libvhd-journal.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/* Copyright (c) 2008, XenSource Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of XenSource Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _VHD_JOURNAL_H_
|
||||
#define _VHD_JOURNAL_H_
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "libvhd.h"
|
||||
|
||||
#define VHD_JOURNAL_METADATA 0x01
|
||||
#define VHD_JOURNAL_DATA 0x02
|
||||
|
||||
#define VHD_JOURNAL_HEADER_COOKIE "vjournal"
|
||||
#define VHD_JOURNAL_ENTRY_COOKIE 0xaaaa12344321aaaa
|
||||
|
||||
typedef struct vhd_journal_header {
|
||||
char cookie[8];
|
||||
blk_uuid_t uuid;
|
||||
uint64_t vhd_footer_offset;
|
||||
uint32_t journal_data_entries;
|
||||
uint32_t journal_metadata_entries;
|
||||
uint64_t journal_data_offset;
|
||||
uint64_t journal_metadata_offset;
|
||||
uint64_t journal_eof;
|
||||
char pad[448];
|
||||
} vhd_journal_header_t;
|
||||
|
||||
typedef struct vhd_journal {
|
||||
char *jname;
|
||||
int jfd;
|
||||
int is_block; /* is jfd a block device */
|
||||
vhd_journal_header_t header;
|
||||
vhd_context_t vhd;
|
||||
} vhd_journal_t;
|
||||
|
||||
int vhd_journal_create(vhd_journal_t *, const char *file, const char *jfile);
|
||||
int vhd_journal_open(vhd_journal_t *, const char *file, const char *jfile);
|
||||
int vhd_journal_add_block(vhd_journal_t *, uint32_t block, char mode);
|
||||
int vhd_journal_commit(vhd_journal_t *);
|
||||
int vhd_journal_revert(vhd_journal_t *);
|
||||
int vhd_journal_close(vhd_journal_t *);
|
||||
int vhd_journal_remove(vhd_journal_t *);
|
||||
|
||||
#endif
|
||||
124
extracters/vhd-util/include/list.h
Normal file
124
extracters/vhd-util/include/list.h
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* list.h
|
||||
*
|
||||
* This is a subset of linux's list.h intended to be used in user-space.
|
||||
* XXX The namespace conflicts with NetBSD's <sys/queue.h>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __LIST_H__
|
||||
#define __LIST_H__
|
||||
|
||||
#define LIST_POISON1 ((void *) 0x00100100)
|
||||
#define LIST_POISON2 ((void *) 0x00200200)
|
||||
|
||||
struct list_head {
|
||||
struct list_head *next, *prev;
|
||||
};
|
||||
|
||||
/* XXX workaround for conflicts. The list API should use its own
|
||||
* namespace prefix, i.e. BLK_
|
||||
*/
|
||||
#ifdef LIST_HEAD_INIT
|
||||
#undef LIST_HEAD_INIT
|
||||
#endif
|
||||
#ifndef LIST_HEAD
|
||||
#undef LIST_HEAD
|
||||
#endif
|
||||
|
||||
#define LIST_HEAD_INIT(name) { &(name), &(name) }
|
||||
|
||||
#define LIST_HEAD(name) \
|
||||
struct list_head name = LIST_HEAD_INIT(name)
|
||||
|
||||
static inline void INIT_LIST_HEAD(struct list_head *list)
|
||||
{
|
||||
list->next = list;
|
||||
list->prev = list;
|
||||
}
|
||||
|
||||
static inline void __list_add(struct list_head *new,
|
||||
struct list_head *prev,
|
||||
struct list_head *next)
|
||||
{
|
||||
next->prev = new;
|
||||
new->next = next;
|
||||
new->prev = prev;
|
||||
prev->next = new;
|
||||
}
|
||||
|
||||
static inline void list_add(struct list_head *new, struct list_head *head)
|
||||
{
|
||||
__list_add(new, head, head->next);
|
||||
}
|
||||
|
||||
static inline void list_add_tail(struct list_head *new, struct list_head *head)
|
||||
{
|
||||
__list_add(new, head->prev, head);
|
||||
}
|
||||
|
||||
static inline void __list_del(struct list_head * prev, struct list_head * next)
|
||||
{
|
||||
next->prev = prev;
|
||||
prev->next = next;
|
||||
}
|
||||
|
||||
static inline void list_del(struct list_head *entry)
|
||||
{
|
||||
__list_del(entry->prev, entry->next);
|
||||
entry->next = LIST_POISON1;
|
||||
entry->prev = LIST_POISON2;
|
||||
}
|
||||
|
||||
static inline void list_del_init(struct list_head *entry)
|
||||
{
|
||||
__list_del(entry->prev, entry->next);
|
||||
INIT_LIST_HEAD(entry);
|
||||
}
|
||||
|
||||
static inline int list_empty(const struct list_head *head)
|
||||
{
|
||||
return head->next == head;
|
||||
}
|
||||
|
||||
static inline int list_is_last(const struct list_head *list,
|
||||
const struct list_head *head)
|
||||
{
|
||||
return list->next == head;
|
||||
}
|
||||
|
||||
static inline void __list_splice(struct list_head *list,
|
||||
struct list_head *head)
|
||||
{
|
||||
struct list_head *first = list->next;
|
||||
struct list_head *last = list->prev;
|
||||
struct list_head *at = head->next;
|
||||
|
||||
first->prev = head;
|
||||
head->next = first;
|
||||
|
||||
last->next = at;
|
||||
at->prev = last;
|
||||
}
|
||||
|
||||
static inline void list_splice(struct list_head *list, struct list_head *head)
|
||||
{
|
||||
if (!list_empty(list))
|
||||
__list_splice(list, head);
|
||||
}
|
||||
|
||||
#define list_entry(ptr, type, member) \
|
||||
((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
|
||||
|
||||
#define list_for_each_entry(pos, head, member) \
|
||||
for (pos = list_entry((head)->next, typeof(*pos), member); \
|
||||
&pos->member != (head); \
|
||||
pos = list_entry(pos->member.next, typeof(*pos), member))
|
||||
|
||||
#define list_for_each_entry_safe(pos, n, head, member) \
|
||||
for (pos = list_entry((head)->next, typeof(*pos), member), \
|
||||
n = list_entry(pos->member.next, typeof(*pos), member); \
|
||||
&pos->member != (head); \
|
||||
pos = n, n = list_entry(n->member.next, typeof(*n), member))
|
||||
|
||||
#endif /* __LIST_H__ */
|
||||
71
extracters/vhd-util/include/lvm-util.h
Normal file
71
extracters/vhd-util/include/lvm-util.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2008, XenSource Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of XenSource Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _LVM_UTIL_H_
|
||||
#define _LVM_UTIL_H_
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#define MAX_NAME_SIZE 256
|
||||
|
||||
#define LVM_SEG_TYPE_LINEAR 1
|
||||
#define LVM_SEG_TYPE_UNKNOWN 2
|
||||
|
||||
struct lv_segment {
|
||||
uint8_t type;
|
||||
char device[MAX_NAME_SIZE];
|
||||
uint64_t pe_start;
|
||||
uint64_t pe_size;
|
||||
};
|
||||
|
||||
struct lv {
|
||||
char name[MAX_NAME_SIZE];
|
||||
uint64_t size;
|
||||
uint32_t segments;
|
||||
struct lv_segment first_segment;
|
||||
};
|
||||
|
||||
struct pv {
|
||||
char name[MAX_NAME_SIZE];
|
||||
uint64_t start;
|
||||
};
|
||||
|
||||
struct vg {
|
||||
char name[MAX_NAME_SIZE];
|
||||
uint64_t extent_size;
|
||||
|
||||
int pv_cnt;
|
||||
struct pv *pvs;
|
||||
|
||||
int lv_cnt;
|
||||
struct lv *lvs;
|
||||
};
|
||||
|
||||
int lvm_scan_vg(const char *vg_name, struct vg *vg);
|
||||
void lvm_free_vg(struct vg *vg);
|
||||
|
||||
#endif
|
||||
73
extracters/vhd-util/include/vhd-util-win32.h
Normal file
73
extracters/vhd-util/include/vhd-util-win32.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Compatibility file for Windows.
|
||||
* Compiler-forced #include at line 1 of every source.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <errno.h>
|
||||
#include <io.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <sys/types.h>
|
||||
#if defined(_MSC_VER)
|
||||
#include <BaseTsd.h>
|
||||
typedef SSIZE_T ssize_t;
|
||||
#endif
|
||||
#include <wingetopt.h>
|
||||
#include "relative-path.h"
|
||||
#define O_DIRECT 0
|
||||
|
||||
#define STDIN_FILENO 0
|
||||
#define STDOUT_FILENO 1
|
||||
#define STDERR_FILENO 2
|
||||
|
||||
#define open _open
|
||||
#define close _close
|
||||
|
||||
static inline int ftruncate(int fd, __int64 length)
|
||||
{
|
||||
HANDLE fh = (HANDLE)_get_osfhandle(fd);
|
||||
|
||||
if (!fh || _lseeki64(fd, length, SEEK_SET))
|
||||
return -1;
|
||||
return SetEndOfFile(fh) ? 0 : -1;
|
||||
}
|
||||
|
||||
#define fdatasync fsync
|
||||
|
||||
static inline int
|
||||
fsync (int fd)
|
||||
{
|
||||
HANDLE h = (HANDLE) _get_osfhandle (fd);
|
||||
DWORD err;
|
||||
|
||||
if (h == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!FlushFileBuffers (h))
|
||||
{
|
||||
err = GetLastError ();
|
||||
switch (err)
|
||||
{
|
||||
case ERROR_ACCESS_DENIED:
|
||||
return 0;
|
||||
|
||||
case ERROR_INVALID_HANDLE:
|
||||
errno = EINVAL;
|
||||
break;
|
||||
|
||||
default:
|
||||
errno = EIO;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Emulated in libvhd */
|
||||
|
||||
char *basename( char *path );
|
||||
44
extracters/vhd-util/include/vhd-util.h
Normal file
44
extracters/vhd-util/include/vhd-util.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/* Copyright (c) 2008, XenSource Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of XenSource Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _VHD_UTIL_H_
|
||||
#define _VHD_UTIL_H_
|
||||
|
||||
int vhd_util_create(int argc, char **argv);
|
||||
int vhd_util_snapshot(int argc, char **argv);
|
||||
int vhd_util_query(int argc, char **argv);
|
||||
int vhd_util_read(int argc, char **argv);
|
||||
int vhd_util_set_field(int argc, char **argv);
|
||||
int vhd_util_repair(int argc, char **argv);
|
||||
int vhd_util_fill(int argc, char **argv);
|
||||
int vhd_util_resize(int argc, char **argv);
|
||||
int vhd_util_coalesce(int argc, char **argv);
|
||||
int vhd_util_modify(int argc, char **argv);
|
||||
int vhd_util_scan(int argc, char **argv);
|
||||
int vhd_util_check(int argc, char **argv);
|
||||
int vhd_util_revert(int argc, char **argv);
|
||||
|
||||
#endif
|
||||
88
extracters/vhd-util/include/wingetopt.h
Normal file
88
extracters/vhd-util/include/wingetopt.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/* Declarations for getopt.
|
||||
Copyright (C) 1989,90,91,92,93,94,96,97,98 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
#ifndef _GETOPT_H
|
||||
|
||||
#ifndef __need_getopt
|
||||
# define _GETOPT_H 1
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern char *optarg;
|
||||
|
||||
extern int optind;
|
||||
|
||||
extern int opterr;
|
||||
|
||||
extern int optopt;
|
||||
|
||||
#ifndef __need_getopt
|
||||
|
||||
struct option
|
||||
{
|
||||
# if defined __STDC__ && __STDC__
|
||||
const char *name;
|
||||
# else
|
||||
char *name;
|
||||
# endif
|
||||
int has_arg;
|
||||
int *flag;
|
||||
int val;
|
||||
};
|
||||
|
||||
# define no_argument 0
|
||||
# define required_argument 1
|
||||
# define optional_argument 2
|
||||
#endif /* need getopt */
|
||||
|
||||
|
||||
#if defined __STDC__ && __STDC__
|
||||
extern int getopt ();
|
||||
|
||||
# ifndef __need_getopt
|
||||
extern int getopt_long (int __argc, char *const *__argv, const char *__shortopts,
|
||||
const struct option *__longopts, int *__longind);
|
||||
extern int getopt_long_only (int __argc, char *const *__argv,
|
||||
const char *__shortopts,
|
||||
const struct option *__longopts, int *__longind);
|
||||
|
||||
extern int _getopt_internal (int __argc, char *const *__argv,
|
||||
const char *__shortopts,
|
||||
const struct option *__longopts, int *__longind,
|
||||
int __long_only);
|
||||
# endif
|
||||
#else /* not __STDC__ */
|
||||
extern int getopt ();
|
||||
# ifndef __need_getopt
|
||||
extern int getopt_long ();
|
||||
extern int getopt_long_only ();
|
||||
|
||||
extern int _getopt_internal ();
|
||||
# endif
|
||||
#endif /* __STDC__ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#undef __need_getopt
|
||||
|
||||
#endif /* getopt.h */
|
||||
1618
extracters/vhd-util/libvhd-journal.c
Normal file
1618
extracters/vhd-util/libvhd-journal.c
Normal file
File diff suppressed because it is too large
Load Diff
349
extracters/vhd-util/lvm-util.c
Normal file
349
extracters/vhd-util/lvm-util.c
Normal file
@@ -0,0 +1,349 @@
|
||||
/*
|
||||
* Copyright (c) 2008, XenSource Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of XenSource Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lvm-util.h"
|
||||
|
||||
#define _NAME "%255s"
|
||||
static char line[1024];
|
||||
|
||||
static inline int
|
||||
lvm_read_line(FILE *scan)
|
||||
{
|
||||
memset(line, 0, sizeof(line));
|
||||
return (fscanf(scan, "%1023[^\n]", line) != 1);
|
||||
}
|
||||
|
||||
static inline int
|
||||
lvm_next_line(FILE *scan)
|
||||
{
|
||||
return (fscanf(scan, "%1023[\n]", line) != 1);
|
||||
}
|
||||
|
||||
static int
|
||||
lvm_copy_name(char *dst, const char *src, size_t size)
|
||||
{
|
||||
if (strnlen(src, size) == size)
|
||||
return -ENAMETOOLONG;
|
||||
|
||||
strcpy(dst, src);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
lvm_parse_pv(struct vg *vg, const char *name, int pvs, uint64_t start)
|
||||
{
|
||||
int i, err;
|
||||
struct pv *pv;
|
||||
|
||||
pv = NULL;
|
||||
|
||||
if (!vg->pvs) {
|
||||
vg->pvs = calloc(pvs, sizeof(struct pv));
|
||||
if (!vg->pvs)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
for (i = 0; i < pvs; i++) {
|
||||
pv = vg->pvs + i;
|
||||
|
||||
if (!pv->name[0])
|
||||
break;
|
||||
|
||||
if (!strcmp(pv->name, name))
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
if (!pv)
|
||||
return -ENOENT;
|
||||
|
||||
if (i == pvs)
|
||||
return -ENOMEM;
|
||||
|
||||
err = lvm_copy_name(pv->name, name, sizeof(pv->name) - 1);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
pv->start = start;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
lvm_open_vg(const char *vgname, struct vg *vg)
|
||||
{
|
||||
FILE *scan;
|
||||
int i, err, pvs, lvs;
|
||||
char *cmd, pvname[256];
|
||||
uint64_t size, pv_start;
|
||||
|
||||
memset(vg, 0, sizeof(*vg));
|
||||
|
||||
err = asprintf(&cmd, "/usr/sbin/vgs %s --noheadings --nosuffix --units=b "
|
||||
"--options=vg_name,vg_extent_size,lv_count,pv_count,"
|
||||
"pv_name,pe_start --unbuffered 2> /dev/null", vgname);
|
||||
if (err == -1)
|
||||
return -ENOMEM;
|
||||
|
||||
errno = 0;
|
||||
scan = popen(cmd, "r");
|
||||
if (!scan) {
|
||||
err = (errno ? -errno : ENOMEM);
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
if (lvm_read_line(scan))
|
||||
break;
|
||||
|
||||
err = -EINVAL;
|
||||
if (sscanf(line, _NAME" %"SCNu64" %d %d "_NAME" %"SCNu64,
|
||||
vg->name, &size, &lvs, &pvs, pvname, &pv_start) != 6)
|
||||
goto out;
|
||||
|
||||
if (strcmp(vg->name, vgname))
|
||||
goto out;
|
||||
|
||||
err = lvm_parse_pv(vg, pvname, pvs, pv_start);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
if (lvm_next_line(scan))
|
||||
break;
|
||||
}
|
||||
|
||||
err = -EINVAL;
|
||||
if (strcmp(vg->name, vgname))
|
||||
goto out;
|
||||
|
||||
for (i = 0; i < pvs; i++)
|
||||
if (!vg->pvs[i].name[0])
|
||||
goto out;
|
||||
|
||||
err = -ENOMEM;
|
||||
vg->lvs = calloc(lvs, sizeof(struct lv));
|
||||
if (!vg->lvs)
|
||||
goto out;
|
||||
|
||||
err = 0;
|
||||
vg->lv_cnt = lvs;
|
||||
vg->pv_cnt = pvs;
|
||||
vg->extent_size = size;
|
||||
|
||||
out:
|
||||
if (scan)
|
||||
pclose(scan);
|
||||
if (err)
|
||||
lvm_free_vg(vg);
|
||||
free(cmd);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
lvm_parse_lv_devices(struct vg *vg, struct lv_segment *seg, char *devices)
|
||||
{
|
||||
size_t i;
|
||||
uint64_t start, pe_start;
|
||||
|
||||
for (i = 0; i < strlen(devices); i++)
|
||||
if (strchr(",()", devices[i]))
|
||||
devices[i] = ' ';
|
||||
|
||||
if (sscanf(devices, _NAME" %"SCNu64, seg->device, &start) != 2)
|
||||
return -EINVAL;
|
||||
|
||||
pe_start = -1;
|
||||
for (i = 0; i < (size_t)vg->pv_cnt; i++)
|
||||
if (!strcmp(vg->pvs[i].name, seg->device)) {
|
||||
pe_start = vg->pvs[i].start;
|
||||
break;
|
||||
}
|
||||
|
||||
if (pe_start == -1)
|
||||
return -EINVAL;
|
||||
|
||||
seg->pe_start = (start * vg->extent_size) + pe_start;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
lvm_scan_lvs(struct vg *vg)
|
||||
{
|
||||
char *cmd;
|
||||
FILE *scan;
|
||||
int i, err;
|
||||
|
||||
err = asprintf(&cmd, "/usr/sbin/lvs %s --noheadings --nosuffix --units=b "
|
||||
"--options=lv_name,lv_size,segtype,seg_count,seg_start,"
|
||||
"seg_size,devices --unbuffered 2> /dev/null", vg->name);
|
||||
if (err == -1)
|
||||
return -ENOMEM;
|
||||
|
||||
errno = 0;
|
||||
scan = popen(cmd, "r");
|
||||
if (!scan) {
|
||||
err = (errno ? -errno : -ENOMEM);
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0;;) {
|
||||
int segs;
|
||||
struct lv *lv;
|
||||
struct lv_segment seg;
|
||||
uint64_t size, seg_start;
|
||||
char type[32], name[256], devices[1024];
|
||||
|
||||
if (i >= vg->lv_cnt)
|
||||
break;
|
||||
|
||||
if (lvm_read_line(scan)) {
|
||||
vg->lv_cnt = i;
|
||||
break;
|
||||
}
|
||||
|
||||
err = -EINVAL;
|
||||
lv = vg->lvs + i;
|
||||
|
||||
if (sscanf(line, _NAME" %"SCNu64" %31s %u %"SCNu64" %"SCNu64" %1023s",
|
||||
name, &size, type, &segs, &seg_start,
|
||||
&seg.pe_size, devices) != 7)
|
||||
goto out;
|
||||
|
||||
if (seg_start)
|
||||
goto next;
|
||||
|
||||
if (!strcmp(type, "linear"))
|
||||
seg.type = LVM_SEG_TYPE_LINEAR;
|
||||
else
|
||||
seg.type = LVM_SEG_TYPE_UNKNOWN;
|
||||
|
||||
if (lvm_parse_lv_devices(vg, &seg, devices))
|
||||
goto out;
|
||||
|
||||
i++;
|
||||
lv->size = size;
|
||||
lv->segments = segs;
|
||||
lv->first_segment = seg;
|
||||
|
||||
err = lvm_copy_name(lv->name, name, sizeof(lv->name) - 1);
|
||||
if (err)
|
||||
goto out;
|
||||
err = -EINVAL;
|
||||
|
||||
next:
|
||||
if (lvm_next_line(scan))
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = 0;
|
||||
|
||||
out:
|
||||
if (scan)
|
||||
pclose(scan);
|
||||
free(cmd);
|
||||
return err;
|
||||
}
|
||||
|
||||
void
|
||||
lvm_free_vg(struct vg *vg)
|
||||
{
|
||||
free(vg->lvs);
|
||||
free(vg->pvs);
|
||||
memset(vg, 0, sizeof(*vg));
|
||||
}
|
||||
|
||||
int
|
||||
lvm_scan_vg(const char *vg_name, struct vg *vg)
|
||||
{
|
||||
int err;
|
||||
|
||||
memset(vg, 0, sizeof(*vg));
|
||||
|
||||
err = lvm_open_vg(vg_name, vg);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = lvm_scan_lvs(vg);
|
||||
if (err) {
|
||||
lvm_free_vg(vg);
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef LVM_UTIL
|
||||
static int
|
||||
usage(void)
|
||||
{
|
||||
printf("usage: lvm-util <vgname>\n");
|
||||
exit(EINVAL);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int i, err;
|
||||
struct vg vg;
|
||||
struct pv *pv;
|
||||
struct lv *lv;
|
||||
struct lv_segment *seg;
|
||||
|
||||
if (argc != 2)
|
||||
usage();
|
||||
|
||||
err = lvm_scan_vg(argv[1], &vg);
|
||||
if (err) {
|
||||
printf("scan failed: %d\n", err);
|
||||
return (err >= 0 ? err : -err);
|
||||
}
|
||||
|
||||
|
||||
printf("vg %s: extent_size: %"PRIu64", pvs: %d, lvs: %d\n",
|
||||
vg.name, vg.extent_size, vg.pv_cnt, vg.lv_cnt);
|
||||
|
||||
for (i = 0; i < vg.pv_cnt; i++) {
|
||||
pv = vg.pvs + i;
|
||||
printf("pv %s: start %"PRIu64"\n", pv->name, pv->start);
|
||||
}
|
||||
|
||||
for (i = 0; i < vg.lv_cnt; i++) {
|
||||
lv = vg.lvs + i;
|
||||
seg = &lv->first_segment;
|
||||
printf("lv %s: size: %"PRIu64", segments: %u, type: %u, "
|
||||
"dev: %s, pe_start: %"PRIu64", pe_size: %"PRIu64"\n",
|
||||
lv->name, lv->size, lv->segments, seg->type,
|
||||
seg->device, seg->pe_start, seg->pe_size);
|
||||
}
|
||||
|
||||
lvm_free_vg(&vg);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
BIN
extracters/vhd-util/vhd-util
Executable file
BIN
extracters/vhd-util/vhd-util
Executable file
Binary file not shown.
1024
extracters/vhd-util/vhd-util-check.c
Normal file
1024
extracters/vhd-util/vhd-util-check.c
Normal file
File diff suppressed because it is too large
Load Diff
232
extracters/vhd-util/vhd-util-coalesce.c
Normal file
232
extracters/vhd-util/vhd-util-coalesce.c
Normal file
@@ -0,0 +1,232 @@
|
||||
/* Copyright (c) 2008, XenSource Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of XenSource Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
#include "libvhd.h"
|
||||
|
||||
static int
|
||||
__raw_io_write(int fd, char* buf, uint64_t sec, uint32_t secs)
|
||||
{
|
||||
off_t off;
|
||||
size_t ret;
|
||||
|
||||
errno = 0;
|
||||
off = lseek(fd, (off_t)vhd_sectors_to_bytes(sec), SEEK_SET);
|
||||
if (off == (off_t)-1) {
|
||||
printf("raw parent: seek(0x%08"PRIx64") failed: %d\n",
|
||||
vhd_sectors_to_bytes(sec), -errno);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
ret = write(fd, buf, (size_t)vhd_sectors_to_bytes(secs));
|
||||
if (ret == vhd_sectors_to_bytes(secs))
|
||||
return 0;
|
||||
|
||||
printf("raw parent: write of 0x%"PRIx64" returned %zd, errno: %d\n",
|
||||
vhd_sectors_to_bytes(secs), ret, -errno);
|
||||
return (errno ? -errno : -EIO);
|
||||
}
|
||||
|
||||
/*
|
||||
* Use 'parent' if the parent is VHD, and 'parent_fd' if the parent is raw
|
||||
*/
|
||||
static int
|
||||
vhd_util_coalesce_block(vhd_context_t *vhd, vhd_context_t *parent,
|
||||
int parent_fd, uint64_t block)
|
||||
{
|
||||
size_t i;
|
||||
int err;
|
||||
char *buf, *map;
|
||||
uint64_t sec, secs;
|
||||
|
||||
buf = NULL;
|
||||
map = NULL;
|
||||
sec = block * vhd->spb;
|
||||
|
||||
if (vhd->bat.bat[block] == DD_BLK_UNUSED)
|
||||
return 0;
|
||||
|
||||
#ifdef _WIN32
|
||||
buf = _aligned_malloc( vhd->header.block_size, 4096 );
|
||||
if( buf == NULL )
|
||||
return -errno;
|
||||
#else
|
||||
err = posix_memalign( (void **)&buf, 4096, vhd->header.block_size );
|
||||
if( err )
|
||||
return -err;
|
||||
#endif
|
||||
|
||||
err = vhd_io_read(vhd, buf, sec, vhd->spb);
|
||||
if (err)
|
||||
goto done;
|
||||
|
||||
if (vhd_has_batmap(vhd) && vhd_batmap_test(vhd, &vhd->batmap, (uint32_t)block)) {
|
||||
if (parent->file)
|
||||
err = vhd_io_write(parent, buf, sec, vhd->spb);
|
||||
else
|
||||
err = __raw_io_write(parent_fd, buf, sec, vhd->spb);
|
||||
goto done;
|
||||
}
|
||||
|
||||
err = vhd_read_bitmap(vhd, (uint32_t)block, &map);
|
||||
if (err)
|
||||
goto done;
|
||||
|
||||
for (i = 0; i < vhd->spb; i++) {
|
||||
if (!vhd_bitmap_test(vhd, map, i))
|
||||
continue;
|
||||
|
||||
for (secs = 0; i + secs < vhd->spb; secs++)
|
||||
if (!vhd_bitmap_test(vhd, map, i + (uint32_t)secs))
|
||||
break;
|
||||
|
||||
if (parent->file)
|
||||
err = vhd_io_write(parent,
|
||||
buf + vhd_sectors_to_bytes(i),
|
||||
sec + i, (uint32_t)secs);
|
||||
else
|
||||
err = __raw_io_write(parent_fd,
|
||||
buf + vhd_sectors_to_bytes(i),
|
||||
sec + i, (uint32_t)secs);
|
||||
if (err)
|
||||
goto done;
|
||||
|
||||
i += (uint32_t)secs;
|
||||
}
|
||||
|
||||
err = 0;
|
||||
|
||||
done:
|
||||
#ifdef _WIN32
|
||||
_aligned_free( buf );
|
||||
#else
|
||||
free( buf );
|
||||
#endif
|
||||
free(map);
|
||||
return err;
|
||||
}
|
||||
|
||||
int
|
||||
vhd_util_coalesce(int argc, char **argv)
|
||||
{
|
||||
int err, c;
|
||||
uint64_t i;
|
||||
char *name, *pname;
|
||||
vhd_context_t vhd, parent;
|
||||
int parent_fd = -1;
|
||||
|
||||
name = NULL;
|
||||
pname = NULL;
|
||||
parent.file = NULL;
|
||||
|
||||
if (!argc || !argv)
|
||||
goto usage;
|
||||
|
||||
optind = 0;
|
||||
while ((c = getopt(argc, argv, "n:h")) != -1) {
|
||||
switch (c) {
|
||||
case 'n':
|
||||
name = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
|
||||
if (!name || optind != argc)
|
||||
goto usage;
|
||||
|
||||
err = vhd_open(&vhd, name, VHD_OPEN_RDONLY);
|
||||
if (err) {
|
||||
printf("error opening %s: %d\n", name, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = vhd_parent_locator_get(&vhd, &pname);
|
||||
if (err) {
|
||||
printf("error finding %s parent: %d\n", name, err);
|
||||
vhd_close(&vhd);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (vhd_parent_raw(&vhd)) {
|
||||
parent_fd = open(pname, O_RDWR | O_DIRECT | O_LARGEFILE | O_BINARY, 0644);
|
||||
if (parent_fd == -1) {
|
||||
err = -errno;
|
||||
printf("failed to open parent %s: %d\n", pname, err);
|
||||
vhd_close(&vhd);
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
err = vhd_open(&parent, pname, VHD_OPEN_RDWR);
|
||||
if (err) {
|
||||
printf("error opening %s: %d\n", pname, err);
|
||||
free(pname);
|
||||
vhd_close(&vhd);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
err = vhd_get_bat(&vhd);
|
||||
if (err)
|
||||
goto done;
|
||||
|
||||
if (vhd_has_batmap(&vhd)) {
|
||||
err = vhd_get_batmap(&vhd);
|
||||
if (err)
|
||||
goto done;
|
||||
}
|
||||
|
||||
for (i = 0; i < vhd.bat.entries; i++) {
|
||||
err = vhd_util_coalesce_block(&vhd, &parent, parent_fd, i);
|
||||
if (err)
|
||||
goto done;
|
||||
}
|
||||
|
||||
err = 0;
|
||||
|
||||
done:
|
||||
free(pname);
|
||||
vhd_close(&vhd);
|
||||
if (parent.file)
|
||||
vhd_close(&parent);
|
||||
else
|
||||
close(parent_fd);
|
||||
return err;
|
||||
|
||||
usage:
|
||||
printf("options: <-n name> [-h help]\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
82
extracters/vhd-util/vhd-util-create.c
Normal file
82
extracters/vhd-util/vhd-util-create.c
Normal file
@@ -0,0 +1,82 @@
|
||||
/* Copyright (c) 2008, XenSource Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of XenSource Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "libvhd.h"
|
||||
|
||||
int
|
||||
vhd_util_create(int argc, char **argv)
|
||||
{
|
||||
char *name;
|
||||
uint64_t size;
|
||||
int c, sparse, err;
|
||||
vhd_flag_creat_t flags;
|
||||
|
||||
err = -EINVAL;
|
||||
size = 0;
|
||||
sparse = 1;
|
||||
name = NULL;
|
||||
flags = 0;
|
||||
|
||||
if (!argc || !argv)
|
||||
goto usage;
|
||||
|
||||
optind = 0;
|
||||
while ((c = getopt(argc, argv, "n:s:rh")) != -1) {
|
||||
switch (c) {
|
||||
case 'n':
|
||||
name = optarg;
|
||||
break;
|
||||
case 's':
|
||||
err = 0;
|
||||
size = strtoull(optarg, NULL, 10);
|
||||
break;
|
||||
case 'r':
|
||||
sparse = 0;
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
|
||||
if (err || !name || optind != argc)
|
||||
goto usage;
|
||||
|
||||
return vhd_create(name, size << 20,
|
||||
(sparse ? HD_TYPE_DYNAMIC : HD_TYPE_FIXED),
|
||||
flags);
|
||||
|
||||
usage:
|
||||
printf("options: <-n name> <-s size (MB)> [-r reserve] [-h help]\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
119
extracters/vhd-util/vhd-util-fill.c
Normal file
119
extracters/vhd-util/vhd-util-fill.c
Normal file
@@ -0,0 +1,119 @@
|
||||
/* Copyright (c) 2008, XenSource Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of XenSource Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "libvhd.h"
|
||||
|
||||
int
|
||||
vhd_util_fill( int argc, char **argv )
|
||||
{
|
||||
int err, c;
|
||||
char *buf, *name;
|
||||
vhd_context_t vhd;
|
||||
uint64_t i, sec, secs;
|
||||
|
||||
buf = NULL;
|
||||
name = NULL;
|
||||
|
||||
if( !argc || !argv )
|
||||
goto usage;
|
||||
|
||||
optind = 0;
|
||||
while( (c = getopt( argc, argv, "n:h" )) != -1 ) {
|
||||
switch( c ) {
|
||||
case 'n':
|
||||
name = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
|
||||
if( !name || optind != argc )
|
||||
goto usage;
|
||||
|
||||
err = vhd_open( &vhd, name, VHD_OPEN_RDWR );
|
||||
if( err ) {
|
||||
printf( "error opening %s: %d\n", name, err );
|
||||
return err;
|
||||
}
|
||||
|
||||
err = vhd_get_bat( &vhd );
|
||||
if( err )
|
||||
goto done;
|
||||
|
||||
#ifdef _WIN32
|
||||
buf = _aligned_malloc( vhd.header.block_size, 4096 );
|
||||
if( buf == NULL ) {
|
||||
err = -errno;
|
||||
goto done;
|
||||
}
|
||||
#else
|
||||
err = posix_memalign((void **)&buf, 4096, vhd.header.block_size);
|
||||
if (err) {
|
||||
err = -err;
|
||||
goto done;
|
||||
}
|
||||
#endif
|
||||
|
||||
sec = 0;
|
||||
secs = vhd.header.block_size >> VHD_SECTOR_SHIFT;
|
||||
|
||||
for (i = 0; i < vhd.header.max_bat_size; i++) {
|
||||
err = vhd_io_read(&vhd, buf, sec, (uint32_t)secs);
|
||||
if (err)
|
||||
goto done;
|
||||
|
||||
err = vhd_io_write(&vhd, buf, sec, (uint32_t)secs);
|
||||
if (err)
|
||||
goto done;
|
||||
|
||||
sec += secs;
|
||||
}
|
||||
|
||||
err = 0;
|
||||
|
||||
done:
|
||||
#ifdef _WIN32
|
||||
_aligned_free( buf );
|
||||
#else
|
||||
free( buf );
|
||||
#endif
|
||||
vhd_close(&vhd);
|
||||
return err;
|
||||
|
||||
usage:
|
||||
printf("options: <-n name> [-h help]\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
144
extracters/vhd-util/vhd-util-modify.c
Normal file
144
extracters/vhd-util/vhd-util-modify.c
Normal file
@@ -0,0 +1,144 @@
|
||||
/* Copyright (c) 2008, XenSource Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of XenSource Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Altering operations:
|
||||
*
|
||||
* 1. Change the parent pointer to another file.
|
||||
* 2. Change the size of the file containing the VHD image. This does NOT
|
||||
* affect the VHD disk capacity, only the physical size of the file containing
|
||||
* the VHD. Naturally, it is not possible to set the file size to be less than
|
||||
* the what VHD utilizes.
|
||||
* The operation doesn't actually change the file size, but it writes the
|
||||
* footer in the right location such that resizing the file (manually, as a
|
||||
* separate step) will produce the correct results. If the new file size is
|
||||
* greater than the current file size, the file must first be expanded and then
|
||||
* altered with this operation. If the new size is smaller than the current
|
||||
* size, the VHD must first be altered with this operation and then the file
|
||||
* must be shrunk. Failing to resize the file will result in a corrupted VHD.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "libvhd.h"
|
||||
|
||||
TEST_FAIL_EXTERN_VARS;
|
||||
|
||||
int
|
||||
vhd_util_modify(int argc, char **argv)
|
||||
{
|
||||
char *name;
|
||||
vhd_context_t vhd;
|
||||
int err, c, size, parent, parent_flags;
|
||||
off_t newsize = 0;
|
||||
char *newparent = NULL;
|
||||
|
||||
name = NULL;
|
||||
size = 0;
|
||||
parent = 0;
|
||||
parent_flags = 0;
|
||||
|
||||
optind = 0;
|
||||
while ((c = getopt(argc, argv, "n:s:p:P:mh")) != -1) {
|
||||
switch (c) {
|
||||
case 'n':
|
||||
name = optarg;
|
||||
break;
|
||||
case 's':
|
||||
size = 1;
|
||||
errno = 0;
|
||||
newsize = (off_t)strtoll(optarg, NULL, 10);
|
||||
if (errno) {
|
||||
fprintf(stderr, "Invalid size '%s'\n", optarg);
|
||||
goto usage;
|
||||
}
|
||||
break;
|
||||
case 'p':
|
||||
if( parent && strcmp( newparent, optarg ) ) {
|
||||
fprintf(stderr, "Parent name doesn't match\n");
|
||||
goto usage;
|
||||
}
|
||||
++parent;
|
||||
newparent = optarg;
|
||||
break;
|
||||
case 'P':
|
||||
parent = 2;
|
||||
parent_flags |= 2;
|
||||
newparent = optarg;
|
||||
break;
|
||||
case 'm':
|
||||
parent_flags |= 1;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
|
||||
if (!name || optind != argc || (parent && parent <2))
|
||||
goto usage;
|
||||
|
||||
err = vhd_open(&vhd, name, VHD_OPEN_RDWR);
|
||||
if (err) {
|
||||
printf("error opening %s: %d\n", name, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (size) {
|
||||
err = vhd_set_phys_size(&vhd, newsize);
|
||||
if (err)
|
||||
printf("failed to set physical size to %"PRIu64":"
|
||||
" %d\n", (uintmax_t)newsize, err);
|
||||
}
|
||||
|
||||
if (parent) {
|
||||
TEST_FAIL_AT(FAIL_REPARENT_BEGIN);
|
||||
err = vhd_change_parent(&vhd, newparent, parent_flags);
|
||||
if (err) {
|
||||
printf("failed to set parent to '%s': %d\n",
|
||||
newparent, err);
|
||||
goto done;
|
||||
}
|
||||
TEST_FAIL_AT(FAIL_REPARENT_END);
|
||||
}
|
||||
|
||||
done:
|
||||
vhd_close(&vhd);
|
||||
return err;
|
||||
|
||||
usage:
|
||||
printf("*** Dangerous operations, use with care ***\n");
|
||||
printf("options: <-n name> [-p NEW_PARENT set parent [-m raw]] "
|
||||
"[-P change PARENT with uuid check] "
|
||||
"[-s NEW_SIZE set size] [-h help]\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
161
extracters/vhd-util/vhd-util-query.c
Normal file
161
extracters/vhd-util/vhd-util-query.c
Normal file
@@ -0,0 +1,161 @@
|
||||
/* Copyright (c) 2008, XenSource Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of XenSource Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "libvhd.h"
|
||||
|
||||
int
|
||||
vhd_util_query(int argc, char **argv)
|
||||
{
|
||||
char *name;
|
||||
vhd_context_t vhd;
|
||||
off_t currsize;
|
||||
int ret, err, c, size, physize, parent, fields, depth;
|
||||
|
||||
name = NULL;
|
||||
size = 0;
|
||||
physize = 0;
|
||||
parent = 0;
|
||||
fields = 0;
|
||||
depth = 0;
|
||||
|
||||
if (!argc || !argv) {
|
||||
err = -EINVAL;
|
||||
goto usage;
|
||||
}
|
||||
|
||||
optind = 0;
|
||||
while ((c = getopt(argc, argv, "n:vspfdh")) != -1) {
|
||||
switch (c) {
|
||||
case 'n':
|
||||
name = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
size = 1;
|
||||
break;
|
||||
case 's':
|
||||
physize = 1;
|
||||
break;
|
||||
case 'p':
|
||||
parent = 1;
|
||||
break;
|
||||
case 'f':
|
||||
fields = 1;
|
||||
break;
|
||||
case 'd':
|
||||
depth = 1;
|
||||
break;
|
||||
case 'h':
|
||||
err = 0;
|
||||
goto usage;
|
||||
default:
|
||||
err = -EINVAL;
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
|
||||
if (!name || optind != argc) {
|
||||
err = -EINVAL;
|
||||
goto usage;
|
||||
}
|
||||
|
||||
err = vhd_open(&vhd, name, VHD_OPEN_RDONLY | VHD_OPEN_IGNORE_DISABLED);
|
||||
if (err) {
|
||||
printf("error opening %s: %d\n", name, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (size)
|
||||
printf("%"PRIu64"\n", vhd.footer.curr_size >> 20);
|
||||
|
||||
if (physize) {
|
||||
err = vhd_get_phys_size(&vhd, &currsize);
|
||||
if (err)
|
||||
printf("failed to get physical size: %d\n", err);
|
||||
else
|
||||
printf("%"PRIu64"\n", (uintmax_t)currsize);
|
||||
}
|
||||
|
||||
if (parent) {
|
||||
ret = 0;
|
||||
|
||||
if (vhd.footer.type != HD_TYPE_DIFF)
|
||||
printf("%s has no parent\n", name);
|
||||
else {
|
||||
char *pname;
|
||||
|
||||
ret = vhd_parent_locator_get(&vhd, &pname);
|
||||
if (ret)
|
||||
printf("query failed\n");
|
||||
else {
|
||||
printf("%s\n", pname);
|
||||
free(pname);
|
||||
}
|
||||
}
|
||||
|
||||
err = (err ? err : ret);
|
||||
}
|
||||
|
||||
if (fields) {
|
||||
int hidden;
|
||||
|
||||
ret = vhd_hidden(&vhd, &hidden);
|
||||
if (ret)
|
||||
printf("error checking 'hidden' field: %d\n", ret);
|
||||
else
|
||||
printf("hidden: %d\n", hidden);
|
||||
|
||||
err = (err ? err : ret);
|
||||
}
|
||||
|
||||
if (depth) {
|
||||
int length;
|
||||
|
||||
ret = vhd_chain_depth(&vhd, &length);
|
||||
if (ret)
|
||||
printf("error checking chain depth: %d\n", ret);
|
||||
else
|
||||
printf("chain depth: %d\n", length);
|
||||
|
||||
err = (err ? err : ret);
|
||||
}
|
||||
|
||||
vhd_close(&vhd);
|
||||
return err;
|
||||
|
||||
usage:
|
||||
printf("options: <-n name> [-v print virtual size (in MB)] "
|
||||
"[-s print physical utilization (bytes)] [-p print parent] "
|
||||
"[-f print fields] [-d print chain depth] [-h help]\n");
|
||||
return err;
|
||||
}
|
||||
876
extracters/vhd-util/vhd-util-read.c
Normal file
876
extracters/vhd-util/vhd-util-read.c
Normal file
@@ -0,0 +1,876 @@
|
||||
/* Copyright (c) 2008, XenSource Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of XenSource Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#define _O_BINARY 0
|
||||
#endif
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "libvhd.h"
|
||||
#include "vhd-util.h"
|
||||
|
||||
#define nsize 15
|
||||
static char nbuf[nsize];
|
||||
|
||||
static inline char *
|
||||
__xconv(uint64_t num)
|
||||
{
|
||||
snprintf(nbuf, nsize, "%#" PRIx64 , num);
|
||||
return nbuf;
|
||||
}
|
||||
|
||||
static inline char *
|
||||
__dconv(uint64_t num)
|
||||
{
|
||||
snprintf(nbuf, nsize, "%" PRIu64, num);
|
||||
return nbuf;
|
||||
}
|
||||
|
||||
#define conv(hex, num) \
|
||||
(hex ? __xconv((uint64_t)num) : __dconv((uint64_t)num))
|
||||
|
||||
static void
|
||||
vhd_print_header(vhd_context_t *vhd, vhd_header_t *h, int hex)
|
||||
{
|
||||
int err;
|
||||
uint32_t cksm;
|
||||
char uuid[39], time_str[26], cookie[9], *name;
|
||||
|
||||
printf("VHD Header Summary:\n-------------------\n");
|
||||
|
||||
snprintf(cookie, sizeof(cookie), "%s", h->cookie);
|
||||
printf("Cookie : %s\n", cookie);
|
||||
|
||||
printf("Data offset (unusd) : %s\n", conv(hex, h->data_offset));
|
||||
printf("Table offset : %s\n", conv(hex, h->table_offset));
|
||||
printf("Header version : 0x%08x\n", h->hdr_ver);
|
||||
printf("Max BAT size : %s\n", conv(hex, h->max_bat_size));
|
||||
printf("Block size : %s ", conv(hex, h->block_size));
|
||||
printf("(%s MB)\n", conv(hex, h->block_size >> 20));
|
||||
|
||||
err = vhd_header_decode_parent(vhd, h, &name);
|
||||
printf("Parent name : %s\n",
|
||||
(err ? "failed to read name" : name));
|
||||
free(name);
|
||||
|
||||
blk_uuid_to_string(&h->prt_uuid, uuid, sizeof(uuid));
|
||||
printf("Parent UUID : %s\n", uuid);
|
||||
|
||||
vhd_time_to_string(h->prt_ts, time_str);
|
||||
printf("Parent timestamp : %s\n", time_str);
|
||||
|
||||
cksm = vhd_checksum_header(h);
|
||||
printf("Checksum : 0x%x|0x%x (%s)\n", h->checksum, cksm,
|
||||
h->checksum == cksm ? "Good!" : "Bad!");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void
|
||||
vhd_print_footer(vhd_footer_t *f, int hex)
|
||||
{
|
||||
uint64_t c, h, s;
|
||||
uint32_t ff_maj, ff_min, cr_maj, cr_min, cksm;
|
||||
char time_str[26], creator[5], uuid[39], cookie[9];
|
||||
|
||||
printf("VHD Footer Summary:\n-------------------\n");
|
||||
|
||||
snprintf(cookie, sizeof(cookie), "%s", f->cookie);
|
||||
printf("Cookie : %s\n", cookie);
|
||||
|
||||
printf("Features : (0x%08x) %s%s\n", f->features,
|
||||
(f->features & HD_TEMPORARY) ? "<TEMP>" : "",
|
||||
(f->features & HD_RESERVED) ? "<RESV>" : "");
|
||||
|
||||
ff_maj = f->ff_version >> 16;
|
||||
ff_min = f->ff_version & 0xffff;
|
||||
printf("File format version : Major: %d, Minor: %d\n",
|
||||
ff_maj, ff_min);
|
||||
|
||||
printf("Data offset : %s\n", conv(hex, f->data_offset));
|
||||
|
||||
vhd_time_to_string(f->timestamp, time_str);
|
||||
printf("Timestamp : %s\n", time_str);
|
||||
|
||||
memcpy(creator, f->crtr_app, 4);
|
||||
creator[4] = '\0';
|
||||
printf("Creator Application : '%s'\n", creator);
|
||||
|
||||
cr_maj = f->crtr_ver >> 16;
|
||||
cr_min = f->crtr_ver & 0xffff;
|
||||
printf("Creator version : Major: %d, Minor: %d\n",
|
||||
cr_maj, cr_min);
|
||||
|
||||
printf("Creator OS : %s\n",
|
||||
((f->crtr_os == HD_CR_OS_WINDOWS) ? "Windows" :
|
||||
((f->crtr_os == HD_CR_OS_MACINTOSH) ? "Macintosh" :
|
||||
((f->crtr_os == HD_CR_OS_UNIX) ? "Unix" :
|
||||
((f->crtr_os == HD_CR_OS_VMS) ? "VMS" :
|
||||
"Unknown!")))));
|
||||
|
||||
printf("Original disk size : %s MB ", conv(hex, f->orig_size >> 20));
|
||||
printf("(%s Bytes)\n", conv(hex, f->orig_size));
|
||||
|
||||
printf("Current disk size : %s MB ", conv(hex, f->curr_size >> 20));
|
||||
printf("(%s Bytes)\n", conv(hex, f->curr_size));
|
||||
|
||||
c = f->geometry >> 16;
|
||||
h = (f->geometry & 0x0000FF00) >> 8;
|
||||
s = f->geometry & 0x000000FF;
|
||||
printf("Geometry : Cyl: %s, ", conv(hex, c));
|
||||
printf("Hds: %s, ", conv(hex, h));
|
||||
printf("Sctrs: %s\n", conv(hex, s));
|
||||
printf(" : = %s MB ", conv(hex, (c * h * s) >> 11));
|
||||
printf("(%s Bytes)\n", conv(hex, c * h * s << 9));
|
||||
|
||||
printf("Disk type : %s\n",
|
||||
f->type <= HD_TYPE_MAX ?
|
||||
HD_TYPE_STR[f->type] : "Unknown");
|
||||
|
||||
cksm = vhd_checksum_footer(f);
|
||||
printf("Checksum : 0x%x|0x%x (%s)\n", f->checksum, cksm,
|
||||
f->checksum == cksm ? "Good!" : "Bad!");
|
||||
|
||||
blk_uuid_to_string(&f->uuid, uuid, sizeof(uuid));
|
||||
printf("UUID : %s\n", uuid);
|
||||
|
||||
printf("Saved state : %s\n", f->saved == 0 ? "No" : "Yes");
|
||||
printf("Hidden : %d\n", f->hidden);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static inline char *
|
||||
code_name(uint32_t code)
|
||||
{
|
||||
switch(code) {
|
||||
case PLAT_CODE_NONE:
|
||||
return "PLAT_CODE_NONE";
|
||||
case PLAT_CODE_WI2R:
|
||||
return "PLAT_CODE_WI2R";
|
||||
case PLAT_CODE_WI2K:
|
||||
return "PLAT_CODE_WI2K";
|
||||
case PLAT_CODE_W2RU:
|
||||
return "PLAT_CODE_W2RU";
|
||||
case PLAT_CODE_W2KU:
|
||||
return "PLAT_CODE_W2KU";
|
||||
case PLAT_CODE_MAC:
|
||||
return "PLAT_CODE_MAC";
|
||||
case PLAT_CODE_MACX:
|
||||
return "PLAT_CODE_MACX";
|
||||
default:
|
||||
return "UNKOWN";
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
vhd_print_parent(vhd_context_t *vhd, vhd_parent_locator_t *loc)
|
||||
{
|
||||
int err;
|
||||
char *buf;
|
||||
|
||||
err = vhd_parent_locator_read(vhd, loc, &buf);
|
||||
if (err) {
|
||||
printf("failed to read parent name\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf(" decoded name : %s\n", buf);
|
||||
free( buf );
|
||||
}
|
||||
|
||||
static void
|
||||
vhd_print_parent_locators(vhd_context_t *vhd, int hex)
|
||||
{
|
||||
int i, n;
|
||||
vhd_parent_locator_t *loc;
|
||||
|
||||
printf("VHD Parent Locators:\n--------------------\n");
|
||||
|
||||
n = sizeof(vhd->header.loc) / sizeof(struct prt_loc);
|
||||
for (i = 0; i < n; i++) {
|
||||
loc = &vhd->header.loc[i];
|
||||
|
||||
if (loc->code == PLAT_CODE_NONE)
|
||||
continue;
|
||||
|
||||
printf("locator: : %d\n", i);
|
||||
printf(" code : %s\n",
|
||||
code_name(loc->code));
|
||||
printf(" data_space : %s\n",
|
||||
conv(hex, loc->data_space));
|
||||
printf(" data_length : %s\n",
|
||||
conv(hex, loc->data_len));
|
||||
printf(" data_offset : %s\n",
|
||||
conv(hex, loc->data_offset));
|
||||
vhd_print_parent(vhd, loc);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
vhd_print_batmap_header(vhd_batmap_t *batmap, int hex)
|
||||
{
|
||||
uint32_t cksm;
|
||||
|
||||
printf("VHD Batmap Summary:\n-------------------\n");
|
||||
printf("Batmap offset : %s\n",
|
||||
conv(hex, batmap->header.batmap_offset));
|
||||
printf("Batmap size (secs) : %s\n",
|
||||
conv(hex, batmap->header.batmap_size));
|
||||
printf("Batmap version : 0x%08x\n",
|
||||
batmap->header.batmap_version);
|
||||
|
||||
cksm = vhd_checksum_batmap(batmap);
|
||||
printf("Checksum : 0x%x|0x%x (%s)\n",
|
||||
batmap->header.checksum, cksm,
|
||||
(batmap->header.checksum == cksm ? "Good!" : "Bad!"));
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static inline int
|
||||
check_block_range(vhd_context_t *vhd, uint64_t block, int hex)
|
||||
{
|
||||
if (block > vhd->header.max_bat_size) {
|
||||
fprintf(stderr, "block %s past end of file\n",
|
||||
conv(hex, block));
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
vhd_print_headers(vhd_context_t *vhd, int hex)
|
||||
{
|
||||
int err;
|
||||
|
||||
vhd_print_footer(&vhd->footer, hex);
|
||||
|
||||
if (vhd_type_dynamic(vhd)) {
|
||||
vhd_print_header(vhd, &vhd->header, hex);
|
||||
|
||||
if (vhd->footer.type == HD_TYPE_DIFF)
|
||||
vhd_print_parent_locators(vhd, hex);
|
||||
|
||||
if (vhd_has_batmap(vhd)) {
|
||||
err = vhd_get_batmap(vhd);
|
||||
if (err) {
|
||||
printf("failed to get batmap header\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
vhd_print_batmap_header(&vhd->batmap, hex);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
vhd_dump_headers(const char *name, int hex)
|
||||
{
|
||||
vhd_context_t vhd;
|
||||
|
||||
libvhd_set_log_level(1);
|
||||
memset(&vhd, 0, sizeof(vhd));
|
||||
|
||||
printf("\n%s appears invalid; dumping headers\n\n", name);
|
||||
|
||||
vhd.fd = open(name, O_DIRECT | O_LARGEFILE | O_RDONLY | _O_BINARY);
|
||||
if (vhd.fd == -1)
|
||||
return -errno;
|
||||
|
||||
vhd.file = strdup(name);
|
||||
|
||||
vhd_read_footer(&vhd, &vhd.footer);
|
||||
vhd_read_header(&vhd, &vhd.header);
|
||||
|
||||
vhd_print_footer(&vhd.footer, hex);
|
||||
vhd_print_header(&vhd, &vhd.header, hex);
|
||||
|
||||
close(vhd.fd);
|
||||
free(vhd.file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
vhd_print_logical_to_physical(vhd_context_t *vhd,
|
||||
uint64_t sector, int count, int hex)
|
||||
{
|
||||
int i;
|
||||
uint32_t blk, lsec;
|
||||
uint64_t cur, offset;
|
||||
|
||||
if (vhd_sectors_to_bytes(sector + count) > vhd->footer.curr_size) {
|
||||
fprintf(stderr, "sector %s past end of file\n",
|
||||
conv(hex, sector + count));
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
cur = sector + i;
|
||||
blk = (uint32_t)(cur / vhd->spb);
|
||||
lsec = cur % vhd->spb;
|
||||
offset = vhd->bat.bat[blk];
|
||||
|
||||
if (offset != DD_BLK_UNUSED) {
|
||||
offset += lsec + 1;
|
||||
offset = vhd_sectors_to_bytes(offset);
|
||||
}
|
||||
|
||||
printf("logical sector %s: ", conv(hex, cur));
|
||||
printf("block number: %s, ", conv(hex, blk));
|
||||
printf("sector offset: %s, ", conv(hex, lsec));
|
||||
printf("file offset: %s\n", (offset == DD_BLK_UNUSED ?
|
||||
"not allocated" : conv(hex, offset)));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
vhd_print_bat(vhd_context_t *vhd, uint64_t block, int count, int hex)
|
||||
{
|
||||
int i;
|
||||
uint64_t cur, offset;
|
||||
|
||||
if (check_block_range(vhd, block + count, hex))
|
||||
return -ERANGE;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
cur = block + i;
|
||||
offset = vhd->bat.bat[cur];
|
||||
|
||||
printf("block: %s: ", conv(hex, cur));
|
||||
printf("offset: %s\n",
|
||||
(offset == DD_BLK_UNUSED ? "not allocated" :
|
||||
conv(hex, vhd_sectors_to_bytes(offset))));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
write_full(int fd, void* buf, size_t count)
|
||||
{
|
||||
ssize_t num_written = 0;
|
||||
if (!buf) return;
|
||||
|
||||
|
||||
while(count > 0) {
|
||||
|
||||
num_written = write(fd, buf, count);
|
||||
if (num_written == -1) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
count -= num_written;
|
||||
buf = ((char *)buf) + num_written;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
vhd_print_bitmap(vhd_context_t *vhd, uint64_t block, int count, int hex)
|
||||
{
|
||||
char *buf;
|
||||
int i, err;
|
||||
uint64_t cur;
|
||||
|
||||
if (check_block_range(vhd, block + count, hex))
|
||||
return -ERANGE;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
cur = block + i;
|
||||
|
||||
if (vhd->bat.bat[cur] == DD_BLK_UNUSED) {
|
||||
printf("block %s not allocated\n", conv(hex, cur));
|
||||
continue;
|
||||
}
|
||||
|
||||
err = vhd_read_bitmap(vhd, (uint32_t)cur, &buf);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
write_full(STDOUT_FILENO, buf,
|
||||
(size_t)vhd_sectors_to_bytes(vhd->bm_secs));
|
||||
#ifdef _WIN32
|
||||
_aligned_free(buf);
|
||||
#else
|
||||
free(buf);
|
||||
#endif
|
||||
}
|
||||
|
||||
err = 0;
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
vhd_test_bitmap(vhd_context_t *vhd, uint64_t sector, int count, int hex)
|
||||
{
|
||||
char *buf;
|
||||
uint64_t cur;
|
||||
int i, err, bit;
|
||||
uint32_t blk, bm_blk, sec;
|
||||
|
||||
if (vhd_sectors_to_bytes(sector + count) > vhd->footer.curr_size) {
|
||||
printf("sector %s past end of file\n", conv(hex, sector));
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
bm_blk = -1;
|
||||
buf = NULL;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
cur = sector + i;
|
||||
blk = (uint32_t)(cur / vhd->spb);
|
||||
sec = cur % vhd->spb;
|
||||
|
||||
if (blk != bm_blk) {
|
||||
bm_blk = blk;
|
||||
free(buf);
|
||||
buf = NULL;
|
||||
|
||||
if (vhd->bat.bat[blk] != DD_BLK_UNUSED) {
|
||||
err = vhd_read_bitmap(vhd, blk, &buf);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (vhd->bat.bat[blk] == DD_BLK_UNUSED)
|
||||
bit = 0;
|
||||
else
|
||||
bit = vhd_bitmap_test(vhd, buf, blk);
|
||||
|
||||
printf("block %s: ", conv(hex, blk));
|
||||
printf("sec: %s: %d\n", conv(hex, sec), bit);
|
||||
}
|
||||
|
||||
err = 0;
|
||||
out:
|
||||
#ifdef _WIN32
|
||||
_aligned_free( buf );
|
||||
#else
|
||||
free( buf );
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
vhd_print_batmap(vhd_context_t *vhd)
|
||||
{
|
||||
int err;
|
||||
size_t size;
|
||||
|
||||
err = vhd_get_batmap(vhd);
|
||||
if (err) {
|
||||
printf("failed to read batmap: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
size = (uint32_t)vhd_sectors_to_bytes(vhd->batmap.header.batmap_size);
|
||||
write_full(STDOUT_FILENO, vhd->batmap.map, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
vhd_test_batmap(vhd_context_t *vhd, uint64_t block, int count, int hex)
|
||||
{
|
||||
int i, err;
|
||||
uint64_t cur;
|
||||
|
||||
if (check_block_range(vhd, block + count, hex))
|
||||
return -ERANGE;
|
||||
|
||||
err = vhd_get_batmap(vhd);
|
||||
if (err) {
|
||||
fprintf(stderr, "failed to get batmap\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
cur = block + i;
|
||||
fprintf(stderr, "batmap for block %s: %d\n", conv(hex, cur),
|
||||
vhd_batmap_test(vhd, &vhd->batmap, (uint32_t)cur));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
vhd_print_data(vhd_context_t *vhd, uint64_t block, int count, int hex)
|
||||
{
|
||||
char *buf;
|
||||
int i, err;
|
||||
uint64_t cur;
|
||||
|
||||
err = 0;
|
||||
|
||||
if (check_block_range(vhd, block + count, hex))
|
||||
return -ERANGE;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
cur = block + i;
|
||||
|
||||
if (vhd->bat.bat[cur] == DD_BLK_UNUSED) {
|
||||
printf("block %s not allocated\n", conv(hex, cur));
|
||||
continue;
|
||||
}
|
||||
|
||||
err = vhd_read_block(vhd, (uint32_t)cur, &buf);
|
||||
if (err)
|
||||
break;
|
||||
|
||||
write_full(STDOUT_FILENO, buf, vhd->header.block_size);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
vhd_read_data(vhd_context_t *vhd, uint64_t sec, int count, int hex)
|
||||
{
|
||||
char *buf;
|
||||
uint64_t cur;
|
||||
int err;
|
||||
size_t max, secs;
|
||||
|
||||
if (vhd_sectors_to_bytes(sec + count) > vhd->footer.curr_size)
|
||||
return -ERANGE;
|
||||
|
||||
max = MIN((size_t)vhd_sectors_to_bytes(count), VHD_BLOCK_SIZE);
|
||||
#ifdef _WIN32
|
||||
buf = _aligned_malloc( max, VHD_SECTOR_SIZE );
|
||||
if( buf == NULL )
|
||||
return -errno;
|
||||
#else
|
||||
err = posix_memalign((void **)&buf, VHD_SECTOR_SIZE, max);
|
||||
if (err)
|
||||
return -err;
|
||||
#endif
|
||||
|
||||
cur = sec;
|
||||
while (count) {
|
||||
secs = MIN((max >> VHD_SECTOR_SHIFT), (size_t)count);
|
||||
err = vhd_io_read(vhd, buf, cur, secs);
|
||||
if (err)
|
||||
break;
|
||||
|
||||
write_full(STDOUT_FILENO, buf, (size_t)vhd_sectors_to_bytes(secs));
|
||||
|
||||
cur += secs;
|
||||
count -= secs;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
_aligned_free( buf );
|
||||
#else
|
||||
free( buf );
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
static void vhd_print_brief(vhd_context_t *cvhd, char *name) {
|
||||
int err;
|
||||
size_t i, n, level = 0;
|
||||
vhd_parent_locator_t *loc;
|
||||
vhd_context_t *vhd;
|
||||
char uuid[39], time_str[26], *pname;
|
||||
|
||||
if( !vhd_type_dynamic(cvhd) ) {
|
||||
printf( "%s has no parent\n",
|
||||
cvhd->footer.type <= HD_TYPE_MAX?
|
||||
HD_TYPE_STR[cvhd->footer.type] :
|
||||
"Unknown disk type" );
|
||||
return;
|
||||
}
|
||||
|
||||
name = strdup( name );
|
||||
if( name == NULL )
|
||||
return;
|
||||
|
||||
vhd = malloc( sizeof( vhd_context_t ) );
|
||||
if( vhd == NULL )
|
||||
goto out;
|
||||
|
||||
memcpy( vhd, cvhd, sizeof( vhd_context_t ) );
|
||||
|
||||
pname = NULL;
|
||||
level = 0;
|
||||
|
||||
while( 1 ) {
|
||||
printf( "%s\n", name );
|
||||
free( name );
|
||||
name = NULL;
|
||||
|
||||
printf(" Disk type : %s\n",
|
||||
vhd->footer.type <= HD_TYPE_MAX ?
|
||||
HD_TYPE_STR[vhd->footer.type] : "Unknown");
|
||||
|
||||
if( vhd->footer.type != HD_TYPE_DIFF ) {
|
||||
blk_uuid_to_string(&vhd->footer.uuid, uuid, sizeof(uuid));
|
||||
printf(" UUID : %s\n", uuid);
|
||||
vhd_time_to_string(vhd->footer.timestamp, time_str);
|
||||
printf(" Timestamp : %s\n", time_str);
|
||||
break;
|
||||
}
|
||||
err = vhd_header_decode_parent(vhd, &vhd->header, &name);
|
||||
printf(" Parent name : %s\n",
|
||||
(err ? "failed to read name" : name));
|
||||
free(name);
|
||||
name = NULL;
|
||||
|
||||
blk_uuid_to_string(&vhd->header.prt_uuid, uuid, sizeof(uuid));
|
||||
printf(" Parent UUID : %s\n", uuid);
|
||||
|
||||
vhd_time_to_string(vhd->header.prt_ts, time_str);
|
||||
printf(" Parent timestamp : %s\n", time_str);
|
||||
|
||||
n = sizeof(vhd->header.loc) / sizeof(struct prt_loc);
|
||||
for (i = 0; i < n; i++) {
|
||||
loc = &vhd->header.loc[i];
|
||||
|
||||
if (loc->code == PLAT_CODE_NONE)
|
||||
continue;
|
||||
err = vhd_parent_locator_read( vhd, loc, &name );
|
||||
if( err ) {
|
||||
printf( "Failed to read parent locator %u", i );
|
||||
break;
|
||||
}
|
||||
|
||||
printf(" Parent location %4d: %s\n", i, name );
|
||||
|
||||
if( pname == NULL ) {
|
||||
err = vhd_find_parent( vhd, name, &pname );
|
||||
}
|
||||
free( name );
|
||||
name = NULL;
|
||||
}
|
||||
if( pname == NULL )
|
||||
break;
|
||||
printf( "\nParent is " );
|
||||
name = pname;
|
||||
pname = NULL;
|
||||
if( level != 0 )
|
||||
vhd_close(vhd);
|
||||
|
||||
err = vhd_open(vhd, name, VHD_OPEN_RDONLY | VHD_OPEN_IGNORE_DISABLED);
|
||||
if (err) {
|
||||
printf("unable to open: %d\n", err);
|
||||
break;
|
||||
}
|
||||
++level;
|
||||
}
|
||||
|
||||
out:
|
||||
if( level > 0 )
|
||||
vhd_close( vhd );
|
||||
free( vhd );
|
||||
free( pname );
|
||||
free( name );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
vhd_util_read(int argc, char **argv)
|
||||
{
|
||||
char *name;
|
||||
vhd_context_t vhd;
|
||||
int c, err, headers, brief, hex;
|
||||
uint64_t bat, bitmap, tbitmap, batmap, tbatmap, data, lsec, count, read;
|
||||
|
||||
err = 0;
|
||||
hex = 0;
|
||||
headers = 0;
|
||||
brief = 0;
|
||||
count = 1;
|
||||
bat = -1;
|
||||
bitmap = -1;
|
||||
tbitmap = -1;
|
||||
batmap = -1;
|
||||
tbatmap = -1;
|
||||
data = -1;
|
||||
lsec = -1;
|
||||
read = -1;
|
||||
name = NULL;
|
||||
|
||||
if (!argc || !argv)
|
||||
goto usage;
|
||||
|
||||
optind = 0;
|
||||
while ((c = getopt(argc, argv, "n:pPt:b:m:i:aj:d:c:r:xh")) != -1) {
|
||||
switch(c) {
|
||||
case 'n':
|
||||
name = optarg;
|
||||
break;
|
||||
case 'p':
|
||||
headers = 1;
|
||||
break;
|
||||
case 'P':
|
||||
brief = 1;
|
||||
break;
|
||||
case 't':
|
||||
lsec = strtoul(optarg, NULL, 10);
|
||||
break;
|
||||
case 'b':
|
||||
bat = strtoull(optarg, NULL, 10);
|
||||
break;
|
||||
case 'm':
|
||||
bitmap = strtoull(optarg, NULL, 10);
|
||||
break;
|
||||
case 'i':
|
||||
tbitmap = strtoul(optarg, NULL, 10);
|
||||
break;
|
||||
case 'a':
|
||||
batmap = 1;
|
||||
break;
|
||||
case 'j':
|
||||
tbatmap = strtoull(optarg, NULL, 10);
|
||||
break;
|
||||
case 'd':
|
||||
data = strtoull(optarg, NULL, 10);
|
||||
break;
|
||||
case 'r':
|
||||
read = strtoull(optarg, NULL, 10);
|
||||
break;
|
||||
case 'c':
|
||||
count = strtoul(optarg, NULL, 10);
|
||||
break;
|
||||
case 'x':
|
||||
hex = 1;
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
|
||||
if (!name || optind != argc)
|
||||
goto usage;
|
||||
|
||||
err = vhd_open(&vhd, name, VHD_OPEN_RDONLY | VHD_OPEN_IGNORE_DISABLED);
|
||||
if (err) {
|
||||
printf("Failed to open %s: %d\n", name, err);
|
||||
vhd_dump_headers(name, hex);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = vhd_get_bat(&vhd);
|
||||
if (err) {
|
||||
printf("Failed to get bat for %s: %d\n", name, err);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (headers)
|
||||
vhd_print_headers(&vhd, hex);
|
||||
|
||||
if (brief)
|
||||
vhd_print_brief(&vhd, name);
|
||||
|
||||
if (lsec != -1) {
|
||||
err = vhd_print_logical_to_physical(&vhd, lsec, (int)count, hex);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (bat != -1) {
|
||||
err = vhd_print_bat(&vhd, bat, (int)count, hex);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (bitmap != -1) {
|
||||
err = vhd_print_bitmap(&vhd, bitmap, (int)count, hex);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (tbitmap != -1) {
|
||||
err = vhd_test_bitmap(&vhd, tbitmap, (int)count, hex);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (batmap != -1) {
|
||||
err = vhd_print_batmap(&vhd);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (tbatmap != -1) {
|
||||
err = vhd_test_batmap(&vhd, tbatmap, (int)count, hex);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (data != -1) {
|
||||
err = vhd_print_data(&vhd, data, (int)count, hex);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (read != -1) {
|
||||
err = vhd_read_data(&vhd, read, (int)count, hex);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = 0;
|
||||
|
||||
out:
|
||||
vhd_close(&vhd);
|
||||
return err;
|
||||
|
||||
usage:
|
||||
printf("options:\n"
|
||||
"-h help\n"
|
||||
"-n name\n"
|
||||
"-p print VHD headers\n"
|
||||
"-P print parent summary\n"
|
||||
"-t sec translate logical sector to VHD location\n"
|
||||
"-b blk print bat entry\n"
|
||||
"-m blk print bitmap\n"
|
||||
"-i sec test bitmap for logical sector\n"
|
||||
"-a print batmap\n"
|
||||
"-j blk test batmap for block\n"
|
||||
"-d blk print data\n"
|
||||
"-c num num units\n"
|
||||
"-r sec read num sectors at sec\n"
|
||||
"-x print in hex\n");
|
||||
return EINVAL;
|
||||
}
|
||||
86
extracters/vhd-util/vhd-util-repair.c
Normal file
86
extracters/vhd-util/vhd-util-repair.c
Normal file
@@ -0,0 +1,86 @@
|
||||
/* Copyright (c) 2008, XenSource Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of XenSource Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "libvhd.h"
|
||||
|
||||
int
|
||||
vhd_util_repair(int argc, char **argv)
|
||||
{
|
||||
char *name;
|
||||
int err, c;
|
||||
off_t eof;
|
||||
vhd_context_t vhd;
|
||||
|
||||
name = NULL;
|
||||
|
||||
if (!argc || !argv)
|
||||
goto usage;
|
||||
|
||||
optind = 0;
|
||||
while ((c = getopt(argc, argv, "n:h")) != -1) {
|
||||
switch (c) {
|
||||
case 'n':
|
||||
name = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
|
||||
if (!name || optind != argc)
|
||||
goto usage;
|
||||
|
||||
err = vhd_open(&vhd, name, VHD_OPEN_RDWR);
|
||||
if (err) {
|
||||
printf("error opening %s: %d\n", name, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = vhd_end_of_data(&vhd, &eof);
|
||||
if (err) {
|
||||
printf("error finding end of data: %d\n", err);
|
||||
goto done;
|
||||
}
|
||||
|
||||
err = vhd_write_footer_at(&vhd, &vhd.footer, eof);
|
||||
|
||||
done:
|
||||
vhd_close(&vhd);
|
||||
return err;
|
||||
|
||||
usage:
|
||||
printf("options: <-n name> [-h help]\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
1199
extracters/vhd-util/vhd-util-resize.c
Normal file
1199
extracters/vhd-util/vhd-util-resize.c
Normal file
File diff suppressed because it is too large
Load Diff
108
extracters/vhd-util/vhd-util-revert.c
Normal file
108
extracters/vhd-util/vhd-util-revert.c
Normal file
@@ -0,0 +1,108 @@
|
||||
/* Copyright (c) 2008, XenSource Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of XenSource Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Altering operations:
|
||||
*
|
||||
* 1. Change the parent pointer to another file.
|
||||
* 2. Change the size of the file containing the VHD image. This does NOT
|
||||
* affect the VHD disk capacity, only the physical size of the file containing
|
||||
* the VHD. Naturally, it is not possible to set the file size to be less than
|
||||
* the what VHD utilizes.
|
||||
* The operation doesn't actually change the file size, but it writes the
|
||||
* footer in the right location such that resizing the file (manually, as a
|
||||
* separate step) will produce the correct results. If the new file size is
|
||||
* greater than the current file size, the file must first be expanded and then
|
||||
* altered with this operation. If the new size is smaller than the current
|
||||
* size, the VHD must first be altered with this operation and then the file
|
||||
* must be shrunk. Failing to resize the file will result in a corrupted VHD.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
/*#include <fcntl.h>*/
|
||||
#include <stdio.h>
|
||||
/*#include <stdlib.h> */
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "libvhd.h"
|
||||
#include "libvhd-journal.h"
|
||||
|
||||
int
|
||||
vhd_util_revert(int argc, char **argv)
|
||||
{
|
||||
char *name, *jname;
|
||||
vhd_journal_t journal;
|
||||
int c, err;
|
||||
|
||||
name = NULL;
|
||||
jname = NULL;
|
||||
|
||||
optind = 0;
|
||||
while ((c = getopt(argc, argv, "n:j:h")) != -1) {
|
||||
switch (c) {
|
||||
case 'n':
|
||||
name = optarg;
|
||||
break;
|
||||
case 'j':
|
||||
jname = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
|
||||
if (!name || !jname || argc != optind)
|
||||
goto usage;
|
||||
|
||||
libvhd_set_log_level(1);
|
||||
err = vhd_journal_open(&journal, name, jname);
|
||||
if (err) {
|
||||
printf("opening journal failed: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = vhd_journal_revert(&journal);
|
||||
if (err) {
|
||||
printf("reverting journal failed: %d\n", err);
|
||||
vhd_journal_close(&journal);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = vhd_journal_remove(&journal);
|
||||
if (err) {
|
||||
printf("removing journal failed: %d\n", err);
|
||||
vhd_journal_close(&journal);
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
printf("options: <-n name> <-j journal> [-h help]\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
1319
extracters/vhd-util/vhd-util-scan.c
Normal file
1319
extracters/vhd-util/vhd-util-scan.c
Normal file
File diff suppressed because it is too large
Load Diff
106
extracters/vhd-util/vhd-util-set-field.c
Normal file
106
extracters/vhd-util/vhd-util-set-field.c
Normal file
@@ -0,0 +1,106 @@
|
||||
/* Copyright (c) 2008, XenSource Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of XenSource Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "libvhd.h"
|
||||
|
||||
int
|
||||
vhd_util_set_field(int argc, char **argv)
|
||||
{
|
||||
long value;
|
||||
int err, c;
|
||||
vhd_context_t vhd;
|
||||
char *name, *field;
|
||||
|
||||
err = -EINVAL;
|
||||
value = 0;
|
||||
name = NULL;
|
||||
field = NULL;
|
||||
|
||||
if (!argc || !argv)
|
||||
goto usage;
|
||||
|
||||
optind = 0;
|
||||
while ((c = getopt(argc, argv, "n:f:v:h")) != -1) {
|
||||
switch (c) {
|
||||
case 'n':
|
||||
name = optarg;
|
||||
break;
|
||||
case 'f':
|
||||
field = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
err = 0;
|
||||
value = strtol(optarg, NULL, 10);
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
|
||||
if (!name || !field || optind != argc || err)
|
||||
goto usage;
|
||||
|
||||
if (strnlen(field, 25) >= 25) {
|
||||
printf("invalid field\n");
|
||||
goto usage;
|
||||
}
|
||||
|
||||
if (strcmp(field, "hidden")) {
|
||||
printf("invalid field %s\n", field);
|
||||
goto usage;
|
||||
}
|
||||
|
||||
if (value < 0 || value > 255) {
|
||||
printf("invalid value %ld\n", value);
|
||||
goto usage;
|
||||
}
|
||||
|
||||
err = vhd_open(&vhd, name, VHD_OPEN_RDWR);
|
||||
if (err) {
|
||||
printf("error opening %s: %d\n", name, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
vhd.footer.hidden = (char)value;
|
||||
|
||||
err = vhd_write_footer(&vhd, &vhd.footer);
|
||||
|
||||
vhd_close(&vhd);
|
||||
return err;
|
||||
|
||||
usage:
|
||||
printf("options: <-n name> <-f field> <-v value> [-h help]\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
225
extracters/vhd-util/vhd-util-snapshot.c
Normal file
225
extracters/vhd-util/vhd-util-snapshot.c
Normal file
@@ -0,0 +1,225 @@
|
||||
/* Copyright (c) 2008, XenSource Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of XenSource Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "libvhd.h"
|
||||
|
||||
static int
|
||||
vhd_util_find_snapshot_target(const char *name, char **result, int *parent_raw)
|
||||
{
|
||||
size_t i;
|
||||
int err;
|
||||
char *target;
|
||||
vhd_context_t vhd;
|
||||
|
||||
*parent_raw = 0;
|
||||
*result = NULL;
|
||||
|
||||
target = strdup(name);
|
||||
if (!target)
|
||||
return -ENOMEM;
|
||||
|
||||
for (;;) {
|
||||
err = vhd_open(&vhd, target, VHD_OPEN_RDONLY);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (vhd.footer.type != HD_TYPE_DIFF)
|
||||
goto out;
|
||||
|
||||
err = vhd_get_bat(&vhd);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
for (i = 0; i < vhd.bat.entries; i++)
|
||||
if (vhd.bat.bat[i] != DD_BLK_UNUSED)
|
||||
goto out;
|
||||
|
||||
free(target);
|
||||
err = vhd_parent_locator_get(&vhd, &target);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
if (vhd_parent_raw(&vhd)) {
|
||||
*parent_raw = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
vhd_close(&vhd);
|
||||
}
|
||||
|
||||
out:
|
||||
vhd_close(&vhd);
|
||||
if (err)
|
||||
free(target);
|
||||
else
|
||||
*result = target;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
vhd_util_check_depth(const char *name, int *depth)
|
||||
{
|
||||
int err;
|
||||
vhd_context_t vhd;
|
||||
|
||||
err = vhd_open(&vhd, name, VHD_OPEN_RDONLY);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = vhd_chain_depth(&vhd, depth);
|
||||
vhd_close(&vhd);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int
|
||||
vhd_util_snapshot(int argc, char **argv)
|
||||
{
|
||||
vhd_flag_creat_t flags;
|
||||
int c, err, prt_raw, limit;
|
||||
char *name, *pname, *ppath, *backing;
|
||||
uint64_t size;
|
||||
vhd_context_t vhd;
|
||||
|
||||
name = NULL;
|
||||
pname = NULL;
|
||||
ppath = NULL;
|
||||
backing = NULL;
|
||||
size = 0;
|
||||
flags = 0;
|
||||
limit = 0;
|
||||
|
||||
if (!argc || !argv) {
|
||||
err = -EINVAL;
|
||||
goto usage;
|
||||
}
|
||||
|
||||
optind = 0;
|
||||
while ((c = getopt(argc, argv, "n:p:l:mh")) != -1) {
|
||||
switch (c) {
|
||||
case 'n':
|
||||
name = optarg;
|
||||
break;
|
||||
case 'p':
|
||||
pname = optarg;
|
||||
break;
|
||||
case 'l':
|
||||
limit = strtol(optarg, NULL, 10);
|
||||
break;
|
||||
case 'm':
|
||||
vhd_flag_set(flags, VHD_FLAG_CREAT_PARENT_RAW);
|
||||
break;
|
||||
case 'h':
|
||||
err = 0;
|
||||
goto usage;
|
||||
default:
|
||||
err = -EINVAL;
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
|
||||
if (!name || !pname || optind != argc) {
|
||||
err = -EINVAL;
|
||||
goto usage;
|
||||
}
|
||||
|
||||
ppath = realpath(pname, NULL);
|
||||
if (!ppath)
|
||||
return -errno;
|
||||
#ifdef _WIN32
|
||||
ppath++;
|
||||
#endif
|
||||
if (vhd_flag_test(flags, VHD_FLAG_CREAT_PARENT_RAW)) {
|
||||
backing = strdup(ppath);
|
||||
if (!backing) {
|
||||
err = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
err = vhd_util_find_snapshot_target(ppath, &backing, &prt_raw);
|
||||
if (err) {
|
||||
backing = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* if the sizes of the parent chain are non-uniform, we need to
|
||||
* pick the right size: that of the supplied parent
|
||||
*/
|
||||
if (strcmp(ppath, backing)) {
|
||||
err = vhd_open(&vhd, ppath, VHD_OPEN_RDONLY);
|
||||
if (err)
|
||||
goto out;
|
||||
size = vhd.footer.curr_size;
|
||||
vhd_close(&vhd);
|
||||
}
|
||||
|
||||
if (prt_raw)
|
||||
vhd_flag_set(flags, VHD_FLAG_CREAT_PARENT_RAW);
|
||||
}
|
||||
|
||||
if (limit && !vhd_flag_test(flags, VHD_FLAG_CREAT_PARENT_RAW)) {
|
||||
int depth;
|
||||
|
||||
err = vhd_util_check_depth(backing, &depth);
|
||||
if (err)
|
||||
printf("error checking snapshot depth: %d\n", err);
|
||||
else if (depth + 1 > limit) {
|
||||
err = -ENOSPC;
|
||||
printf("snapshot depth exceeded: "
|
||||
"current depth: %d, limit: %d\n", depth, limit);
|
||||
}
|
||||
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = vhd_snapshot(name, size, pname, flags);
|
||||
|
||||
out:
|
||||
#ifdef _WIN32
|
||||
free( ppath - 1 );
|
||||
#else
|
||||
free(ppath);
|
||||
#endif
|
||||
free(backing);
|
||||
|
||||
return err;
|
||||
|
||||
usage:
|
||||
printf("options: <-n name> <-p parent name> [-l snapshot depth limit]"
|
||||
" [-m parent_is_raw] [-h help]\n");
|
||||
return err;
|
||||
}
|
||||
168
extracters/vhd-util/vhd-util.c
Normal file
168
extracters/vhd-util/vhd-util.c
Normal file
@@ -0,0 +1,168 @@
|
||||
/* Copyright (c) 2008, XenSource Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of XenSource Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "libvhd.h"
|
||||
#include "vhd-util.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#if 1
|
||||
#define DFPRINTF(_f, _a...) fprintf(stdout, _f , ##_a)
|
||||
#else
|
||||
#define DFPRINTF(_f, _a...) ((void)0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef int (*vhd_util_func_t) (int, char **);
|
||||
|
||||
struct command {
|
||||
char *name;
|
||||
vhd_util_func_t func;
|
||||
};
|
||||
|
||||
struct command commands[] = {
|
||||
{ .name = "create", .func = vhd_util_create },
|
||||
{ .name = "snapshot", .func = vhd_util_snapshot },
|
||||
{ .name = "query", .func = vhd_util_query },
|
||||
{ .name = "read", .func = vhd_util_read },
|
||||
{ .name = "set", .func = vhd_util_set_field },
|
||||
{ .name = "repair", .func = vhd_util_repair },
|
||||
{ .name = "resize", .func = vhd_util_resize },
|
||||
{ .name = "fill", .func = vhd_util_fill },
|
||||
{ .name = "coalesce", .func = vhd_util_coalesce },
|
||||
{ .name = "modify", .func = vhd_util_modify },
|
||||
#ifndef _WIN32
|
||||
{ .name = "scan", .func = vhd_util_scan },
|
||||
#endif
|
||||
{.name = "check", .func = vhd_util_check },
|
||||
{ .name = "revert", .func = vhd_util_revert },
|
||||
};
|
||||
|
||||
#define print_commands() \
|
||||
do { \
|
||||
int i, n; \
|
||||
n = sizeof(commands) / sizeof(struct command); \
|
||||
printf("COMMAND := { "); \
|
||||
printf("%s", commands[0].name); \
|
||||
for (i = 1; i < n; i++) \
|
||||
printf(" | %s", commands[i].name); \
|
||||
printf(" }\n"); \
|
||||
} while (0)
|
||||
|
||||
TEST_FAIL_EXTERN_VARS;
|
||||
|
||||
void
|
||||
help(void)
|
||||
{
|
||||
printf("usage: vhd-util COMMAND [OPTIONS]\n");
|
||||
print_commands();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
struct command *
|
||||
get_command(char *command)
|
||||
{
|
||||
int i, n;
|
||||
|
||||
if (strnlen(command, 25) >= 25)
|
||||
return NULL;
|
||||
|
||||
n = sizeof(commands) / sizeof (struct command);
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
if (!strcmp(command, commands[i].name))
|
||||
return &commands[i];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
char **cargv;
|
||||
struct command *cmd;
|
||||
int cargc, i, cnt, ret;
|
||||
|
||||
#ifdef CORE_DUMP
|
||||
#include <sys/resource.h>
|
||||
struct rlimit rlim;
|
||||
rlim.rlim_cur = RLIM_INFINITY;
|
||||
rlim.rlim_max = RLIM_INFINITY;
|
||||
if (setrlimit(RLIMIT_CORE, &rlim) < 0)
|
||||
fprintf(stderr, "setrlimit failed: %d\n", errno);
|
||||
#endif
|
||||
|
||||
ret = 0;
|
||||
|
||||
libvhd_set_log_level(-1);
|
||||
if (argc < 2)
|
||||
help();
|
||||
|
||||
cargc = argc - 1;
|
||||
cmd = get_command(argv[1]);
|
||||
if (!cmd) {
|
||||
fprintf(stderr, "invalid COMMAND %s\n", argv[1]);
|
||||
help();
|
||||
}
|
||||
|
||||
cargv = malloc(sizeof(char *) * cargc);
|
||||
if (!cargv)
|
||||
exit(ENOMEM);
|
||||
|
||||
cnt = 1;
|
||||
cargv[0] = cmd->name;
|
||||
for (i = 1; i < cargc; i++) {
|
||||
char *arg = argv[i + (argc - cargc)];
|
||||
|
||||
if (!strcmp(arg, "--debug")) {
|
||||
libvhd_set_log_level(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
cargv[cnt++] = arg;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_FAILURE_TESTING
|
||||
for (i = 0; i < NUM_FAIL_TESTS; i++) {
|
||||
TEST_FAIL[i] = 0;
|
||||
if (getenv(ENV_VAR_FAIL[i]))
|
||||
TEST_FAIL[i] = 1;
|
||||
}
|
||||
#endif /* ENABLE_FAILURE_TESTING */
|
||||
|
||||
ret = cmd->func(cnt, cargv);
|
||||
|
||||
free(cargv);
|
||||
|
||||
if( ret )
|
||||
printf( "Failed: (%d): %s\n", ret, strerror( (ret >0)? ret: -ret ) );
|
||||
|
||||
return (ret >= 0 ? ret : -ret);
|
||||
}
|
||||
BIN
extracters/vhd-util/vhd-util.exe
Executable file
BIN
extracters/vhd-util/vhd-util.exe
Executable file
Binary file not shown.
145
extracters/vhd-util/vhd-util.vcxproj
Normal file
145
extracters/vhd-util/vhd-util.vcxproj
Normal file
@@ -0,0 +1,145 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{CC5FB437-0C01-4ECF-A75F-10C37B607AC6}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(ProjectDir)$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(ProjectDir)$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>include;../libvhd/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<ForcedIncludeFiles>vhd-util-win32.h</ForcedIncludeFiles>
|
||||
<SDLCheck>false</SDLCheck>
|
||||
<PreprocessToFile>false</PreprocessToFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<AdditionalDependencies>../libvhd/Debug/libvhd.lib;Rpcrt4.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<AdditionalIncludeDirectories>include;../libvhd/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<SDLCheck>false</SDLCheck>
|
||||
<ForcedIncludeFiles>vhd-util-win32.h</ForcedIncludeFiles>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>../libvhd/Release/libvhd.lib;Rpcrt4.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>copy $(TargetPath) $(TargetDir)..\</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="atomicio.c" />
|
||||
<ClCompile Include="gnugetopt.c" />
|
||||
<ClCompile Include="libvhd-journal.c" />
|
||||
<ClCompile Include="vhd-util-check.c" />
|
||||
<ClCompile Include="vhd-util-coalesce.c" />
|
||||
<ClCompile Include="vhd-util-create.c" />
|
||||
<ClCompile Include="vhd-util-fill.c" />
|
||||
<ClCompile Include="vhd-util-modify.c" />
|
||||
<ClCompile Include="vhd-util-query.c" />
|
||||
<ClCompile Include="vhd-util-read.c" />
|
||||
<ClCompile Include="vhd-util-repair.c" />
|
||||
<ClCompile Include="vhd-util-resize.c" />
|
||||
<ClCompile Include="vhd-util-revert.c" />
|
||||
<ClCompile Include="vhd-util-set-field.c" />
|
||||
<ClCompile Include="vhd-util-snapshot.c" />
|
||||
<ClCompile Include="vhd-util.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\libvhd\include\libvhd.h" />
|
||||
<ClInclude Include="..\libvhd\include\relative-path.h" />
|
||||
<ClInclude Include="..\libvhd\include\vhd.h" />
|
||||
<ClInclude Include="include\atomicio.h" />
|
||||
<ClInclude Include="include\wingetopt.h" />
|
||||
<ClInclude Include="include\libvhd-journal.h" />
|
||||
<ClInclude Include="include\list.h" />
|
||||
<ClInclude Include="include\vhd-util.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
93
extracters/vhd-util/vhd-util.vcxproj.filters
Normal file
93
extracters/vhd-util/vhd-util.vcxproj.filters
Normal file
@@ -0,0 +1,93 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="include\atomicio.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\libvhd-journal.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\list.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\vhd-util.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libvhd\include\libvhd.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libvhd\include\vhd.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libvhd\include\relative-path.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\wingetopt.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="atomicio.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="libvhd-journal.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="vhd-util.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="vhd-util-check.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="vhd-util-coalesce.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="vhd-util-create.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="vhd-util-fill.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="vhd-util-modify.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="vhd-util-query.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="vhd-util-read.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="vhd-util-repair.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="vhd-util-resize.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="vhd-util-revert.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="vhd-util-set-field.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="vhd-util-snapshot.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="gnugetopt.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user