mirror of
https://github.com/open-simh/simtools.git
synced 2026-01-23 10:58:52 +00:00
Add XEN's libvhd
These comprise the vhd library from the XEN project. They are a subset of the XEN tools. From http://www.openfoundry.org/svn/xenids/xen-4.0.0/tools/blktap2/ This commit is the baseline as found in XEN. Subsequent commits will fix compile issues and allow compilation under Windows. The API will remain compatible with the shared library, which can also be used. (With these headers.)
This commit is contained in:
parent
5f00f5b509
commit
d7d2293838
130
extracters/ods2/vhd/blk_uuid.h
Normal file
130
extracters/ods2/vhd/blk_uuid.h
Normal file
@ -0,0 +1,130 @@
|
||||
/* 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 __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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#error "Please update blk_uuid.h for your OS"
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __BLKTAP2_UUID_H__ */
|
||||
3352
extracters/ods2/vhd/libvhd.c
Normal file
3352
extracters/ods2/vhd/libvhd.c
Normal file
File diff suppressed because it is too large
Load Diff
326
extracters/ods2/vhd/libvhd.h
Normal file
326
extracters/ods2/vhd/libvhd.h
Normal file
@ -0,0 +1,326 @@
|
||||
/* 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_LIB_H_
|
||||
#define _VHD_LIB_H_
|
||||
|
||||
#include <string.h>
|
||||
#if defined(__linux__)
|
||||
#include <endian.h>
|
||||
#include <byteswap.h>
|
||||
#elif defined(__NetBSD__)
|
||||
#include <sys/endian.h>
|
||||
#include <sys/bswap.h>
|
||||
#endif
|
||||
|
||||
#include "blk_uuid.h"
|
||||
#include "vhd.h"
|
||||
|
||||
#ifndef O_LARGEFILE
|
||||
#define O_LARGEFILE 0
|
||||
#endif
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
#if defined(__linux__)
|
||||
#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))
|
||||
|
||||
|
||||
#define ENABLE_FAILURE_TESTING
|
||||
#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); }
|
||||
#define TEST_FAIL_EXTERN_VARS \
|
||||
extern const char* ENV_VAR_FAIL[]; \
|
||||
extern int TEST_FAIL[];
|
||||
#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 ((bytes + (VHD_SECTOR_SIZE - 1)) >> VHD_SECTOR_SHIFT);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
secs_round_up_no_zero(uint64_t bytes)
|
||||
{
|
||||
return (secs_round_up(bytes) ? : 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 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);
|
||||
}
|
||||
|
||||
void libvhd_set_log_level(int);
|
||||
|
||||
int vhd_test_file_fixed(const char *, int *);
|
||||
|
||||
uint32_t vhd_time(time_t time);
|
||||
size_t vhd_time_to_string(uint32_t timestamp, char *target);
|
||||
uint32_t vhd_chs(uint64_t size);
|
||||
|
||||
uint32_t vhd_checksum_footer(vhd_footer_t *);
|
||||
uint32_t vhd_checksum_header(vhd_header_t *);
|
||||
uint32_t vhd_checksum_batmap(vhd_batmap_t *);
|
||||
|
||||
void vhd_footer_in(vhd_footer_t *);
|
||||
void vhd_footer_out(vhd_footer_t *);
|
||||
void vhd_header_in(vhd_header_t *);
|
||||
void vhd_header_out(vhd_header_t *);
|
||||
void vhd_bat_in(vhd_bat_t *);
|
||||
void vhd_bat_out(vhd_bat_t *);
|
||||
void vhd_batmap_header_in(vhd_batmap_t *);
|
||||
void vhd_batmap_header_out(vhd_batmap_t *);
|
||||
|
||||
int vhd_validate_footer(vhd_footer_t *footer);
|
||||
int vhd_validate_header(vhd_header_t *header);
|
||||
int vhd_validate_batmap_header(vhd_batmap_t *batmap);
|
||||
int vhd_validate_batmap(vhd_batmap_t *batmap);
|
||||
int vhd_validate_platform_code(uint32_t code);
|
||||
|
||||
int vhd_open(vhd_context_t *, const char *file, int flags);
|
||||
void vhd_close(vhd_context_t *);
|
||||
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 */
|
||||
int vhd_snapshot(const char *snapshot, uint64_t bytes, const char *parent,
|
||||
vhd_flag_creat_t);
|
||||
|
||||
int vhd_hidden(vhd_context_t *, int *);
|
||||
int vhd_chain_depth(vhd_context_t *, int *);
|
||||
|
||||
off_t vhd_position(vhd_context_t *);
|
||||
int vhd_seek(vhd_context_t *, off_t, int);
|
||||
int vhd_read(vhd_context_t *, void *, size_t);
|
||||
int vhd_write(vhd_context_t *, void *, size_t);
|
||||
|
||||
int vhd_offset(vhd_context_t *, uint32_t, uint32_t *);
|
||||
|
||||
int vhd_end_of_headers(vhd_context_t *ctx, off_t *off);
|
||||
int vhd_end_of_data(vhd_context_t *ctx, off_t *off);
|
||||
int vhd_batmap_header_offset(vhd_context_t *ctx, off_t *off);
|
||||
|
||||
int vhd_get_header(vhd_context_t *);
|
||||
int vhd_get_footer(vhd_context_t *);
|
||||
int vhd_get_bat(vhd_context_t *);
|
||||
int vhd_get_batmap(vhd_context_t *);
|
||||
|
||||
void vhd_put_header(vhd_context_t *);
|
||||
void vhd_put_footer(vhd_context_t *);
|
||||
void vhd_put_bat(vhd_context_t *);
|
||||
void vhd_put_batmap(vhd_context_t *);
|
||||
|
||||
int vhd_has_batmap(vhd_context_t *);
|
||||
int vhd_batmap_test(vhd_context_t *, vhd_batmap_t *, uint32_t);
|
||||
void vhd_batmap_set(vhd_context_t *, vhd_batmap_t *, uint32_t);
|
||||
void vhd_batmap_clear(vhd_context_t *, vhd_batmap_t *, uint32_t);
|
||||
|
||||
int vhd_get_phys_size(vhd_context_t *, off_t *);
|
||||
int vhd_set_phys_size(vhd_context_t *, off_t);
|
||||
|
||||
int vhd_bitmap_test(vhd_context_t *, char *, uint32_t);
|
||||
void vhd_bitmap_set(vhd_context_t *, char *, uint32_t);
|
||||
void vhd_bitmap_clear(vhd_context_t *, char *, uint32_t);
|
||||
|
||||
int vhd_parent_locator_count(vhd_context_t *);
|
||||
int vhd_parent_locator_get(vhd_context_t *, char **);
|
||||
int vhd_parent_locator_read(vhd_context_t *, vhd_parent_locator_t *, char **);
|
||||
int vhd_find_parent(vhd_context_t *, const char *, char **);
|
||||
int vhd_parent_locator_write_at(vhd_context_t *, const char *,
|
||||
off_t, uint32_t, size_t,
|
||||
vhd_parent_locator_t *);
|
||||
|
||||
int vhd_header_decode_parent(vhd_context_t *, vhd_header_t *, char **);
|
||||
int vhd_change_parent(vhd_context_t *, char *parent_path, int raw);
|
||||
|
||||
int vhd_read_footer(vhd_context_t *, vhd_footer_t *);
|
||||
int vhd_read_footer_at(vhd_context_t *, vhd_footer_t *, off_t);
|
||||
int vhd_read_footer_strict(vhd_context_t *, vhd_footer_t *);
|
||||
int vhd_read_header(vhd_context_t *, vhd_header_t *);
|
||||
int vhd_read_header_at(vhd_context_t *, vhd_header_t *, off_t);
|
||||
int vhd_read_bat(vhd_context_t *, vhd_bat_t *);
|
||||
int vhd_read_batmap(vhd_context_t *, vhd_batmap_t *);
|
||||
int vhd_read_bitmap(vhd_context_t *, uint32_t block, char **bufp);
|
||||
int vhd_read_block(vhd_context_t *, uint32_t block, char **bufp);
|
||||
|
||||
int vhd_write_footer(vhd_context_t *, vhd_footer_t *);
|
||||
int vhd_write_footer_at(vhd_context_t *, vhd_footer_t *, off_t);
|
||||
int vhd_write_header(vhd_context_t *, vhd_header_t *);
|
||||
int vhd_write_header_at(vhd_context_t *, vhd_header_t *, off_t);
|
||||
int vhd_write_bat(vhd_context_t *, vhd_bat_t *);
|
||||
int vhd_write_batmap(vhd_context_t *, vhd_batmap_t *);
|
||||
int vhd_write_bitmap(vhd_context_t *, uint32_t block, char *bitmap);
|
||||
int vhd_write_block(vhd_context_t *, uint32_t block, char *data);
|
||||
|
||||
int vhd_io_read(vhd_context_t *, char *, uint64_t, uint32_t);
|
||||
int vhd_io_write(vhd_context_t *, char *, uint64_t, uint32_t);
|
||||
|
||||
#endif
|
||||
299
extracters/ods2/vhd/relative-path.c
Normal file
299
extracters/ods2/vhd/relative-path.c
Normal file
@ -0,0 +1,299 @@
|
||||
/* 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 "relative-path.h"
|
||||
|
||||
#define sfree(ptr) \
|
||||
do { \
|
||||
free(ptr); \
|
||||
ptr = NULL; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* count number of tokens between DELIMETER characters
|
||||
*/
|
||||
static 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
|
||||
*/
|
||||
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("invalid input; max path length is %d\n",
|
||||
MAX_NAME_LEN);
|
||||
*err = -ENAMETOOLONG;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
to_absolute = realpath(to, NULL);
|
||||
if (!to_absolute) {
|
||||
EPRINTF("failed to get absolute path of %s\n", to);
|
||||
*err = -errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
from_absolute = realpath(from, NULL);
|
||||
if (!from_absolute) {
|
||||
EPRINTF("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("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("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("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("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("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;
|
||||
}
|
||||
43
extracters/ods2/vhd/relative-path.h
Normal file
43
extracters/ods2/vhd/relative-path.h
Normal file
@ -0,0 +1,43 @@
|
||||
/* 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 _RELATIVE_PATH_H_
|
||||
#define _RELATIVE_PATH_H_
|
||||
|
||||
#include <syslog.h>
|
||||
|
||||
#define DELIMITER '/'
|
||||
#define MAX_NAME_LEN 1000
|
||||
|
||||
#define EPRINTF(_f, _a...) syslog(LOG_ERR, "tap-err:%s: " _f, __func__, ##_a)
|
||||
|
||||
/*
|
||||
* returns a relative path from @src to @dest
|
||||
* result should be freed
|
||||
*/
|
||||
char *relative_path_to(char *src, char *dest, int *err);
|
||||
|
||||
#endif
|
||||
219
extracters/ods2/vhd/vhd.h
Normal file
219
extracters/ods2/vhd/vhd.h
Normal file
@ -0,0 +1,219 @@
|
||||
/* 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_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 ) */
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
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
|
||||
Loading…
x
Reference in New Issue
Block a user