Win32OperatingSystem.st
branchjv
changeset 17757 73caeb68bf1f
parent 17754 5322906cdb6a
child 17761 b0e5971141bc
--- a/Win32OperatingSystem.st	Sun Mar 21 19:37:43 2010 +0000
+++ b/Win32OperatingSystem.st	Thu Apr 08 18:25:02 2010 +0100
@@ -480,48 +480,48 @@
     tv.tv_usec = 0;
 
     if (readMode) {
-	n = select (sock + 1, & fds, NULL, NULL, & tv);
+        n = select (sock + 1, & fds, NULL, NULL, & tv);
     } else {
-	n = select (sock + 1, NULL, & fds, NULL, & tv);
+        n = select (sock + 1, NULL, & fds, NULL, & tv);
     }
 
     if (n == 0) {
-	return (0);
+        return (0);
     }
 
     if (n > 0) {
-	return ((FD_ISSET (sock, & fds)) ? 1 : 0);
+        return ((FD_ISSET (sock, & fds)) ? 1 : 0);
     }
 
     winErrNo = WSAGetLastError();
     switch (winErrNo) {
-	case WSAENOTSOCK:
-	    if (readMode) {
-
-		DWORD  w = 0;
-		HANDLE h = (HANDLE) _get_osfhandle (aFD);
-
-		if (PeekNamedPipe (h, 0, 0, 0, & w, 0)) {
-		    if( !__isWinNT || w > 0 )
-			return (1);
-
-		    return (0);
-		}
+        case WSAENOTSOCK:
+            if (readMode) {
+
+                DWORD  w = 0;
+                HANDLE h = (HANDLE) _get_osfhandle (aFD);
+
+                if (PeekNamedPipe (h, 0, 0, 0, & w, 0)) {
+                    if( !__isWinNT || w > 0 )
+                        return (1);
+
+                    return (0);
+                }
 #if 0
-		console_fprintf(stderr, "_canAccessIOWithoutBlocking non Socket\n");
-#endif
-		return (-1);
-	    }
-	    /* in writeMode we return allways true for none-sockets */
-	    return (1);
-
-	case WSAEINPROGRESS:
-	case WSAEWOULDBLOCK:
-	    return (0);
-
-	default:
-	    console_fprintf(stderr, "_canAccessIOWithoutBlocking -> %d (0x%x)\n", winErrNo, winErrNo);
-	    return (-1);
+                console_fprintf(stderr, "_canAccessIOWithoutBlocking non Socket\n");
+#endif
+                return (-1);
+            }
+            /* in writeMode we return allways true for none-sockets */
+            return (1);
+
+        case WSAEINPROGRESS:
+        case WSAEWOULDBLOCK:
+            return (0);
+
+        default:
+            console_fprintf(stderr, "_canAccessIOWithoutBlocking -> %d (0x%x)\n", winErrNo, winErrNo);
+            return (-1);
     }
 
     /* not reached */
@@ -543,7 +543,7 @@
     FARPROC entry;
 
     if (*pLibHandle == NULL) {
-	*pLibHandle = LoadLibrary(libraryName);
+        *pLibHandle = LoadLibrary(libraryName);
     }
     entry = GetProcAddress(*pLibHandle, functionName);
     return entry;
@@ -575,6 +575,24 @@
     return __get_functionAddress(&libHandle, "ole32.DLL", functionName);
 }
 
+void
+TimetToFileTime( time_t t, LPFILETIME pft )
+{
+    LONGLONG ll = Int32x32To64(t, 10000000) + 116444736000000000;
+    pft->dwLowDateTime = (DWORD) ll;
+    pft->dwHighDateTime = ll >>32;
+}
+
+OBJ
+FileTimeToOsTime(LPFILETIME pft)
+{
+    LONGLONG lTime = ((LONGLONG)pft->dwHighDateTime << 32) + pft->dwLowDateTime;
+    lTime = (lTime / 10000) - 11644473600000;
+
+    return(__MKLARGEINT64(1, (unsigned INT)(lTime & 0xFFFFFFFF), (unsigned INT)(lTime >> 32)));
+}
+
+
 %}
 ! !
 
@@ -5302,9 +5320,7 @@
 
     |info type mode uid gid size id
      atime mtime ctime
