mirror of
https://github.com/open-simh/simtools.git
synced 2026-01-24 19:32:06 +00:00
Preliminary port of libvhd to windows
This makes libvhd run on windows, with some minor tweaks on Unix. The latter make it possible to capture errors on a terminal rather than syslog. A bug was fixed where an error code wasn't properly negated on return. The 'absolute path" code now writes an absolute path. Many compiler warnings were dealt with; this code now compiles cleanly under MSVC as well as linux (gcc). The approach was to do as much mechanical substitution as possible to avoid introducing new bugs - even where some re-engineering would be profitable.
This commit is contained in:
parent
d7d2293838
commit
076dbe88b9
@ -24,6 +24,12 @@
|
||||
* 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__
|
||||
|
||||
@ -47,6 +53,7 @@ static inline void blk_uuid_generate(blk_uuid_t *uuid)
|
||||
|
||||
static inline void blk_uuid_to_string(blk_uuid_t *uuid, char *out, size_t size)
|
||||
{
|
||||
(void) size;
|
||||
uuid_unparse(uuid->uuid, out);
|
||||
}
|
||||
|
||||
@ -121,6 +128,69 @@ static inline int blk_uuid_compare(blk_uuid_t *uuid1, blk_uuid_t *uuid2)
|
||||
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"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -24,9 +24,17 @@
|
||||
* 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>
|
||||
@ -34,6 +42,14 @@
|
||||
#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"
|
||||
@ -44,7 +60,7 @@
|
||||
#endif
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
#if defined(__linux__)
|
||||
#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))
|
||||
@ -113,7 +129,7 @@
|
||||
#else
|
||||
#define TEST_FAIL_AT(point)
|
||||
#define TEST_FAIL_EXTERN_VARS
|
||||
#endif // ENABLE_FAILURE_TESTING
|
||||
#endif /* ENABLE_FAILURE_TESTING */
|
||||
|
||||
|
||||
static const char VHD_POISON_COOKIE[] = "v_poison";
|
||||
@ -156,13 +172,16 @@ struct vhd_context {
|
||||
static inline uint32_t
|
||||
secs_round_up(uint64_t bytes)
|
||||
{
|
||||
return ((bytes + (VHD_SECTOR_SIZE - 1)) >> VHD_SECTOR_SHIFT);
|
||||
return (uint32_t)((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);
|
||||
uint32_t result;
|
||||
|
||||
result = secs_round_up(bytes);
|
||||
return ( result? result : 1);
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
@ -206,7 +225,7 @@ vhd_parent_locator_size(vhd_parent_locator_t *loc)
|
||||
* but sometimes we find it in bytes
|
||||
*/
|
||||
if (loc->data_space < 512)
|
||||
return vhd_sectors_to_bytes(loc->data_space);
|
||||
return (size_t)vhd_sectors_to_bytes(loc->data_space);
|
||||
else if (loc->data_space % 512 == 0)
|
||||
return loc->data_space;
|
||||
else
|
||||
|
||||
@ -24,6 +24,17 @@
|
||||
* 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>
|
||||
@ -31,17 +42,112 @@
|
||||
|
||||
#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
|
||||
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;
|
||||
}
|
||||
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 DELIMETER characters
|
||||
* count number of tokens between DELIMITER characters
|
||||
*/
|
||||
static int
|
||||
count_nodes(char *path)
|
||||
|
||||
int count_nodes(char *path)
|
||||
{
|
||||
int i;
|
||||
char *tmp;
|
||||
@ -223,30 +329,30 @@ relative_path_to(char *from, char *to, int *err)
|
||||
|
||||
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);
|
||||
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("failed to get absolute path of %s\n", to);
|
||||
EPRINTF((FN,"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);
|
||||
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("invalid input; max path length is %d\n",
|
||||
MAX_NAME_LEN);
|
||||
EPRINTF((FN,"invalid input; max path length is %d\n",
|
||||
MAX_NAME_LEN));
|
||||
*err = -ENAMETOOLONG;
|
||||
goto out;
|
||||
}
|
||||
@ -257,8 +363,8 @@ relative_path_to(char *from, char *to, int *err)
|
||||
/* 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);
|
||||
EPRINTF((FN,"failed to count common nodes of %s and %s: %d\n",
|
||||
to_absolute, from_absolute, common));
|
||||
*err = common;
|
||||
goto out;
|
||||
}
|
||||
@ -266,8 +372,8 @@ relative_path_to(char *from, char *to, int *err)
|
||||
/* 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);
|
||||
EPRINTF((FN,"failed to allocate relative path for %s: %d\n",
|
||||
from_absolute, -ENOMEM));
|
||||
*err = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
@ -275,16 +381,16 @@ relative_path_to(char *from, char *to, int *err)
|
||||
/* 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);
|
||||
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("failed to construct final path %s%s: %d\n",
|
||||
up, common_target_path, -ENOMEM);
|
||||
EPRINTF((FN,"failed to construct final path %s%s: %d\n",
|
||||
up, common_target_path, -ENOMEM));
|
||||
relative_path = NULL;
|
||||
*err = -ENOMEM;
|
||||
goto out;
|
||||
@ -297,3 +403,39 @@ out:
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -24,20 +24,26 @@
|
||||
* 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_
|
||||
|
||||
#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);
|
||||
|
||||
#ifdef _WIN32
|
||||
char *realpath( const char *path, char *resolved );
|
||||
int asprintf( char **result, const char *fmt, ... );
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@ -24,6 +24,11 @@
|
||||
* 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__
|
||||
|
||||
@ -32,7 +37,7 @@
|
||||
typedef uint32_t u32;
|
||||
typedef uint64_t u64;
|
||||
|
||||
#define DEBUG 1
|
||||
/* #define DEBUG 1 */
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* General definitions. */
|
||||
@ -79,7 +84,8 @@ static const char HD_COOKIE[9] = "conectix";
|
||||
/* 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
|
||||
@ -106,6 +112,9 @@ static const char HD_COOKIE[9] = "conectix";
|
||||
#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 */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user