From e94ba41122aa42b6c344529cc2a8f51072e8d9f0 Mon Sep 17 00:00:00 2001 From: Timothe Litt Date: Fri, 25 Mar 2016 13:01:59 -0400 Subject: [PATCH] Update ODS2 VHD library with DOS port Only reason they're separate is because ODS2 uses DOS line endings. --- extracters/ods2/vhd/libvhd.c | 148 +++++++++++++---------- extracters/ods2/vhd/libvhd.h | 180 +++++++++++++++------------- extracters/ods2/vhd/relative-path.c | 5 +- extracters/ods2/vhd/relative-path.h | 16 ++- 4 files changed, 203 insertions(+), 146 deletions(-) diff --git a/extracters/ods2/vhd/libvhd.c b/extracters/ods2/vhd/libvhd.c index 4af9a80..2780d78 100644 --- a/extracters/ods2/vhd/libvhd.c +++ b/extracters/ods2/vhd/libvhd.c @@ -45,7 +45,7 @@ #include #include #ifdef _WIN32 -#include +#include #include #define strdup _strdup #define open _open @@ -157,6 +157,7 @@ static void vhd_log_error( const char *func, const char *fmt, ... ) } #ifdef _WIN32 +LIBVHD_API char *dirname( char *path ) { static char buf[MAX_PATH + 1]; char *p, *d; @@ -193,6 +194,7 @@ char *dirname( char *path ) { *p = '\0'; return buf; } +LIBVHD_API char *basename( char *path ) { static char buf[MAX_PATH + 1]; char *p, *d; @@ -580,6 +582,7 @@ static size_t iconv( iconv_t cd, #define BIT_MASK 0x80 #ifdef ENABLE_FAILURE_TESTING +LIBVHD_API const char* ENV_VAR_FAIL[NUM_FAIL_TESTS] = { "VHD_UTIL_TEST_FAIL_REPARENT_BEGIN", "VHD_UTIL_TEST_FAIL_REPARENT_LOCATOR", @@ -589,6 +592,7 @@ const char* ENV_VAR_FAIL[NUM_FAIL_TESTS] = { "VHD_UTIL_TEST_FAIL_RESIZE_METADATA_MOVED", "VHD_UTIL_TEST_FAIL_RESIZE_END" }; +LIBVHD_API int TEST_FAIL[NUM_FAIL_TESTS]; #endif /* ENABLE_FAILURE_TESTING */ @@ -1261,7 +1265,7 @@ vhd_time_to_string(uint32_t timestamp, char *target) t2 = t1 + (time_t)timestamp; #ifdef _WIN32 t3 = (__time32_t)t2; - _ctime32_s( target, 27, &t3 ); + _ctime32_s( target, 26, &t3 ); #else ctime_r(&t2, target); #endif @@ -1835,7 +1839,7 @@ vhd_test_file_fixed(const char *file, int *is_block) int vhd_find_parent(vhd_context_t *ctx, const char *parent, char **_location) { - int err; + int err, isabs = 0, isrd = 0; char *location, *cpath, *cdir, *path; err = 0; @@ -1847,58 +1851,65 @@ vhd_find_parent(vhd_context_t *ctx, const char *parent, char **_location) if (!parent) return -EINVAL; - if (parent[0] == '/') { - int ok; #ifdef _WIN32 - int fd; - - if( (fd = _open( parent, _O_RDONLY | _O_BINARY )) != -1 ) { - _close( fd ); - ok = 1; - } else - ok = 0; -#else - ok = !access( parent, R_OK ); -#endif - if( ok) { - path = strdup( parent ); - if( !path ) - return -ENOMEM; - *_location = path; - return 0; + if( parent[0] == '/' ) + isabs = 1; + else { + const char *p; + for( p = parent; *p && *p != '/' && *p != ':'; p++ ) + ; + isabs = ( *p == ':' ); } + + if( isabs ) { + if( (isrd = _open( parent, _O_RDONLY | _O_BINARY )) == -1 ) + goto errout; + else { + _close( isrd ); + isrd = 1; + } + } +#else + if (parent[0] == '/') { + isabs = 1; + isrd = !access( parent, R_OK ); + } +#endif + if( isabs ) { + if( isrd ) { + path = strdup( parent ); + if( !path ) + return -ENOMEM; + *_location = path; + return 0; + } + goto errout; } /* check parent path relative to child's directory */ cpath = realpath(ctx->file, NULL); - if (!cpath) { - err = -errno; - goto out; - } + if (!cpath) + goto errout; #ifdef _WIN32 - cdir = dirname( cpath + 1 ); + cdir = dirname( cpath + 1 ); #else - cdir = dirname( cpath ); + cdir = dirname( cpath ); #endif if (asprintf(&location, "%s/%s", cdir, parent) == -1) { - err = -errno; location = NULL; - goto out; + goto errout; } - { - int ok; #ifdef _WIN32 - int fd; - - if( (fd = _open( location, _O_RDONLY | _O_BINARY )) != -1 ) { - _close( fd ); - ok = 1; - } else - ok = 0; + if( (isrd = _open( location, _O_RDONLY | _O_BINARY )) == -1 ) + isrd = 0; + else { + _close( isrd ); + isrd = 1; + } #else - ok = !access( location, R_OK ); + isrd = !access( location, R_OK ); #endif - if( ok ) { + if( isrd ) { path = realpath( location, NULL ); if( path ) { #ifdef _WIN32 @@ -1912,16 +1923,15 @@ vhd_find_parent(vhd_context_t *ctx, const char *parent, char **_location) return 0; } } - } - err = -errno; -out: +errout: + err = -errno; free(location); free(cpath); return err; } -static int +static int vhd_macx_encode_location(char *name, char **out, size_t *outlen) { iconv_t cd; @@ -1938,7 +1948,7 @@ vhd_macx_encode_location(char *name, char **out, size_t *outlen) len = strlen(name) + strlen("file://"); ibl = len; - obl = len; + obl = len * 2; urip = uri = malloc(ibl + 1); uri_utf8 = uri_utf8p = malloc(obl); @@ -1959,11 +1969,11 @@ vhd_macx_encode_location(char *name, char **out, size_t *outlen) (char **) #endif &urip, &ibl, &uri_utf8p, &obl) == (size_t)-1 || - ibl || obl) { + ibl) { err = (errno ? -errno : -EIO); goto out; } - + len = (size_t)(uri_utf8p - uri_utf8); ret = malloc(len); if (!ret) { err = -ENOMEM; @@ -2030,7 +2040,7 @@ vhd_w2u_encode_location(char *name, char **out, size_t *outlen) len = strlen(uri); ibl = len; - obl = len * 2; + obl = len * 4; urip = uri; uri_utf16 = uri_utf16p = malloc(obl); @@ -2054,12 +2064,12 @@ vhd_w2u_encode_location(char *name, char **out, size_t *outlen) (char **) #endif &urip, &ibl, &uri_utf16p, &obl) == (size_t)-1 || - ibl || obl) { + ibl) { err = (errno ? -errno : -EIO); goto out; } - len = len * 2; + len = (size_t)(uri_utf16p - uri_utf16); ret = malloc(len); if (!ret) { err = -ENOMEM; @@ -2123,15 +2133,17 @@ vhd_w2u_decode_location(const char *in, char *out, int len, char *utf_type) ibl = obl = len; cd = iconv_open("ASCII", utf_type); - if (cd == (iconv_t)-1) + if (cd == (iconv_t)-1) return NULL; if (iconv(cd, #ifdef __linux__ (char **) #endif - &in, &ibl, &out, &obl) == (size_t)-1 || ibl) - return NULL; + &in, &ibl, &out, &obl) == (size_t)-1 || ibl) { + iconv_close(cd); + return NULL; + } iconv_close(cd); *out = '\0'; @@ -2145,14 +2157,13 @@ vhd_w2u_decode_location(const char *in, char *out, int len, char *utf_type) if (strstr(name, "C:") == name || strstr(name, "c:") == name) name += strlen("c:"); - return strdup(name); } int vhd_header_decode_parent(vhd_context_t *ctx, vhd_header_t *header, char **buf) { - char *code, out[512]; + char *code, out[512+1]; if (vhd_creator_tapdisk(ctx) && ctx->footer.crtr_ver == VHD_VERSION(0, 1)) @@ -3289,7 +3300,7 @@ vhd_initialize_header(vhd_context_t *ctx, const char *parent_path, err = vhd_open(&parent, parent_path, VHD_OPEN_RDONLY); if (err) return err; - + ctx->header.prt_ts = vhd_time(stats.st_mtime); blk_uuid_copy(&ctx->header.prt_uuid, &parent.footer.uuid); if (!size) @@ -3347,7 +3358,7 @@ vhd_write_parent_locators(vhd_context_t *ctx, const char *parent) } int -vhd_change_parent(vhd_context_t *child, char *parent_path, int raw) +vhd_change_parent(vhd_context_t *child, char *parent_path, int flags) { int i, err; char *ppath; @@ -3360,7 +3371,9 @@ vhd_change_parent(vhd_context_t *child, char *parent_path, int raw) parent_path, child->file, errno)); return -errno; } - +#ifdef _WIN32 + ppath++; +#endif err = stat(ppath, &stats); if (err == -1) { err = -errno; @@ -3380,7 +3393,7 @@ vhd_change_parent(vhd_context_t *child, char *parent_path, int raw) } #endif - if (raw) { + if (flags & 1) { blk_uuid_clear(&child->header.prt_uuid); } else { err = vhd_open(&parent, ppath, VHD_OPEN_RDONLY); @@ -3389,7 +3402,18 @@ vhd_change_parent(vhd_context_t *child, char *parent_path, int raw) ppath, child->file, err)); goto out; } - blk_uuid_copy(&child->header.prt_uuid, &parent.footer.uuid); + /* Extension */ + if( flags & 2 ) { + if( blk_uuid_compare(&child->header.prt_uuid, + &parent.footer.uuid) != 0 ) { + VHDLOG((FN,"new parent %s for %s: parent UUID doesn't match child\n", + ppath, child->file)); + vhd_close(&parent); + err = -EINVAL; + goto out; + } + } else + blk_uuid_copy(&child->header.prt_uuid, &parent.footer.uuid); vhd_close(&parent); } @@ -3430,7 +3454,11 @@ vhd_change_parent(vhd_context_t *child, char *parent_path, int raw) err = 0; out: +#ifdef _WIN32 + free(ppath -1); +#else free(ppath); +#endif return err; } diff --git a/extracters/ods2/vhd/libvhd.h b/extracters/ods2/vhd/libvhd.h index ec93fbe..6f607f5 100644 --- a/extracters/ods2/vhd/libvhd.h +++ b/extracters/ods2/vhd/libvhd.h @@ -59,6 +59,16 @@ #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)) @@ -109,7 +119,9 @@ #define vhd_flag_test(word, flag) ((word) & (flag)) -#define ENABLE_FAILURE_TESTING +#ifndef _WIN32x +#define ENABLE_FAILURE_TESTING 1 +#endif #define FAIL_REPARENT_BEGIN 0 #define FAIL_REPARENT_LOCATOR 1 #define FAIL_REPARENT_END 2 @@ -123,9 +135,15 @@ #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 \ - extern const char* ENV_VAR_FAIL[]; \ - extern int TEST_FAIL[]; +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 @@ -238,108 +256,108 @@ vhd_parent_raw(vhd_context_t *ctx) return blk_uuid_is_nil(&ctx->header.prt_uuid); } -void libvhd_set_log_level(int); +LIBVHD_API void libvhd_set_log_level(int); -int vhd_test_file_fixed(const char *, int *); +LIBVHD_API 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); +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); -uint32_t vhd_checksum_footer(vhd_footer_t *); -uint32_t vhd_checksum_header(vhd_header_t *); -uint32_t vhd_checksum_batmap(vhd_batmap_t *); +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 *); -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 *); +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 *); -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); +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); -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); +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 */ -int vhd_snapshot(const char *snapshot, uint64_t bytes, const char *parent, +LIBVHD_API 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 *); +LIBVHD_API int vhd_hidden(vhd_context_t *, int *); +LIBVHD_API 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); +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); -int vhd_offset(vhd_context_t *, uint32_t, uint32_t *); +LIBVHD_API 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); +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); -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 *); +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 *); -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 *); +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 *); -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); +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); -int vhd_get_phys_size(vhd_context_t *, off_t *); -int vhd_set_phys_size(vhd_context_t *, off_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); -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); +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); -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 *, +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 *); -int vhd_header_decode_parent(vhd_context_t *, vhd_header_t *, char **); -int vhd_change_parent(vhd_context_t *, char *parent_path, int raw); +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); -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); +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); -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); +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); -int vhd_io_read(vhd_context_t *, char *, uint64_t, uint32_t); -int vhd_io_write(vhd_context_t *, char *, uint64_t, uint32_t); +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 diff --git a/extracters/ods2/vhd/relative-path.c b/extracters/ods2/vhd/relative-path.c index 38b8aa0..cc328b3 100644 --- a/extracters/ods2/vhd/relative-path.c +++ b/extracters/ods2/vhd/relative-path.c @@ -79,7 +79,7 @@ do { \ } while (0) #ifdef _WIN32 -char *realpath( const char *path, char *resolved ) { +LIBVHD_API char *realpath( const char *path, char *resolved ) { char *p; DWORD len; @@ -122,7 +122,7 @@ char *realpath( const char *path, char *resolved ) { } return resolved; } -int asprintf( char **result, const char *fmt, ... ) { +LIBVHD_API int asprintf( char **result, const char *fmt, ... ) { int len; va_list ap; char *np; @@ -314,6 +314,7 @@ node_offset(char *from, int offset) * return a relative path from @from to @to * result should be freed */ +LIBVHD_API char * relative_path_to(char *from, char *to, int *err) { diff --git a/extracters/ods2/vhd/relative-path.h b/extracters/ods2/vhd/relative-path.h index b6e1784..18ed134 100644 --- a/extracters/ods2/vhd/relative-path.h +++ b/extracters/ods2/vhd/relative-path.h @@ -35,15 +35,25 @@ #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 */ -char *relative_path_to(char *src, char *dest, int *err); +LIBVHD_API char *relative_path_to(char *src, char *dest, int *err); #ifdef _WIN32 -char *realpath( const char *path, char *resolved ); -int asprintf( char **result, const char *fmt, ... ); +LIBVHD_API char *realpath( const char *path, char *resolved ); +LIBVHD_API int asprintf( char **result, const char *fmt, ... ); #endif #endif