ntdll/kernel32: #35

Eric Pouech pouech-eric at wanadoo.fr
Tue Aug 19 14:30:41 CDT 2003


this patch removes the DOSFS_ specific time related conversion routine, 
and makes use of the ntdll equivalent.

A+
-- 
Eric Pouech
-------------- next part --------------
diff -u -N -r -x '*~' -x '.#*' -x CVS dlls/ntdll34/time.c dlls/ntdll/time.c
--- dlls/ntdll34/time.c	2003-08-19 18:34:08.000000000 +0200
+++ dlls/ntdll/time.c	2003-08-19 21:26:06.000000000 +0200
@@ -515,6 +515,9 @@
  */
 BOOLEAN WINAPI RtlTimeToSecondsSince1970( const LARGE_INTEGER *Time, LPDWORD Seconds )
 {
+    /* if needed, there used to be a version of his function without long long support
+     * in files/dos_fs.c
+     */
     ULONGLONG tmp = ((ULONGLONG)Time->s.HighPart << 32) | Time->s.LowPart;
     tmp = RtlLargeIntegerDivide( tmp, 10000000, NULL );
     tmp -= SECS_1601_TO_1970;
@@ -538,6 +541,9 @@
  */
 BOOLEAN WINAPI RtlTimeToSecondsSince1980( const LARGE_INTEGER *Time, LPDWORD Seconds )
 {
+    /* if needed, there used to be a version of his function without long long support
+     * in files/dos_fs.c
+     */
     ULONGLONG tmp = ((ULONGLONG)Time->s.HighPart << 32) | Time->s.LowPart;
     tmp = RtlLargeIntegerDivide( tmp, 10000000, NULL );
     tmp -= SECS_1601_TO_1980;
diff -u -N -r -x '*~' -x '.#*' -x CVS files34/dos_fs.c files/dos_fs.c
--- files34/dos_fs.c	2003-08-19 18:34:25.000000000 +0200
+++ files/dos_fs.c	2003-08-19 21:25:13.000000000 +0200
@@ -40,6 +40,8 @@
 # include <unistd.h>
 #endif
 
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
 #include "windef.h"
 #include "winerror.h"
 #include "wingdi.h"
@@ -2239,225 +2241,6 @@
 }
 
 /***********************************************************************
- *           DOSFS_UnixTimeToFileTime
- *
- * Convert a Unix time to FILETIME format.
- * The FILETIME structure is a 64-bit value representing the number of
- * 100-nanosecond intervals since January 1, 1601, 0:00.
- * 'remainder' is the nonnegative number of 100-ns intervals
- * corresponding to the time fraction smaller than 1 second that
- * couldn't be stored in the time_t value.
- */
-void DOSFS_UnixTimeToFileTime( time_t unix_time, FILETIME *filetime,
-                               DWORD remainder )
-{
-    /* NOTES:
-
-       CONSTANTS:
-       The time difference between 1 January 1601, 00:00:00 and
-       1 January 1970, 00:00:00 is 369 years, plus the leap years
-       from 1604 to 1968, excluding 1700, 1800, 1900.
-       This makes (1968 - 1600) / 4 - 3 = 89 leap days, and a total
-       of 134774 days.
-
-       Any day in that period had 24 * 60 * 60 = 86400 seconds.
-
-       The time difference is 134774 * 86400 * 10000000, which can be written
-       116444736000000000
-       27111902 * 2^32 + 3577643008
-       413 * 2^48 + 45534 * 2^32 + 54590 * 2^16 + 32768
-
-       If you find that these constants are buggy, please change them in all
-       instances in both conversion functions.
-
-       VERSIONS:
-       There are two versions, one of them uses long long variables and
-       is presumably faster but not ISO C. The other one uses standard C
-       data types and operations but relies on the assumption that negative
-       numbers are stored as 2's complement (-1 is 0xffff....). If this
-       assumption is violated, dates before 1970 will not convert correctly.
-       This should however work on any reasonable architecture where WINE
-       will run.
-
-       DETAILS:
-
-       Take care not to remove the casts. I have tested these functions
-       (in both versions) for a lot of numbers. I would be interested in
-       results on other compilers than GCC.
-
-       The operations have been designed to account for the possibility
-       of 64-bit time_t in future UNICES. Even the versions without
-       internal long long numbers will work if time_t only is 64 bit.
-       A 32-bit shift, which was necessary for that operation, turned out
-       not to work correctly in GCC, besides giving the warning. So I
-       used a double 16-bit shift instead. Numbers are in the ISO version
-       represented by three limbs, the most significant with 32 bit, the
-       other two with 16 bit each.
-
-       As the modulo-operator % is not well-defined for negative numbers,
-       negative divisors have been avoided in DOSFS_FileTimeToUnixTime.
-
-       There might be quicker ways to do this in C. Certainly so in
-       assembler.
-
-       Claus Fischer, fischer at iue.tuwien.ac.at
-       */
-
-#if SIZEOF_LONG_LONG >= 8
-#  define USE_LONG_LONG 1
-#else
-#  define USE_LONG_LONG 0
-#endif
-
-#if USE_LONG_LONG		/* gcc supports long long type */
-
-    long long int t = unix_time;
-    t *= 10000000;
-    t += 116444736000000000LL;
-    t += remainder;
-    filetime->dwLowDateTime  = (UINT)t;
-    filetime->dwHighDateTime = (UINT)(t >> 32);
-
-#else  /* ISO version */
-
-    UINT a0;			/* 16 bit, low    bits */
-    UINT a1;			/* 16 bit, medium bits */
-    UINT a2;			/* 32 bit, high   bits */
-
-    /* Copy the unix time to a2/a1/a0 */
-    a0 =  unix_time & 0xffff;
-    a1 = (unix_time >> 16) & 0xffff;
-    /* This is obsolete if unix_time is only 32 bits, but it does not hurt.
-       Do not replace this by >> 32, it gives a compiler warning and it does
-       not work. */
-    a2 = (unix_time >= 0 ? (unix_time >> 16) >> 16 :
-	  ~((~unix_time >> 16) >> 16));
-
-    /* Multiply a by 10000000 (a = a2/a1/a0)
-       Split the factor into 10000 * 1000 which are both less than 0xffff. */
-    a0 *= 10000;
-    a1 = a1 * 10000 + (a0 >> 16);
-    a2 = a2 * 10000 + (a1 >> 16);
-    a0 &= 0xffff;
-    a1 &= 0xffff;
-
-    a0 *= 1000;
-    a1 = a1 * 1000 + (a0 >> 16);
-    a2 = a2 * 1000 + (a1 >> 16);
-    a0 &= 0xffff;
-    a1 &= 0xffff;
-
-    /* Add the time difference and the remainder */
-    a0 += 32768 + (remainder & 0xffff);
-    a1 += 54590 + (remainder >> 16   ) + (a0 >> 16);
-    a2 += 27111902                     + (a1 >> 16);
-    a0 &= 0xffff;
-    a1 &= 0xffff;
-
-    /* Set filetime */
-    filetime->dwLowDateTime  = (a1 << 16) + a0;
-    filetime->dwHighDateTime = a2;
-#endif
-}
-
-
-/***********************************************************************
- *           DOSFS_FileTimeToUnixTime
- *
- * Convert a FILETIME format to Unix time.
- * If not NULL, 'remainder' contains the fractional part of the filetime,
- * in the range of [0..9999999] (even if time_t is negative).
- */
-time_t DOSFS_FileTimeToUnixTime( const FILETIME *filetime, DWORD *remainder )
-{
-    /* Read the comment in the function DOSFS_UnixTimeToFileTime. */
-#if USE_LONG_LONG
-
-    long long int t = filetime->dwHighDateTime;
-    t <<= 32;
-    t += (UINT)filetime->dwLowDateTime;
-    t -= 116444736000000000LL;
-    if (t < 0)
-    {
-	if (remainder) *remainder = 9999999 - (-t - 1) % 10000000;
-	return -1 - ((-t - 1) / 10000000);
-    }
-    else
-    {
-	if (remainder) *remainder = t % 10000000;
-	return t / 10000000;
-    }
-
-#else  /* ISO version */
-
-    UINT a0;			/* 16 bit, low    bits */
-    UINT a1;			/* 16 bit, medium bits */
-    UINT a2;			/* 32 bit, high   bits */
-    UINT r;			/* remainder of division */
-    unsigned int carry;		/* carry bit for subtraction */
-    int negative;		/* whether a represents a negative value */
-
-    /* Copy the time values to a2/a1/a0 */
-    a2 =  (UINT)filetime->dwHighDateTime;
-    a1 = ((UINT)filetime->dwLowDateTime ) >> 16;
-    a0 = ((UINT)filetime->dwLowDateTime ) & 0xffff;
-
-    /* Subtract the time difference */
-    if (a0 >= 32768           ) a0 -=             32768        , carry = 0;
-    else                        a0 += (1 << 16) - 32768        , carry = 1;
-
-    if (a1 >= 54590    + carry) a1 -=             54590 + carry, carry = 0;
-    else                        a1 += (1 << 16) - 54590 - carry, carry = 1;
-
-    a2 -= 27111902 + carry;
-
-    /* If a is negative, replace a by (-1-a) */
-    negative = (a2 >= ((UINT)1) << 31);
-    if (negative)
-    {
-	/* Set a to -a - 1 (a is a2/a1/a0) */
-	a0 = 0xffff - a0;
-	a1 = 0xffff - a1;
-	a2 = ~a2;
-    }
-
-    /* Divide a by 10000000 (a = a2/a1/a0), put the rest into r.
-       Split the divisor into 10000 * 1000 which are both less than 0xffff. */
-    a1 += (a2 % 10000) << 16;
-    a2 /=       10000;
-    a0 += (a1 % 10000) << 16;
-    a1 /=       10000;
-    r   =  a0 % 10000;
-    a0 /=       10000;
-
-    a1 += (a2 % 1000) << 16;
-    a2 /=       1000;
-    a0 += (a1 % 1000) << 16;
-    a1 /=       1000;
-    r  += (a0 % 1000) * 10000;
-    a0 /=       1000;
-
-    /* If a was negative, replace a by (-1-a) and r by (9999999 - r) */
-    if (negative)
-    {
-	/* Set a to -a - 1 (a is a2/a1/a0) */
-	a0 = 0xffff - a0;
-	a1 = 0xffff - a1;
-	a2 = ~a2;
-
-        r  = 9999999 - r;
-    }
-
-    if (remainder) *remainder = r;
-
-    /* Do not replace this by << 32, it gives a compiler warning and it does
-       not work. */
-    return ((((time_t)a2) << 16) << 16) + (a1 << 16) + a0;
-#endif
-}
-
-
-/***********************************************************************
  *           MulDiv   (KERNEL32.@)
  * RETURNS
  *	Result of multiplication and division
@@ -2545,8 +2328,16 @@
 BOOL WINAPI FileTimeToDosDateTime( const FILETIME *ft, LPWORD fatdate,
                                      LPWORD fattime )
 {
-    time_t unixtime = DOSFS_FileTimeToUnixTime( ft, NULL );
-    struct tm *tm = gmtime( &unixtime );
+    LARGE_INTEGER       li;
+    ULONG               t;
+    time_t              unixtime;
+    struct tm*          tm;
+
+    li.s.LowPart = ft->dwLowDateTime;
+    li.s.HighPart = ft->dwHighDateTime;
+    RtlTimeToSecondsSince1970( &li, &t );
+    unixtime = t;
+    tm = gmtime( &unixtime );
     if (fattime)
         *fattime = (tm->tm_hour << 11) + (tm->tm_min << 5) + (tm->tm_sec / 2);
     if (fatdate)
diff -u -N -r -x '*~' -x '.#*' -x CVS include34/file.h include/file.h
--- include34/file.h	2003-08-19 18:34:27.000000000 +0200
+++ include/file.h	2003-08-19 21:25:14.000000000 +0200
@@ -94,9 +94,6 @@
                              DOS_FULL_NAME *full_name, BOOL win32 );
 
 /* files/dos_fs.c */
-extern void DOSFS_UnixTimeToFileTime( time_t unixtime, LPFILETIME ft,
-                                      DWORD remainder );
-extern time_t DOSFS_FileTimeToUnixTime( const FILETIME *ft, DWORD *remainder );
 extern BOOL DOSFS_ToDosFCBFormat( LPCWSTR name, LPWSTR buffer );
 extern const DOS_DEVICE *DOSFS_GetDevice( LPCWSTR name );
 extern const DOS_DEVICE *DOSFS_GetDeviceByHandle( HANDLE hFile );


More information about the wine-patches mailing list