From dadd2432f9f830c0664005ceff25e99738694d9f Mon Sep 17 00:00:00 2001 From: shermp <14854761+shermp@users.noreply.github.com> Date: Sat, 14 Nov 2020 13:46:54 +1300 Subject: [PATCH] Add get modified timestamp function --- src/minivhd.h | 3 ++- src/minivhd_util.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ src/minivhd_util.h | 23 +++++++++++++++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) diff --git a/src/minivhd.h b/src/minivhd.h index d18bc64..f617496 100644 --- a/src/minivhd.h +++ b/src/minivhd.h @@ -24,7 +24,8 @@ typedef enum MVHDError { MVHD_ERR_INVALID_SIZE, MVHD_ERR_INVALID_BLOCK_SIZE, MVHD_ERR_INVALID_PARAMS, - MVHD_ERR_CONV_SIZE + MVHD_ERR_CONV_SIZE, + MVHD_ERR_TIMESTAMP } MVHDError; typedef enum MVHDType { diff --git a/src/minivhd_util.c b/src/minivhd_util.c index 5e1475e..365890e 100644 --- a/src/minivhd_util.c +++ b/src/minivhd_util.c @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include "libxml2_encoding.h" #include "minivhd_internal.h" #include "minivhd_util.h" @@ -109,6 +111,15 @@ uint32_t vhd_calc_timestamp(void) return (uint32_t)vhd_time; } +uint32_t mvhd_epoch_to_vhd_ts(time_t ts) { + time_t start_time = MVHD_START_TS; + if (ts < start_time) { + return start_time; + } + double vhd_time = difftime(ts, start_time); + return (uint32_t)vhd_time; +} + time_t vhd_get_created_time(MVHDMeta *vhdm) { time_t vhd_time = (time_t)vhdm->footer.timestamp; @@ -273,4 +284,39 @@ uint32_t mvhd_crc32(const void* data, size_t n_bytes) { crc = table[(uint8_t)crc ^ ((uint8_t*)data)[i]] ^ crc >> 8; return crc; +} + +uint32_t mvhd_file_mod_timestamp(const char* path, int *err) { +#ifdef _WIN32 + struct _stat file_stat; + size_t path_len = strlen(path); + mvhd_utf16 new_path[260] = {0}; + int new_path_len = (sizeof new_path) - 2; + int path_res = UTF8ToUTF16LE((unsigned char*)new_path, &new_path_len, (const unsigned char*)path, (int*)&path_len); + if (path_res > 0) { + int stat_res = _wstat(new_path, &file_stat); + if (stat_res != 0) { + mvhd_errno = errno; + *err = MVHD_ERR_FILE; + return -1; + } + return mvhd_epoch_to_vhd_ts(file_stat.st_mtime); + } else { + if (path_res == -1) { + *err = MVHD_ERR_UTF_SIZE; + } else if (path_res == -2) { + *err = MVHD_ERR_UTF_TRANSCODING_FAILED; + } + return -1; + } +#else + struct stat file_stat; + int stat_res = stat(path, &file_stat); + if (stat_res != 0) { + mvhd_errno = errno; + *err = MVHD_ERR_FILE; + return -1; + } + return mvhd_epoch_to_vhd_ts(file_stat.st_mtime); +#endif } \ No newline at end of file diff --git a/src/minivhd_util.h b/src/minivhd_util.h index eabbf92..2e1755c 100644 --- a/src/minivhd_util.h +++ b/src/minivhd_util.h @@ -39,6 +39,16 @@ void mvhd_generate_uuid(uint8_t *uuid); */ uint32_t vhd_calc_timestamp(void); +/** + * \brief Convert an epoch timestamp to a VHD timestamp + * + * \param [in] ts epoch timestamp to convert. + * + * \return The adjusted timestamp, or 0 if the input timestamp is + * earlier that 1 Janurary 2000 + */ +uint32_t mvhd_epoch_to_vhd_ts(time_t ts); + /** * \brief Return the created time from a VHD image * @@ -109,4 +119,17 @@ int mvhd_fseeko64(FILE* stream, int64_t offset, int origin); * \return The CRC32 of the data buffer */ uint32_t mvhd_crc32(const void* data, size_t n_bytes); + +/** + * \brief Calculate the file modification timestamp. + * + * This function is primarily to help protect differencing VHD's + * + * \param [in] path the UTF-8 file path + * \param [out] err The error value, if an error occurrs + * + * \return The file modified timestamp, in VHD compatible timestamp, or -1 on error. + * if error, 'err' will be set. + */ +uint32_t mvhd_file_mod_timestamp(const char* path, int *err); #endif \ No newline at end of file