From d776afa35a25eb6f43abfd17105227efa27df6ab Mon Sep 17 00:00:00 2001 From: Dmitry Brant Date: Sat, 30 Jul 2016 14:14:56 -0400 Subject: [PATCH 1/3] Correctly set last-modified time on exported files in Windows. --- BasiliskII/src/Windows/extfs_windows.cpp | 8 ++++++++ BasiliskII/src/Windows/posix_emu.cpp | 25 ++++++++++++++++++++++++ BasiliskII/src/Windows/posix_emu.h | 8 ++++++++ 3 files changed, 41 insertions(+) diff --git a/BasiliskII/src/Windows/extfs_windows.cpp b/BasiliskII/src/Windows/extfs_windows.cpp index f2b8a372..76538129 100755 --- a/BasiliskII/src/Windows/extfs_windows.cpp +++ b/BasiliskII/src/Windows/extfs_windows.cpp @@ -269,6 +269,14 @@ void get_finfo(const char *path, uint32 finfo, uint32 fxinfo, bool is_dir) void set_finfo(const char *path, uint32 finfo, uint32 fxinfo, bool is_dir) { + struct my_utimbuf times; + times.actime = MacTimeToTime(ReadMacInt32(finfo - ioFlFndrInfo + ioFlCrDat)); + times.modtime = MacTimeToTime(ReadMacInt32(finfo - ioFlFndrInfo + ioFlMdDat)); + + if (utime(path, ×) < 0) { + D(bug("utime failed on %s, error %d\n", path, GetLastError())); + } + // Open Finder info file int fd = open_finf(path, O_RDWR); if (fd < 0) diff --git a/BasiliskII/src/Windows/posix_emu.cpp b/BasiliskII/src/Windows/posix_emu.cpp index 518a526f..26b99939 100755 --- a/BasiliskII/src/Windows/posix_emu.cpp +++ b/BasiliskII/src/Windows/posix_emu.cpp @@ -1123,3 +1123,28 @@ int my_write( int fd, const void *buffer, unsigned int count ) D(bug("write(%ld,%08x,%ld) = %d\n", fd, buffer, count, result)); return result; } + +FILETIME getFileTime(time_t time) { + FILETIME ft; + unsigned long long result = 11644473600LL; + result += time; + result *= 10000000LL; + ft.dwHighDateTime = (result >> 32); + ft.dwLowDateTime = (result & 0xFFFFFFFF); + return ft; +} + +int my_utime( const char *path, struct my_utimbuf * my_times ) +{ + auto tpath = tstr(path); + LPCTSTR p = MRP(tpath.get()); + HANDLE f = CreateFile(p, FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (f != INVALID_HANDLE_VALUE) { + FILETIME crTime = getFileTime(my_times->actime); + FILETIME modTime = getFileTime(my_times->modtime); + SetFileTime(f, &crTime, NULL, &modTime); + CloseHandle(f); + return 0; + } + return -1; +} diff --git a/BasiliskII/src/Windows/posix_emu.h b/BasiliskII/src/Windows/posix_emu.h index f5077558..730d63df 100755 --- a/BasiliskII/src/Windows/posix_emu.h +++ b/BasiliskII/src/Windows/posix_emu.h @@ -73,6 +73,7 @@ int my_read( int fd, void *, unsigned int); int my_write( int fd, const void *, unsigned int); int my_chsize( int fd, unsigned int size ); int my_locking( int fd, int mode, long nbytes ); +int my_utime( const char *path, struct my_utimbuf * ); extern int my_errno; @@ -92,6 +93,7 @@ extern int my_errno; #define write my_write #define ftruncate my_chsize #define locking my_locking +#define utime my_utime #undef errno #define errno my_errno @@ -116,6 +118,12 @@ struct my_stat { time_t st_ctime; }; +struct my_utimbuf +{ + time_t actime; // access time + time_t modtime; // modification time +}; + // Your compiler may have different "struct stat" -> edit "struct my_stat" #define validate_stat_struct ( sizeof(struct my_stat) == sizeof(struct stat) ) From 72ac1218f05f97bf283d2d0791b0558138bb794c Mon Sep 17 00:00:00 2001 From: Dmitry Brant Date: Sat, 30 Jul 2016 14:14:56 -0400 Subject: [PATCH 2/3] Correctly set last-modified time on exported files in Windows. --- BasiliskII/src/Windows/extfs_windows.cpp | 8 ++++++++ BasiliskII/src/Windows/posix_emu.cpp | 25 ++++++++++++++++++++++++ BasiliskII/src/Windows/posix_emu.h | 8 ++++++++ BasiliskII/src/macos_util.cpp | 2 +- 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/BasiliskII/src/Windows/extfs_windows.cpp b/BasiliskII/src/Windows/extfs_windows.cpp index f2b8a372..76538129 100755 --- a/BasiliskII/src/Windows/extfs_windows.cpp +++ b/BasiliskII/src/Windows/extfs_windows.cpp @@ -269,6 +269,14 @@ void get_finfo(const char *path, uint32 finfo, uint32 fxinfo, bool is_dir) void set_finfo(const char *path, uint32 finfo, uint32 fxinfo, bool is_dir) { + struct my_utimbuf times; + times.actime = MacTimeToTime(ReadMacInt32(finfo - ioFlFndrInfo + ioFlCrDat)); + times.modtime = MacTimeToTime(ReadMacInt32(finfo - ioFlFndrInfo + ioFlMdDat)); + + if (utime(path, ×) < 0) { + D(bug("utime failed on %s, error %d\n", path, GetLastError())); + } + // Open Finder info file int fd = open_finf(path, O_RDWR); if (fd < 0) diff --git a/BasiliskII/src/Windows/posix_emu.cpp b/BasiliskII/src/Windows/posix_emu.cpp index 518a526f..26b99939 100755 --- a/BasiliskII/src/Windows/posix_emu.cpp +++ b/BasiliskII/src/Windows/posix_emu.cpp @@ -1123,3 +1123,28 @@ int my_write( int fd, const void *buffer, unsigned int count ) D(bug("write(%ld,%08x,%ld) = %d\n", fd, buffer, count, result)); return result; } + +FILETIME getFileTime(time_t time) { + FILETIME ft; + unsigned long long result = 11644473600LL; + result += time; + result *= 10000000LL; + ft.dwHighDateTime = (result >> 32); + ft.dwLowDateTime = (result & 0xFFFFFFFF); + return ft; +} + +int my_utime( const char *path, struct my_utimbuf * my_times ) +{ + auto tpath = tstr(path); + LPCTSTR p = MRP(tpath.get()); + HANDLE f = CreateFile(p, FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (f != INVALID_HANDLE_VALUE) { + FILETIME crTime = getFileTime(my_times->actime); + FILETIME modTime = getFileTime(my_times->modtime); + SetFileTime(f, &crTime, NULL, &modTime); + CloseHandle(f); + return 0; + } + return -1; +} diff --git a/BasiliskII/src/Windows/posix_emu.h b/BasiliskII/src/Windows/posix_emu.h index f5077558..730d63df 100755 --- a/BasiliskII/src/Windows/posix_emu.h +++ b/BasiliskII/src/Windows/posix_emu.h @@ -73,6 +73,7 @@ int my_read( int fd, void *, unsigned int); int my_write( int fd, const void *, unsigned int); int my_chsize( int fd, unsigned int size ); int my_locking( int fd, int mode, long nbytes ); +int my_utime( const char *path, struct my_utimbuf * ); extern int my_errno; @@ -92,6 +93,7 @@ extern int my_errno; #define write my_write #define ftruncate my_chsize #define locking my_locking +#define utime my_utime #undef errno #define errno my_errno @@ -116,6 +118,12 @@ struct my_stat { time_t st_ctime; }; +struct my_utimbuf +{ + time_t actime; // access time + time_t modtime; // modification time +}; + // Your compiler may have different "struct stat" -> edit "struct my_stat" #define validate_stat_struct ( sizeof(struct my_stat) == sizeof(struct stat) ) diff --git a/BasiliskII/src/macos_util.cpp b/BasiliskII/src/macos_util.cpp index 9001d472..6de3877f 100644 --- a/BasiliskII/src/macos_util.cpp +++ b/BasiliskII/src/macos_util.cpp @@ -151,6 +151,6 @@ uint32 TimeToMacTime(time_t t) time_t MacTimeToTime(uint32 t) { - // simply subtract number of seconds between 1.1.1094 and 1.1.1970 + // simply subtract number of seconds between 1.1.1904 and 1.1.1970 return t - 2082826800; } From 6ac8f16efbd5aea3efae4f559bb4dc0e8f981367 Mon Sep 17 00:00:00 2001 From: Dmitry Brant Date: Tue, 2 Aug 2016 09:02:40 -0400 Subject: [PATCH 3/3] Improve naming consistency. --- BasiliskII/src/Windows/posix_emu.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/BasiliskII/src/Windows/posix_emu.cpp b/BasiliskII/src/Windows/posix_emu.cpp index 26b99939..8d671abc 100755 --- a/BasiliskII/src/Windows/posix_emu.cpp +++ b/BasiliskII/src/Windows/posix_emu.cpp @@ -1124,7 +1124,7 @@ int my_write( int fd, const void *buffer, unsigned int count ) return result; } -FILETIME getFileTime(time_t time) { +static FILETIME get_file_time(time_t time) { FILETIME ft; unsigned long long result = 11644473600LL; result += time; @@ -1140,8 +1140,8 @@ int my_utime( const char *path, struct my_utimbuf * my_times ) LPCTSTR p = MRP(tpath.get()); HANDLE f = CreateFile(p, FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (f != INVALID_HANDLE_VALUE) { - FILETIME crTime = getFileTime(my_times->actime); - FILETIME modTime = getFileTime(my_times->modtime); + FILETIME crTime = get_file_time(my_times->actime); + FILETIME modTime = get_file_time(my_times->modtime); SetFileTime(f, &crTime, NULL, &modTime); CloseHandle(f); return 0;