diff --git a/lib/file.c b/lib/file.c index 551bd55..f43d758 100644 --- a/lib/file.c +++ b/lib/file.c @@ -963,6 +963,30 @@ size_t unshield_file_size(Unshield* unshield, int index)/*{{{*/ return 0; }/*}}}*/ +/* This uses the ISO 8601 date format (except for milliseconds) */ +bool unshield_file_iso_date (Unshield* unshield, int index, char* buf, size_t size)/*{{{*/ +{ + FileDescriptor* fd = unshield_get_file_descriptor(unshield, index); + struct tm date; + + if (size < 32) + { + unshield_error("Buffer size %" SIZE_FORMAT " is too small", size); + return false; + } + + if (fd) + unshield_dos_to_tm(fd->dos_date, fd->dos_time, &date); + else + { + unshield_warning("Failed to get file descriptor %i", index); + memset(&date, 0, sizeof(date)); + } + + (void)strftime(buf, size, "%Y-%m-%d %H:%M:%S", &date); + return fd ? true : false; +}/*}}}*/ + bool unshield_file_save_raw(Unshield* unshield, int index, const char* filename) { /* XXX: Thou Shalt Not Cut & Paste... */ diff --git a/lib/helper.c b/lib/helper.c index 95327c5..7168758 100644 --- a/lib/helper.c +++ b/lib/helper.c @@ -268,4 +268,26 @@ const char* unshield_header_get_string(Header* header, uint32_t offset) return unshield_get_utf8_string(header, unshield_header_get_buffer(header, offset)); } +/** + Based on MIT Wine code and DosDateTimeToFileTime() MSDN documentation + */ +void unshield_dos_to_tm(uint16_t dos_date, uint16_t dos_time, struct tm* tm) +{ + memset(tm, 0, sizeof(*tm)); + + if (dos_date) + { + tm->tm_year = (dos_date >> 9) + 80; + tm->tm_mon = ((dos_date >> 5) & 0x0f) - 1; + tm->tm_mday = dos_date & 0x1f; + } + + if (dos_time) + { + tm->tm_hour = dos_time >> 11; + tm->tm_min = (dos_time >> 5) & 0x3f; + tm->tm_sec = (dos_time & 0x1f) * 2; + } +} + diff --git a/lib/internal.h b/lib/internal.h index f9d091d..3051bca 100644 --- a/lib/internal.h +++ b/lib/internal.h @@ -87,6 +87,8 @@ const char* unshield_header_get_string(Header* header, uint32_t offset); uint8_t* unshield_header_get_buffer(Header* header, uint32_t offset); char *unshield_get_last_path_separator(char *path); +void unshield_dos_to_tm(uint16_t dos_date, uint16_t dos_time, struct tm* tm); + static inline void* unshield_fopen(Unshield* unshield, const char *filename, const char *modes) { return unshield->io_callbacks->fopen(filename, modes, unshield->io_userdata); diff --git a/lib/libunshield.h b/lib/libunshield.h index 9ec349a..fbdc350 100644 --- a/lib/libunshield.h +++ b/lib/libunshield.h @@ -3,6 +3,7 @@ #include #include +#include #define UNSHIELD_LOG_LEVEL_LOWEST 0 @@ -108,6 +109,7 @@ UNSHIELD_API bool unshield_file_is_valid (Unshield* unshield, int in UNSHIELD_API bool unshield_file_save (Unshield* unshield, int index, const char* filename); UNSHIELD_API int unshield_file_directory (Unshield* unshield, int index); UNSHIELD_API size_t unshield_file_size (Unshield* unshield, int index); +UNSHIELD_API bool unshield_file_iso_date (Unshield* unshield, int index, char* buf, size_t size); /** For investigation of compressed data */ UNSHIELD_API bool unshield_file_save_raw(Unshield* unshield, int index, const char* filename); diff --git a/src/unshield.c b/src/unshield.c index 62b1baf..1793356 100644 --- a/src/unshield.c +++ b/src/unshield.c @@ -683,11 +683,14 @@ static int list_files_helper(Unshield* unshield, const char* prefix, int first, for (i = first; i <= last; i++) { char dirname[4096]; + char date[32]; if (unshield_file_is_valid(unshield, i) && should_process_file(unshield, i)) { valid_count++; + (void)unshield_file_iso_date(unshield, i, date, sizeof(date)); + if (prefix && prefix[0]) { strcpy(dirname, prefix); @@ -708,10 +711,11 @@ static int list_files_helper(Unshield* unshield, const char* prefix, int first, if (dirname[strlen(dirname)-1] != '\\') strcat(dirname, "\\"); - printf(" %8" SIZE_FORMAT " %s%s\n", + printf(" %8" SIZE_FORMAT " %s %s%s\n", unshield_file_size(unshield, i), + date, dirname, - unshield_file_name(unshield, i)); + unshield_file_name(unshield, i)); } } @@ -748,7 +752,7 @@ static bool do_action(Unshield* unshield, ActionHelper helper) } } - printf(" -------- -------\n %i files\n", count); + printf(" -------- ------------------- -------\n %i files\n", count); return true; }