1 /*****************************************************************************/
5 /* Replacement for buggy Microsoft code */
9 /* (C) 2012, Ullrich von Bassewitz */
10 /* Roemerstrasse 52 */
11 /* D-70794 Filderstadt */
12 /* EMail: uz@cc65.org */
15 /* This software is provided 'as-is', without any expressed or implied */
16 /* warranty. In no event will the authors be held liable for any damages */
17 /* arising from the use of this software. */
19 /* Permission is granted to anyone to use this software for any purpose, */
20 /* including commercial applications, and to alter it and redistribute it */
21 /* freely, subject to the following restrictions: */
23 /* 1. The origin of this software must not be misrepresented; you must not */
24 /* claim that you wrote the original software. If you use this software */
25 /* in a product, an acknowledgment in the product documentation would be */
26 /* appreciated but is not required. */
27 /* 2. Altered source versions must be plainly marked as such, and must not */
28 /* be misrepresented as being the original software. */
29 /* 3. This notice may not be removed or altered from any source */
32 /*****************************************************************************/
36 /* This module works around bugs in the time conversion code supplied by
37 * Microsoft. The problem described here:
38 * http://www.codeproject.com/KB/datetime/dstbugs.aspx
39 * is also true when setting file times via utime(), so we need a
45 #if defined(__WATCOMC__) && defined(__NT__)
50 #if defined(__WATCOMC__) || defined(_MSC_VER) || defined(__MINGW32__)
51 /* The Windows compilers have the file in the wrong directory */
52 # include <sys/utime.h>
54 # include <sys/types.h> /* FreeBSD needs this */
65 /*****************************************************************************/
67 /*****************************************************************************/
75 static FILETIME* UnixTimeToFileTime (time_t T, FILETIME* FT)
76 /* Calculate a FILETIME value from a time_t. FILETIME contains a 64 bit
77 * value with point zero at 1600-01-01 00:00:00 and counting 100ns intervals.
78 * time_t is in seconds since 1970-01-01 00:00:00.
81 /* Offset between 1600-01-01 and the Epoch in seconds. Watcom C has no
82 * way to express a number > 32 bit (known to me) but is able to do
83 * calculations with 64 bit integers, so we need to do it this way.
85 static const ULARGE_INTEGER Offs = { 0xB6109100UL, 0x00000020UL };
87 V.QuadPart = ((unsigned __int64) T + Offs.QuadPart) * 10000000U;
88 FT->dwLowDateTime = V.LowPart;
89 FT->dwHighDateTime = V.HighPart;
95 int SetFileTimes (const char* Path, time_t T)
96 /* Set the time of last modification and the time of last access of a file to
97 * the given time T. This calls utime() for system where it works, and applies
98 * workarounds for all others (which in fact means "WINDOWS").
103 int Error = EACCES; /* Assume an error */
107 H = CreateFile (Path,
110 0, /* Security attributes */
113 0); /* Template file */
114 if (H != INVALID_HANDLE_VALUE) {
115 /* Set access and modification time */
116 UnixTimeToFileTime (T, &FileTime);
117 if (SetFileTime (H, 0, &FileTime, &FileTime)) {
122 /* Close the handle */
123 (void) CloseHandle (H);
126 /* Return the error code */
136 int SetFileTimes (const char* Path, time_t T)
137 /* Set the time of last modification and the time of last access of a file to
138 * the given time T. This calls utime() for system where it works, and applies
139 * workarounds for all others (which in fact means "WINDOWS").
144 /* Set access and modification time */
147 return utime (Path, &U);