16
|
1 /***********************************************************************
|
|
2 *
|
|
3 * Borrowed from WINE sources!! (http://www.winehq.com)
|
|
4 * Converts a Win32 FILETIME structure to a UNIX time_t value
|
|
5 */
|
|
6
|
|
7 /*** WARNING ****
|
|
8 * This file is not to be incluided in a Visual C++ Project
|
|
9 * It will make the whole project fail to compile
|
|
10 * There are functions in libpst.c to handle the dates
|
|
11 * Do not use this one
|
|
12 */
|
|
13
|
|
14 #include <time.h>
|
|
15 #include "common.h"
|
|
16 #include "timeconv.h"
|
|
17
|
|
18 time_t fileTimeToUnixTime( const FILETIME *filetime, DWORD *remainder );
|
|
19 char * fileTimeToAscii (const FILETIME *filetime);
|
|
20
|
|
21 char * fileTimeToAscii (const FILETIME *filetime) {
|
|
22 time_t t1;
|
|
23
|
|
24 t1 = fileTimeToUnixTime(filetime,0);
|
|
25 return ctime(&t1);
|
|
26 }
|
|
27
|
|
28 struct tm * fileTimeToStructTM (const FILETIME *filetime) {
|
|
29 time_t t1;
|
|
30 t1 = fileTimeToUnixTime(filetime, 0);
|
|
31 return gmtime(&t1);
|
|
32 }
|
|
33
|
|
34 /***********************************************************************
|
|
35 * DOSFS_FileTimeToUnixTime
|
|
36 *
|
|
37 * Convert a FILETIME format to Unix time.
|
|
38 * If not NULL, 'remainder' contains the fractional part of the filetime,
|
|
39 * in the range of [0..9999999] (even if time_t is negative).
|
|
40 */
|
|
41 time_t fileTimeToUnixTime( const FILETIME *filetime, DWORD *remainder )
|
|
42 {
|
|
43 /* Read the comment in the function DOSFS_UnixTimeToFileTime. */
|
|
44 #if USE_LONG_LONG
|
|
45
|
|
46 long long int t = filetime->dwHighDateTime;
|
|
47 t <<= 32;
|
|
48 t += (UINT32)filetime->dwLowDateTime;
|
|
49 t -= 116444736000000000LL;
|
|
50 if (t < 0)
|
|
51 {
|
|
52 if (remainder) *remainder = 9999999 - (-t - 1) % 10000000;
|
|
53 return -1 - ((-t - 1) / 10000000);
|
|
54 }
|
|
55 else
|
|
56 {
|
|
57 if (remainder) *remainder = t % 10000000;
|
|
58 return t / 10000000;
|
|
59 }
|
|
60
|
|
61 #else /* ISO version */
|
|
62
|
|
63 UINT32 a0; /* 16 bit, low bits */
|
|
64 UINT32 a1; /* 16 bit, medium bits */
|
|
65 UINT32 a2; /* 32 bit, high bits */
|
|
66 UINT32 r; /* remainder of division */
|
|
67 unsigned int carry; /* carry bit for subtraction */
|
|
68 int negative; /* whether a represents a negative value */
|
|
69
|
|
70 /* Copy the time values to a2/a1/a0 */
|
|
71 a2 = (UINT32)filetime->dwHighDateTime;
|
|
72 a1 = ((UINT32)filetime->dwLowDateTime ) >> 16;
|
|
73 a0 = ((UINT32)filetime->dwLowDateTime ) & 0xffff;
|
|
74
|
|
75 /* Subtract the time difference */
|
|
76 if (a0 >= 32768 ) a0 -= 32768 , carry = 0;
|
|
77 else a0 += (1 << 16) - 32768 , carry = 1;
|
|
78
|
|
79 if (a1 >= 54590 + carry) a1 -= 54590 + carry, carry = 0;
|
|
80 else a1 += (1 << 16) - 54590 - carry, carry = 1;
|
|
81
|
|
82 a2 -= 27111902 + carry;
|
|
83
|
|
84 /* If a is negative, replace a by (-1-a) */
|
|
85 negative = (a2 >= ((UINT32)1) << 31);
|
|
86 if (negative)
|
|
87 {
|
|
88 /* Set a to -a - 1 (a is a2/a1/a0) */
|
|
89 a0 = 0xffff - a0;
|
|
90 a1 = 0xffff - a1;
|
|
91 a2 = ~a2;
|
|
92 }
|
|
93
|
|
94 /* Divide a by 10000000 (a = a2/a1/a0), put the rest into r.
|
|
95 Split the divisor into 10000 * 1000 which are both less than 0xffff. */
|
|
96 a1 += (a2 % 10000) << 16;
|
|
97 a2 /= 10000;
|
|
98 a0 += (a1 % 10000) << 16;
|
|
99 a1 /= 10000;
|
|
100 r = a0 % 10000;
|
|
101 a0 /= 10000;
|
|
102
|
|
103 a1 += (a2 % 1000) << 16;
|
|
104 a2 /= 1000;
|
|
105 a0 += (a1 % 1000) << 16;
|
|
106 a1 /= 1000;
|
|
107 r += (a0 % 1000) * 10000;
|
|
108 a0 /= 1000;
|
|
109
|
|
110 /* If a was negative, replace a by (-1-a) and r by (9999999 - r) */
|
|
111 if (negative)
|
|
112 {
|
|
113 /* Set a to -a - 1 (a is a2/a1/a0) */
|
|
114 a0 = 0xffff - a0;
|
|
115 a1 = 0xffff - a1;
|
|
116 a2 = ~a2;
|
|
117
|
|
118 r = 9999999 - r;
|
|
119 }
|
|
120
|
|
121 if (remainder) *remainder = r;
|
|
122
|
|
123 /* Do not replace this by << 32, it gives a compiler warning and it does
|
|
124 not work. */
|
|
125 return ((((time_t)a2) << 16) << 16) + (a1 << 16) + a0;
|
|
126 #endif
|
|
127 }
|