-     aYr aMon aDay aHr aMin aSec aMS
-     mYr mMon mDay mHr mMin mSec mMS
-     cYr cMon cDay cHr cMin cSec cMS
+     aOsTime mOsTime cOsTime
      fileName alternativeName|
 
 %{
@@ -5312,10 +5328,6 @@
     int ret;
     wchar_t alternativeFileNameBuffer[15];
     wchar_t fileNameBuffer[MAX_PATH+1];
-    FILETIME tempFileTime;
-    SYSTEMTIME creationTime;
-    SYSTEMTIME accessTime;
-    SYSTEMTIME modificationTime;
     int modeBits = 0;
     WIN32_FILE_ATTRIBUTE_DATA fileAttributeData;
     unsigned INT ino;
@@ -5395,41 +5407,9 @@
 
         mode = __mkSmallInteger(modeBits);
 
-        /*
-         * sigh - convert from stupid time to useful time
-         */
-        FileTimeToLocalFileTime(&fileAttributeData.ftCreationTime, &tempFileTime);
-        FileTimeToSystemTime(&tempFileTime, &creationTime);
-
-        FileTimeToLocalFileTime(&fileAttributeData.ftLastAccessTime, &tempFileTime);
-        FileTimeToSystemTime(&tempFileTime, &accessTime);
-
-        FileTimeToLocalFileTime(&fileAttributeData.ftLastWriteTime, &tempFileTime);
-        FileTimeToSystemTime(&tempFileTime, &modificationTime);
-
-        aYr  = __mkSmallInteger(accessTime.wYear);
-        aMon = __mkSmallInteger(accessTime.wMonth);
-        aDay = __mkSmallInteger(accessTime.wDay);
-        aHr  = __mkSmallInteger(accessTime.wHour);
-        aMin = __mkSmallInteger(accessTime.wMinute);
-        aSec = __mkSmallInteger(accessTime.wSecond);
-        aMS  = __mkSmallInteger(accessTime.wMilliseconds);
-
-        mYr  = __mkSmallInteger(modificationTime.wYear);
-        mMon = __mkSmallInteger(modificationTime.wMonth);
-        mDay = __mkSmallInteger(modificationTime.wDay);
-        mHr  = __mkSmallInteger(modificationTime.wHour);
-        mMin = __mkSmallInteger(modificationTime.wMinute);
-        mSec = __mkSmallInteger(modificationTime.wSecond);
-        mMS  = __mkSmallInteger(modificationTime.wMilliseconds);
-
-        cYr  = __mkSmallInteger(creationTime.wYear);
-        cMon = __mkSmallInteger(creationTime.wMonth);
-        cDay = __mkSmallInteger(creationTime.wDay);
-        cHr  = __mkSmallInteger(creationTime.wHour);
-        cMin = __mkSmallInteger(creationTime.wMinute);
-        cSec = __mkSmallInteger(creationTime.wSecond);
-        cMS  = __mkSmallInteger(creationTime.wMilliseconds);
+        cOsTime = FileTimeToOsTime(&fileAttributeData.ftCreationTime);
+        aOsTime = FileTimeToOsTime(&fileAttributeData.ftLastAccessTime);
+        mOsTime = FileTimeToOsTime(&fileAttributeData.ftLastWriteTime);
     }
 
   badArgument: ;
@@ -5455,13 +5435,13 @@
     ].
     mode notNil ifTrue:[
         atime isNil ifTrue:[
-            atime := Timestamp day:aDay month:aMon year:aYr hour:aHr minutes:aMin seconds:aSec milliseconds:aMS.
+            atime := Timestamp new fromOSTime:aOsTime.
         ].
         mtime isNil ifTrue:[
-            mtime := Timestamp day:mDay month:mMon year:mYr hour:mHr minutes:mMin seconds:mSec milliseconds:mMS.
+            mtime := Timestamp new fromOSTime:mOsTime.
         ].
         ctime isNil ifTrue:[
-            ctime := Timestamp day:cDay month:cMon year:cYr hour:cHr minutes:cMin seconds:cSec milliseconds:cMS.
+            ctime := Timestamp new fromOSTime:cOsTime.
         ].
         fileName notNil ifTrue:[
             fileName := fileName asSingleByteStringIfPossible
@@ -8041,6 +8021,21 @@
     "
 !
 
+getThreadId
+    "return the (windows-) threadId"
+
+%{  /* NOCONTEXT */
+
+    int pid = 0;
+
+    pid = GetCurrentThreadId() & 0x3FFFFFFF;
+    RETURN ( __mkSmallInteger(pid) );
+%}
+    "
+     OperatingSystem getThreadId
+    "
+!
+
 getWindowsDirectory
     "internal interface - only for Windows based systems.
      Return the windows directory
@@ -8361,9 +8356,18 @@
     "
 !
 
-primRtlGenRandomInto:buffer
-    "fill a given buffer with random bytes from the RtlGenRandom function"
-
+randomBytesInto:bufferOrInteger 
+    "If bufferOrInteger is a String or a ByteArray,
+        fill a given buffer with random bytes from the RtlGenRandom function
+        and nswer the buffer.
+
+     If bufferOrInteger is a SmallInteger,
+        return this many bytes (max 4) as a SmallInteger.
+
+     Return nil on error (and raise PrimitiveFailure).   
+
+     NOTE: This is a private interface, please use RandomGenerator!!"
+    
 %{
 //    BOOLEAN RtlGenRandom(
 //      __out  PVOID RandomBuffer,
@@ -8372,34 +8376,42 @@
     static BOOL (__stdcall *P_RtlGenRandom)(PVOID , ULONG) = 0;
     unsigned char *__buffer;
     int __bufferSize;
-
-    if (__isString(buffer)) {
-        __buffer = __stringVal(buffer);
-        __bufferSize = __stringSize(buffer);
+    int __useLocalBuffer = 0;
+    unsigned int __localBuffer = 0;
+
+    if (__isSmallInteger(bufferOrInteger)) {
+        __useLocalBuffer = 1;
+        __buffer = (unsigned char *)&__localBuffer;
+        __bufferSize = __smallIntegerVal(bufferOrInteger);
+        if (__bufferSize > sizeof(INT))
+            __bufferSize = sizeof(INT);
+    } else if (__isString(bufferOrInteger)) {
+        __buffer = __stringVal(bufferOrInteger);
+        __bufferSize = __stringSize(bufferOrInteger);
+    } else if (__isByteArray(bufferOrInteger)) {
+        __buffer = __byteArrayVal(bufferOrInteger);
+        __bufferSize = __byteArraySize(bufferOrInteger);
     } else {
-        if (__isByteArray(buffer)) {
-            __buffer = __byteArrayVal(buffer);
-            __bufferSize = __byteArraySize(buffer);
-        } else {
-            goto error;
-        }
+        goto error;
     }
 
     if (P_RtlGenRandom == 0) {
         HINSTANCE hAdvapi32 = LoadLibrary("advapi32.dll");
         // console_printf("hAdvapi32: %x\n", hAdvapi32);
-        console_printf("hAdvapi32: %x\n", hAdvapi32);
         if (hAdvapi32) {
             P_RtlGenRandom = (BOOL (__stdcall *)(PVOID , ULONG))
                                 GetProcAddress(hAdvapi32, "SystemFunction036");
-            console_printf("P_RtlGenRandom: %x\n", P_RtlGenRandom);
+            // console_printf("P_RtlGenRandom: %x\n", P_RtlGenRandom);
             if (P_RtlGenRandom == 0) {
                 goto error;
             }
         }
     }
     if ((*P_RtlGenRandom)(__buffer, __bufferSize)) {
-        RETURN (buffer);
+        if (__useLocalBuffer) {
+            RETURN(__mkSmallInteger(__localBuffer & _MAX_INT));
+        }
+        RETURN (bufferOrInteger);
     }
 error: ;
 %}.
@@ -8407,8 +8419,9 @@
     ^ nil
 
     "
-     Win32OperatingSystem 
-        primRtlGenRandomInto:(ByteArray new:4)
+     self randomBytesInto:(ByteArray new:4)
+     self randomBytesInto:4
+     self randomBytesInto:1
     "
 !
 
@@ -9734,100 +9747,40 @@
 
 !Win32OperatingSystem class methodsFor:'time and date'!
 
-computeDatePartsOf:osTime for:aBlock
-    "compute year, month and day from the OS time, osTime
-     and evaluate the argument, a 3-arg block with these.
-     Conversion is to localtime including any daylight saving adjustments."
-
-    |year month day osSeconds|
-
-    osSeconds := osTime // 1000.
-%{
-    struct tm* tmPtr;
-    struct tm tmValue;
-    INT t;
-    time_t tt;
-
-    t = __longIntVal(osSeconds);
-    tt = (time_t)t;
-
-#ifdef __BORLANDC__
-    tmPtr = localtime(&tt);
-#else
-    /* be thread safe */
-    if (localtime_s(&tmValue, &tt) == 0)
-	tmPtr = &tmValue;
-    else
-	tmPtr = NULL;
-#endif
-
-    if (tmPtr != NULL) {
-	year = __mkSmallInteger(tmPtr->tm_year + 1900);
-	month = __mkSmallInteger(tmPtr->tm_mon + 1);
-	day = __mkSmallInteger(tmPtr->tm_mday);
-    }
-%}.
-    year isNil ifTrue:[
-	self primitiveFailed
-    ].
-    aBlock value:year value:month value:day
-
-    "
-     OperatingSystem computeDatePartsOf:0 for:[:y :m :d |
-	y printCR. m printCR. d printCR
-     ]
-    "
-
-    "Modified: / 06-07-2006 / 18:18:04 / cg"
-!
-
 computeOSTimeFromUTCYear:y month:m day:d hour:h minute:min second:s millisecond:millis
     "return the OS-dependent time for the given time and day.
      The arguments are assumed to be in UTC time."
 
-    |osSeconds|
-
-%{
-    struct tm tm;
-
+%{
     if (__bothSmallInteger(y, m)
      && __bothSmallInteger(d, h)
      && __bothSmallInteger(min, s)) {
-	time_t t;
-	TIME_ZONE_INFORMATION tzInfo;
-	int gmtoffMinutes;
-
-	if (GetTimeZoneInformation(&tzInfo) < 0) goto error;
-
-	tm.tm_hour = __intVal(h);
-	tm.tm_min = __intVal(min);
-	tm.tm_sec = __intVal(s);
-
-	tm.tm_year = __intVal(y) - 1900;
-	tm.tm_mon = __intVal(m) - 1;
-	tm.tm_mday = __intVal(d);
-	tm.tm_isdst = -1;
-
-	t = mktime(&tm);
-
-	gmtoffMinutes = tzInfo.Bias;
-	if (tm.tm_isdst) {
-	    gmtoffMinutes += tzInfo.DaylightBias;
-	} else {
-	    gmtoffMinutes += tzInfo.StandardBias;
-	}
-	t = t - gmtoffMinutes*60;
-	osSeconds = __MKUINT((INT)t);
+        SYSTEMTIME sysTime;
+        FILETIME fileTime;
+
+        sysTime.wHour = __intVal(h);
+        sysTime.wMinute = __intVal(min);
+        sysTime.wSecond = __intVal(s);
+        sysTime.wMilliseconds = 0;
+
+        sysTime.wYear = __intVal(y);
+        sysTime.wMonth = __intVal(m);
+        sysTime.wDay = __intVal(d);
+
+        if (SystemTimeToFileTime(&sysTime, &fileTime) == 0)
+            goto error;
+
+        RETURN(FileTimeToOsTime(&fileTime));
     }
 error:;
 %}.
-    osSeconds notNil ifTrue:[
-	^ osSeconds * 1000 + millis
-    ].
-    ^ self primitiveFailed
+    "Error, some invalid date ot time"
+    ^ TimeConversionError raiseRequest
 
     "
      OperatingSystem computeOSTimeFromUTCYear:1970 month:1 day:1 hour:0 minute:0 second:0 millisecond:0
+    invalid:
+     OperatingSystem computeOSTimeFromUTCYear:1970 month:1 day:1 hour:24 minute:0 second:0 millisecond:0
     "
 !
 
@@ -9836,158 +9789,44 @@
      The arguments are assumed to be in localtime including
      any daylight saving adjustings."
 
-    |osSeconds|
-
-%{
-    struct tm tm;
-    time_t t;
-
+%{
     if (__bothSmallInteger(y, m)
      && __bothSmallInteger(d, h)
      && __bothSmallInteger(min, s)) {
-	tm.tm_hour = __intVal(h);
-	tm.tm_min = __intVal(min);
-	tm.tm_sec = __intVal(s);
-
-	tm.tm_year = __intVal(y) - 1900;
-	tm.tm_mon = __intVal(m) - 1;
-	tm.tm_mday = __intVal(d);
-	tm.tm_isdst = -1;
-
-	t = mktime(&tm);
-	osSeconds = __MKUINT((INT)t);
-    }
-%}.
-    osSeconds notNil ifTrue:[
-	^ osSeconds * 1000 + millis
-    ].
-    ^ self primitiveFailed
-
-    "
+        SYSTEMTIME sysTime;
+        FILETIME fileTime;
+
+        sysTime.wHour = __intVal(h);
+        sysTime.wMinute = __intVal(min);
+        sysTime.wSecond = __intVal(s);
+        sysTime.wMilliseconds = 0;
+
+        sysTime.wYear = __intVal(y);
+        sysTime.wMonth = __intVal(m);
+        sysTime.wDay = __intVal(d);
+
+#if 0
+        /* Sorry, but this function is not supported in Win2000
+           - we use LocalFileTimeToFileTime */
+        if (TzSpecificLocalTimeToSystemTime(0, &sysTime, &sysTime) == 0)
+            goto error;
+#endif
+        if (SystemTimeToFileTime(&sysTime, &fileTime) == 0)
+            goto error;
+        if (LocalFileTimeToFileTime(&fileTime, &fileTime) == 0)
+            goto error;
+
+        RETURN(FileTimeToOsTime(&fileTime));
+    }
+error:;
+%}.
+    "Error, some invalid date ot time"
+    ^ TimeConversionError raiseRequest
+
+    "
+     OperatingSystem computeOSTimeFromUTCYear:1970 month:1 day:1 hour:0 minute:0 second:0 millisecond:0
      OperatingSystem computeOSTimeFromYear:1970 month:1 day:1 hour:0 minute:0 seconds:0 millis:0
     "
-
-!
-
-computeTimePartsOf:osTime for:aBlock
-    "compute hours, minutes, seconds and milliseconds from the osTime
-     and evaluate the argument, a 4-arg block with these.
-     Conversion is to localtime including any daylight saving adjustments."
-
-    |hours minutes seconds millis osSeconds|
-
-    osSeconds := osTime // 1000.
-    millis := osTime \\ 1000.
-%{
-    struct tm *tmPtr;
-    struct tm tmValue;
-    INT t;
-    time_t tt;
-
-    t = __longIntVal(osSeconds);
-    tt = (time_t)t;
-
-#ifdef __BORLANDC__
-    tmPtr = localtime(&tt);
-#else
-    /* be thread safe */
-    if (localtime_s(&tmValue, &tt) == 0)
-	tmPtr = &tmValue;
-    else
-	tmPtr = NULL;
-#endif
-
-    if (tmPtr != NULL) {
-	hours = __mkSmallInteger(tmPtr->tm_hour);
-	minutes = __mkSmallInteger(tmPtr->tm_min);
-	seconds = __mkSmallInteger(tmPtr->tm_sec);
-    }
-%}.
-    hours isNil ifTrue:[
-	self primitiveFailed
-    ].
-    aBlock value:hours value:minutes value:seconds value:millis
-
-    "
-     OperatingSystem computeTimePartsOf:100 for:[:h :m :s :milli |
-	h printCR. m printCR. s printCR. millis printCR
-     ]
-    "
-
-    "Modified: / 06-07-2006 / 18:18:39 / cg"
-!
-
-computeUTCTimeAndDateFrom:osTime
-    "given an OS-dependent time in osTime, return an Array
-     containing year, month, day, hour, minute and seconds,
-     offset to UTC, daylight savings time flag, milliseconds,
-     dayInYear (1..) and dayInWeek (1..).
-     Conversion is to UTC."
-
-    |year month day hours minutes seconds millis utcOffset
-     dst yDay wDay osSeconds ret|
-
-    millis := osTime \\ 1000.
-    osSeconds := osTime // 1000.
-%{
-    struct tm *tmPtr;
-    struct tm *gmTmPtr;
-    long t;
-
-    t = __longIntVal(osSeconds);
-
-    tmPtr = gmtime(&t);
-    hours = __mkSmallInteger(tmPtr->tm_hour);
-    minutes = __mkSmallInteger(tmPtr->tm_min);
-    seconds = __mkSmallInteger(tmPtr->tm_sec);
-
-    year = __mkSmallInteger(tmPtr->tm_year + 1900);
-    month = __mkSmallInteger(tmPtr->tm_mon + 1);
-    day = __mkSmallInteger(tmPtr->tm_mday);
-
-    yDay = __mkSmallInteger(tmPtr->tm_yday + 1);
-    wDay = __mkSmallInteger(tmPtr->tm_wday == 0 ? 7 : tmPtr->tm_wday);
-    dst = (tmPtr->tm_isdst == 0) ? false : true;
-
-#ifdef WINDOWS_IS_POSIX_CONFORM_WHICH_IT_IS_NOT
-    utcOffset = __MKINT(tmPtr->tm_gmtoff);
-#else
-    {
-	TIME_ZONE_INFORMATION tzInfo;
-	int gmtoffMinutes = 0;
-
-	if (GetTimeZoneInformation(&tzInfo) < 0) goto error;
-	gmtoffMinutes = tzInfo.Bias;
-	if (tmPtr->tm_isdst) {
-	    gmtoffMinutes += tzInfo.DaylightBias;
-	} else {
-	    gmtoffMinutes += tzInfo.StandardBias;
-	}
-
-	utcOffset = __MKINT(gmtoffMinutes*60);
-    }
-#endif
-error:;
-%}.
-    "I would love to have SELF-like inline objects ..."
-    ret := Array new:11.
-    ret at:1 put:year.
-    ret at:2 put:month.
-    ret at:3 put:day.
-    ret at:4 put:hours.
-    ret at:5 put:minutes.
-    ret at:6 put:seconds.
-    ret at:7 put:utcOffset.
-    ret at:8 put:dst.
-    ret at:9 put:millis.
-    ret at:10 put:yDay.
-    ret at:11 put:wDay.
-    ^ ret
-
-    "
-     OperatingSystem computeUTCTimeAndDateFrom:0
-     OperatingSystem computeUTCTimeAndDateFrom:self getOSTime
-    "
 !
 
 getMicrosecondTime
@@ -10005,17 +9844,17 @@
     LONGLONG micros;
 
     if (! frequencyKnown) {
-	// get the high resolution counter's accuracy
-	QueryPerformanceFrequency(&ticksPerSecond);
-	frequencyKnown = 1;
-	divisor = ticksPerSecond / (LONGLONG)1000000;
+        // get the high resolution counter's accuracy
+        QueryPerformanceFrequency(&ticksPerSecond);
+        frequencyKnown = 1;
+        divisor = ticksPerSecond / (LONGLONG)1000000;
     }
 
     // what time is it?
     QueryPerformanceCounter(&tick);
 
     micros = tick / divisor;
-    RETURN ( __MKLARGEINT64(0, (micros & 0xFFFFFFFF), (micros >> 32)) );
+    RETURN ( __MKLARGEINT64(1, (micros & 0xFFFFFFFF), (micros >> 32)) );
 %}
     "
      |t1 t2 dT|
@@ -10044,8 +9883,8 @@
      Use the millisecondTimeXXX:-methods to compare and add time deltas - these know about the wrap.
 
      BAD DESIGN:
-	This should be changed to return some instance of RelativeTime,
-	and these computations moved there.
+        This should be changed to return some instance of RelativeTime,
+        and these computations moved there.
 
      Don't use this method in application code since it is an internal (private)
      interface. For compatibility with ST-80, use Time millisecondClockValue.
@@ -10066,65 +9905,18 @@
 
      Dont use this method in application code since it is an internal (private)
      interface. For compatibility with ST-80, use Time>>millisecondClockValue.
-     or use instances of Time, Date or Timestamp to work with.
-    "
-
-    |seconds millis|
-
-%{
-
-    long t;
-
-#if !defined(HAS_GETTIMEOFDAY)
-# if defined(HAS_FTIME)
-    struct timeb timebuffer;
-
-    ftime(&timebuffer);
-    seconds = __MKUINT(timebuffer.time);
-    millis = __MKUINT(timebuffer.millitm);
-#   define HAVE_TIME
-# endif
-
-# ifndef HAVE_TIME
-#  ifdef MSDOS_LIKE
-#   ifdef __BORLANDC__
-    struct timeb timebuffer;
-    ftime(&timebuffer);
-#   else
-    struct _timeb timebuffer;
-    _ftime(&timebuffer);
-#   endif
-    seconds = __MKUINT(timebuffer.time);
-    millis = __MKUINT(timebuffer.millitm);
-#   define HAVE_TIME
-#  endif
-# endif
-#endif
-
-#ifndef HAVE_TIME
-    /* assume HAS_GETTIMEOFDAY
-     * - will result in a linkage error
-     * if not fixed.
-     */
-    /*
-     * bsd time
-     */
-    struct timeval tb;
-    struct timezone tzb;
-
-    gettimeofday(&tb, &tzb);
-
-    seconds = __MKUINT(tb.tv_sec);
-    millis = __MKUINT(tb.tv_usec / 1000);
-#endif
-
-#undef HAVE_TIME
-
-%}.
-    ^ (seconds * 1000) + millis
-
-    "
-     OperatingSystem getOSTime printCR.
+     or use instances of Time, Date or Timestamp to work with."
+
+%{
+    FILETIME fileTime;
+
+    GetSystemTimeAsFileTime(&fileTime);
+
+    RETURN(FileTimeToOsTime(&fileTime));
+%}.
+
+    "
+     OperatingSystem getOSTime.
      Delay waitForSeconds:0.2.
      OperatingSystem getOSTime printCR.
     "
@@ -10243,123 +10035,85 @@
      OS-second value.
      An internal helper"
 
-    |year month day hours minutes seconds utcOffset
-     dst yDay wDay info reason|
-
-%{
-    struct tm *tmPtr;
-    struct tm tmValue;
+    |year month day hours minutes seconds utcOffset dstOffset
+     dst yDay weekDay info reason|
+
+%{
     UINT t;
-    time_t tt;
+    FILETIME fileTime, localFileTime;
+    SYSTEMTIME sysTime;
 
     t = __longIntVal(osSeconds);
 
     /* try cache */
     {
-	OBJ lastSeconds, lastTimeInfo;
-
-	lastSeconds = @global(LastTimeInfoSeconds);
-	if (lastSeconds
-	 && (__longIntVal(lastSeconds) == t)
-	 && (@global(LastTimeInfoMilliseconds) == osMilliseconds)
-	 && (@global(LastTimeInfoIsLocal) == isLocalTime)
-	) {
-	    lastTimeInfo = @global(LastTimeInfo);
-	    if (lastTimeInfo != nil) {
-		RETURN (lastTimeInfo);
-	    }
-	}
-    }
-    if (t == 0) {
-	reason = @symbol(invalidOSTime);
-	goto error;
-    }
-
-    tt = (time_t)t;
+        OBJ lastSeconds, lastTimeInfo;
+
+        lastSeconds = @global(LastTimeInfoSeconds);
+        if (lastSeconds
+         && (__longIntVal(lastSeconds) == t)
+         && (@global(LastTimeInfoMilliseconds) == osMilliseconds)
+         && (@global(LastTimeInfoIsLocal) == isLocalTime)
+        ) {
+            lastTimeInfo = @global(LastTimeInfo);
+            if (lastTimeInfo != nil) {
+                RETURN (lastTimeInfo);
+            }
+        }
+    }
+
+    TimetToFileTime((time_t)t, &fileTime);
 
     if (isLocalTime == true) {
-#ifdef __BORLANDC__
-	tmPtr = localtime(&tt);
-#else
-	/* be thread safe */
-	if (localtime_s(&tmValue, &tt) == 0)
-	    tmPtr = &tmValue;
-	else
-	    tmPtr = NULL;
-#endif
-	if (tmPtr == NULL) {
-	    reason = @symbol(localtimeConversionFailed);
-	    goto error;
-	}
-
-#ifdef WINDOWS_IS_POSIX_CONFORM_WHICH_IT_IS_NOT
-	utcOffset = __MKINT(tmPtr->tm_gmtoff);
-#else
-	{
-	    TIME_ZONE_INFORMATION tzInfo;
-	    int gmtoffMinutes = 0;
-
-	    if (GetTimeZoneInformation(&tzInfo) < 0) {
-		reason = @symbol(getTimeZoneFailed);
-		goto error;
-	    }
-	    gmtoffMinutes = tzInfo.Bias;
-	    if (tmPtr->tm_isdst) {
-		gmtoffMinutes += tzInfo.DaylightBias;
-	    } else {
-		gmtoffMinutes += tzInfo.StandardBias;
-	    }
-	    utcOffset = __MKINT(gmtoffMinutes*60);
-	}
-#endif
+        TIME_ZONE_INFORMATION tzInfo;
+        int tzState;
+        LONGLONG longTime;
+
+        FileTimeToLocalFileTime(&fileTime, &localFileTime);
+        FileTimeToSystemTime(&localFileTime, &sysTime);
+
+        longTime = ((LONGLONG)fileTime.dwHighDateTime << 32) + fileTime.dwLowDateTime;
+        longTime -= ((LONGLONG)localFileTime.dwHighDateTime << 32) + localFileTime.dwLowDateTime;
+        utcOffset = __mkSmallInteger((INT)(longTime / 10000000));
+
+        if ((tzState = GetTimeZoneInformation(&tzInfo)) < 0) {
+            reason = @symbol(getTimeZoneFailed);
+            goto error;
+        }
+        dstOffset = __mkSmallInteger((tzInfo.Bias + tzInfo.DaylightBias) * 60);
     } else {
-#ifdef __BORLANDC__
-	tmPtr = gmtime(&tt);
-#else
-	/* be thread safe */
-	if (gmtime_s(&tmValue, &tt) == 0)
-	    tmPtr = &tmValue;
-	else
-	    tmPtr = NULL;
-#endif
-	if (tmPtr == NULL) {
-	    reason = @symbol(conversionToGMTimeFailed);
-	    goto error;
-	}
-	utcOffset = __mkSmallInteger(0);
-    }
-
-    hours = __mkSmallInteger(tmPtr->tm_hour);
-    minutes = __mkSmallInteger(tmPtr->tm_min);
-    seconds = __mkSmallInteger(tmPtr->tm_sec);
-
-    year = __mkSmallInteger(tmPtr->tm_year + 1900);
-    month = __mkSmallInteger(tmPtr->tm_mon + 1);
-    day = __mkSmallInteger(tmPtr->tm_mday);
-
-    yDay = __mkSmallInteger(tmPtr->tm_yday+1);
-    wDay = __mkSmallInteger(tmPtr->tm_wday == 0 ? 7 : tmPtr->tm_wday);
-
-    dst = (tmPtr->tm_isdst == 0) ? false : true;
+        FileTimeToSystemTime(&fileTime, &sysTime);
+        utcOffset = __mkSmallInteger(0);
+    }
+
+    hours = __mkSmallInteger(sysTime.wHour);
+    minutes = __mkSmallInteger(sysTime.wMinute);
+    seconds = __mkSmallInteger(sysTime.wSecond);
+
+    year = __mkSmallInteger(sysTime.wYear);
+    month = __mkSmallInteger(sysTime.wMonth);
+    day = __mkSmallInteger(sysTime.wDay);
+
+    weekDay = __mkSmallInteger(sysTime.wDayOfWeek == 0 ? 7 : sysTime.wDayOfWeek);
 error:;
 %}.
-    dst isNil ifTrue:[
-	^ self primitiveFailed
+    year isNil ifTrue:[
+        ^ self primitiveFailed
     ].
 
     info := self timeInfoClass new.
     info
-	year:year
-	month:month
-	day:day
-	hours:hours
-	minutes:minutes
-	seconds:seconds
-	milliseconds:osMilliseconds
-	utcOffset:utcOffset
-	dst:dst
-	dayInYear:yDay
-	dayInWeek:wDay.
+        year:year
+        month:month
+        day:day
+        hours:hours
+        minutes:minutes
+        seconds:seconds
+        milliseconds:osMilliseconds
+        utcOffset:utcOffset
+        dst:(utcOffset = dstOffset)
+        dayInYear:yDay
+        dayInWeek:weekDay.
 
     LastTimeInfo := info.
     LastTimeInfoSeconds := osSeconds.
@@ -10373,6 +10127,7 @@
      OperatingSystem timeInfoFromSeconds:0 milliseconds:0 localTime:false
      OperatingSystem timeInfoFromSeconds:3600 milliseconds:0 localTime:true
      OperatingSystem timeInfoFromSeconds:Timestamp now utcSecondsSince1970 milliseconds:0 localTime:true
+     OperatingSystem timeInfoFromSeconds:Timestamp now utcSecondsSince1970 milliseconds:0 localTime:false
     "
 
     "Modified: / 06-07-2006 / 18:18:56 / cg"
@@ -16497,11 +16252,11 @@
 !Win32OperatingSystem class methodsFor:'documentation'!
 
 version
-    ^ '$Id: Win32OperatingSystem.st 10505 2010-03-08 21:39:02Z vranyj1 $'
+    ^ '$Id: Win32OperatingSystem.st 10510 2010-04-08 17:25:02Z vranyj1 $'
 !
 
 version_CVS
-    ^ '§Header: /cvs/stx/stx/libbasic/Win32OperatingSystem.st,v 1.391 2010/03/08 12:43:38 cg Exp §'
+    ^ '§Header: /cvs/stx/stx/libbasic/Win32OperatingSystem.st,v 1.401 2010/04/06 08:17:14 stefan Exp §'
 ! !
 
 Win32OperatingSystem initialize!
@@ -16515,3 +16270,4 @@
 
 
 
+