Win32OperatingSystem.st
changeset 17006 d6ec5e448ac5
parent 17004 504c08a32877
child 17007 48b4d45626c9
--- a/Win32OperatingSystem.st	Sat Nov 08 19:22:05 2014 +0100
+++ b/Win32OperatingSystem.st	Mon Nov 10 15:05:02 2014 +0100
@@ -534,43 +534,43 @@
     tv.tv_usec = 0;
 
     if (readMode) {
-        n = select (1 , &fds, NULL, NULL, &tv);  // first parameter to select is ignored in windows
+	n = select (1 , &fds, NULL, NULL, &tv);  // first parameter to select is ignored in windows
     } else {
-        n = select (1, NULL, &fds, NULL, &tv);
+	n = select (1, NULL, &fds, NULL, &tv);
     }
 
     if (n == 0) {
-        return (0);
+	return (0);
     }
 
     if (n > 0) {
-        return (FD_ISSET(handle, &fds) ? 1 : 0);
+	return (FD_ISSET(handle, &fds) ? 1 : 0);
     }
 
     winErrNo = WSAGetLastError();
     switch (winErrNo) {
-        case WSAENOTSOCK:
-            if (readMode) {
-                DWORD  w = 0;
-
-                if (PeekNamedPipe (handle, 0, 0, 0, & w, 0)) {
-                    return (w > 0);
-                }
+	case WSAENOTSOCK:
+	    if (readMode) {
+		DWORD  w = 0;
+
+		if (PeekNamedPipe (handle, 0, 0, 0, & w, 0)) {
+		    return (w > 0);
+		}
 #if 0
-                console_fprintf(stderr, "_canAccessIOWithoutBlocking non Socket\n");
-#endif
-                return (-1);
-            }
-            /* in writeMode we return always 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 always 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 */
@@ -592,7 +592,7 @@
     FARPROC entry;
 
     if (*pLibHandle == NULL) {
-        *pLibHandle = LoadLibrary(libraryName);
+	*pLibHandle = LoadLibrary(libraryName);
     }
     entry = GetProcAddress(*pLibHandle, functionName);
     return entry;
@@ -629,7 +629,9 @@
 {
     LONGLONG lTime = ((LONGLONG)pft->dwHighDateTime << 32) + pft->dwLowDateTime;
     lTime = (lTime / 10000);    // convert multiple of 100ns to milliseconds
-    // lTime = lTime - 11644473600000L;
+
+    // rebias to 1970 by subtracting the number of millis from 1.1.1601 to 1.1.1970
+    lTime = lTime - 11644473600000L;
 
     return(__MKLARGEINT64(1, (unsigned INT)(lTime & 0xFFFFFFFF), (unsigned INT)(lTime >> 32)));
 }
@@ -641,10 +643,14 @@
     UINT hi = __unsignedLongIntVal(tHigh);
 
     if (hi == 0 && !__isSmallInteger(tHigh))
-        return(0);      // conversion error
+	return(0);      // conversion error
 
     lTime = ((LONGLONG)hi << 32) + (LONGLONG)low;
+    // rebias to 1601 by adding the number of millis from 1.1.1601 to 1.1.1970
+    lTime = lTime + 11644473600000L;
+
     lTime = lTime * 10000;      // convert to multiple of 100ns
+
     pft->dwHighDateTime = (UINT)(lTime >> 32);
     pft->dwLowDateTime = (UINT)(lTime & 0xFFFFFFFF);
     return(1);
@@ -10140,9 +10146,26 @@
 
 !Win32OperatingSystem class methodsFor:'time and date'!
 
-computeOSTimeFromUTCYear:y month:m day:d hour:h minute:min second:s millisecond:millis
+epochStartOSTime
+    "private interface for timestamp to ask the OS what the minimum time
+     (in milliseconds since the Unix epoch, 1.1.1970) is.
+     Windows epoch starts at 1.1.1601."
+
+    ^ self osTimeOf19700101 negated
+!
+
+epocEndOSTime
+    "private interface for timestamp to ask the OS what the maximum time
+     (in milliseconds since the Unix epoch, 1.1.1970) is.
+     Windows has a 64 Unix 100ns osTime internally."
+
+    ^ (16r7FFFFFFFFFFFFFFF // 10000) - self osTimeOf19700101
+!
+
+computeOSTimeFromYear:y month:m day:d hour:h minute:min second:s millisecond:millis utc:utcBoolean
     "return the OS-dependent time for the given time and day.
-     The arguments are assumed to be in UTC time."
+     The arguments are assumed to be in localtime including
+     any daylight saving adjustings."
 
 %{
     if (__bothSmallInteger(y, m)
@@ -10161,73 +10184,41 @@
 	sysTime.wMonth = __intVal(m);
 	sysTime.wDay = __intVal(d);
 
-	if (SystemTimeToFileTime(&sysTime, &fileTime) == 0)
+	if (sysTime.wYear < 1602) goto outOfRange;   // not 1601 - so we don't have to care for timezone
+	if (sysTime.wYear > 9999) goto outOfRange;
+
+	if (utcBoolean != true) {
+	    // adjust for local time
+
+	    // TzSpecificLocalTimeToSystemTime() is not supported in Win2000
+	    // - but we do not support Win2k any longer as of 2014
+#ifdef __BORLANDC__
+	    {
+		typedef BOOL (WINAPI *P_TzSpecificLocalTimeToSystemTime)(LPTIME_ZONE_INFORMATION, LPSYSTEMTIME, LPSYSTEMTIME);
+		static P_TzSpecificLocalTimeToSystemTime pTzSpecificLocalTimeToSystemTime;
+
+		if (pTzSpecificLocalTimeToSystemTime == NULL) {
+		    pTzSpecificLocalTimeToSystemTime =
+			(P_TzSpecificLocalTimeToSystemTime)
+			    GetProcAddress ( GetModuleHandle ("kernel32.dll"),
+							      "TzSpecificLocalTimeToSystemTime");
+		}
+		if (!pTzSpecificLocalTimeToSystemTime(0, &sysTime, &sysTime))
+		    goto error;
+	    }
+#else
+	    if (!TzSpecificLocalTimeToSystemTime(0, &sysTime, &sysTime))
+		goto error;
+#endif
+	}
+
+	if (! SystemTimeToFileTime(&sysTime, &fileTime))
 	    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
-    invalid:
-     OperatingSystem computeOSTimeFromUTCYear:1970 month:1 day:1 hour:24 minute:0 second:0 millisecond:0
-    "
-
-    "Modified: / 07-07-2010 / 16:56:21 / cg"
-!
-
-computeOSTimeFromYear: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 localtime including
-     any daylight saving adjustings."
-
-%{
-    if (__bothSmallInteger(y, m)
-     && __bothSmallInteger(d, h)
-     && __bothSmallInteger(min, s)
-     && __isSmallInteger(millis)) {
-        SYSTEMTIME sysTime;
-        FILETIME fileTime;
-
-        sysTime.wHour = __intVal(h);
-        sysTime.wMinute = __intVal(min);
-        sysTime.wSecond = __intVal(s);
-        sysTime.wMilliseconds = __intVal(millis);
-
-        sysTime.wYear = __intVal(y);
-        sysTime.wMonth = __intVal(m);
-        sysTime.wDay = __intVal(d);
-
-
-        // TzSpecificLocalTimeToSystemTime() is not supported in Win2000 
-        // - but we do not support Win2k any longer as of 2014
-#ifdef __BORLANDC__
-        {
-            typedef BOOL (WINAPI *P_TzSpecificLocalTimeToSystemTime)(LPTIME_ZONE_INFORMATION, LPSYSTEMTIME, LPSYSTEMTIME);  
-            static P_TzSpecificLocalTimeToSystemTime pTzSpecificLocalTimeToSystemTime;
-
-            if (pTzSpecificLocalTimeToSystemTime == NULL) {
-                pTzSpecificLocalTimeToSystemTime = (P_TzSpecificLocalTimeToSystemTime)GetProcAddress (
-                                                    GetModuleHandle ("kernel32.dll"),
-                                                                     "TzSpecificLocalTimeToSystemTime");
-            }
-            if (!pTzSpecificLocalTimeToSystemTime(0, &sysTime, &sysTime))
-                goto error;
-        }
-#else
-        if (!TzSpecificLocalTimeToSystemTime(0, &sysTime, &sysTime))
-            goto error;
-#endif
-        if (!SystemTimeToFileTime(&sysTime, &fileTime))
-            goto error;
-
-        RETURN(FileTimeToOsTime(&fileTime));
-    }
-error:;
+outOfRange: ;
+error: ;
 %}.
     "Error, some invalid date ot time"
     ^ TimeConversionError raiseRequest
@@ -10254,17 +10245,17 @@
 computeUTCTimeAndDateFrom:osTime
     "given an OS-dependent time in osTime, return an Array
      containing:
-        (full-) year,
-        month,                          (1..)
-        day,                            (1..)
-        hour,                           (0..23)
-        minute                          (0..59)
-        seconds,                        (0..59)
-        offset to UTC,                  (seconds)
-        daylight savings time flag,
-        milliseconds,                   (0..999)
-        dayInYear                       (1..)
-        dayInWeek                       (1..).
+	(full-) year,
+	month,                          (1..)
+	day,                            (1..)
+	hour,                           (0..23)
+	minute                          (0..59)
+	seconds,                        (0..59)
+	offset to UTC,                  (seconds)
+	daylight savings time flag,
+	milliseconds,                   (0..999)
+	dayInYear                       (1..)
+	dayInWeek                       (1..).
      Conversion is to utc."
 
     ^ self timeInfoFromOsTime:osTime localTime:false.
@@ -10462,39 +10453,39 @@
     WCHAR nm[33];
 
     if (anIntegerOrNil == nil) {
-        if (GetTimeZoneInformation(&tzInfo) < 0) {
-            error = __mkSmallInteger(__WIN32_ERR(GetLastError()));
-            goto out;
-        }
+	if (GetTimeZoneInformation(&tzInfo) < 0) {
+	    error = __mkSmallInteger(__WIN32_ERR(GetLastError()));
+	    goto out;
+	}
     } else if (__isSmallInteger(anIntegerOrNil)) {
-        int year = __intVal(anIntegerOrNil);
+	int year = __intVal(anIntegerOrNil);
 #ifdef __BORLANDC__
-        {
-            typedef BOOL (WINAPI *P_GetTimeZoneInformationForYear)(
-                                        USHORT, 
-                                        LPTIME_ZONE_INFORMATION, // - should be, but not defined: PDYNAMIC_TIME_ZONE_INFORMATION, 
-                                        LPTIME_ZONE_INFORMATION);  
-            static P_GetTimeZoneInformationForYear pGetTimeZoneInformationForYear;
-
-            if (pGetTimeZoneInformationForYear == NULL) {
-                    pGetTimeZoneInformationForYear = 
-                        (P_GetTimeZoneInformationForYear)GetProcAddress(GetModuleHandle("kernel32.dll"), "GetTimeZoneInformationForYear");
-            }
-            if (!pGetTimeZoneInformationForYear(year, NULL, &tzInfo)) {
-                error = __mkSmallInteger(__WIN32_ERR(GetLastError()));
-                goto out;
-            }
-        }
-#else
-        if (!GetTimeZoneInformationForYear(year, NULL, &tzInfo)) {
-            error = __mkSmallInteger(__WIN32_ERR(GetLastError()));
-            goto out;
-        }
+	{
+	    typedef BOOL (WINAPI *P_GetTimeZoneInformationForYear)(
+					USHORT,
+					LPTIME_ZONE_INFORMATION, // - should be, but not defined: PDYNAMIC_TIME_ZONE_INFORMATION,
+					LPTIME_ZONE_INFORMATION);
+	    static P_GetTimeZoneInformationForYear pGetTimeZoneInformationForYear;
+
+	    if (pGetTimeZoneInformationForYear == NULL) {
+		    pGetTimeZoneInformationForYear =
+			(P_GetTimeZoneInformationForYear)GetProcAddress(GetModuleHandle("kernel32.dll"), "GetTimeZoneInformationForYear");
+	    }
+	    if (!pGetTimeZoneInformationForYear(year, NULL, &tzInfo)) {
+		error = __mkSmallInteger(__WIN32_ERR(GetLastError()));
+		goto out;
+	    }
+	}
+#else
+	if (!GetTimeZoneInformationForYear(year, NULL, &tzInfo)) {
+	    error = __mkSmallInteger(__WIN32_ERR(GetLastError()));
+	    goto out;
+	}
 #endif
     } else {
-        error = @symbol(badArgument);
-        goto out;
-    }        
+	error = @symbol(badArgument);
+	goto out;
+    }
 
     bias = __mkSmallInteger(tzInfo.Bias);
     memmove(nm, tzInfo.StandardName, 32*sizeof(WCHAR));
@@ -10523,22 +10514,22 @@
 out:;
 %}.
     error notNil ifTrue:[
-        self primitiveFailed:error.
+	self primitiveFailed:error.
     ].
 
     info := AbstractOperatingSystem::TimeZoneInfo new.
     info
-        bias:bias
-        name:standardName standardBias:standardBias
-        daylightName:daylightName daylightBias:daylightBias.
+	bias:bias
+	name:standardName standardBias:standardBias
+	daylightName:daylightName daylightBias:daylightBias.
 
     standardDate_m ~~ 0 ifTrue:[
-        info standardYear:standardDate_y standardMonth:standardDate_m standardDay:standardDate_d
-             standardWeekDay:standardDate_wd standardHour:standardDate_h standardMinute:standardDate_min.
+	info standardYear:standardDate_y standardMonth:standardDate_m standardDay:standardDate_d
+	     standardWeekDay:standardDate_wd standardHour:standardDate_h standardMinute:standardDate_min.
     ].
     daylightDate_m ~~ 0 ifTrue:[
-        info daylightYear:daylightDate_y daylightMonth:daylightDate_m daylightDay:daylightDate_d
-             daylightWeekDay:daylightDate_wd daylightHour:daylightDate_h daylightMinute:daylightDate_min.
+	info daylightYear:daylightDate_y daylightMonth:daylightDate_m daylightDay:daylightDate_d
+	     daylightWeekDay:daylightDate_wd daylightHour:daylightDate_h daylightMinute:daylightDate_min.
     ].
 
     ^ info
@@ -10604,82 +10595,82 @@
 
     /* try cache */
     {
-        OBJ lastOsTimeLow, lastOsTimeHi, lastTimeInfo;
-
-        lastOsTimeLow = @global(LastOsTimeLow);
-        lastOsTimeHi = @global(LastOsTimeHi);
-        if (__isInteger(lastOsTimeLow)
-             && (__unsignedLongIntVal(lastOsTimeLow) == __unsignedLongIntVal(tLow))
-             && lastOsTimeHi
-             && (__unsignedLongIntVal(lastOsTimeHi) == __unsignedLongIntVal(tHigh))
-             && (@global(LastTimeInfoIsLocal) == isLocalTime)
-        ) {
-            lastTimeInfo = @global(LastTimeInfo);
-            if (lastTimeInfo != nil) {
-                RETURN (lastTimeInfo);
-            }
-        }
+	OBJ lastOsTimeLow, lastOsTimeHi, lastTimeInfo;
+
+	lastOsTimeLow = @global(LastOsTimeLow);
+	lastOsTimeHi = @global(LastOsTimeHi);
+	if (__isInteger(lastOsTimeLow)
+	     && (__unsignedLongIntVal(lastOsTimeLow) == __unsignedLongIntVal(tLow))
+	     && lastOsTimeHi
+	     && (__unsignedLongIntVal(lastOsTimeHi) == __unsignedLongIntVal(tHigh))
+	     && (@global(LastTimeInfoIsLocal) == isLocalTime)
+	) {
+	    lastTimeInfo = @global(LastTimeInfo);
+	    if (lastTimeInfo != nil) {
+		RETURN (lastTimeInfo);
+	    }
+	}
     }
 
     if (!OsTimeToFileTime(tLow, tHigh, &fileTime))
-        goto out;
+	goto out;
     if (!FileTimeToSystemTime(&fileTime, &sysTime))
-        goto out;
+	goto out;
 
     if (isLocalTime == true) {
-        TIME_ZONE_INFORMATION tzInfo;
-        int tzState;
-        LONGLONG longTime;
-        SYSTEMTIME localSysTime;
-        FILETIME localFileTime;
-
-        if (!SystemTimeToTzSpecificLocalTime(NULL, &sysTime, &localSysTime))
-            goto out;
-        if (!SystemTimeToFileTime(&localSysTime, &localFileTime))
-            goto out;
-
-        // all the rest is computing the UTC offset and whether DST applies
-        longTime = ((LONGLONG)fileTime.dwHighDateTime << 32) + fileTime.dwLowDateTime;
-        longTime -= ((LONGLONG)localFileTime.dwHighDateTime << 32) + localFileTime.dwLowDateTime;
-        utcOffset = __mkSmallInteger((INT)(longTime / 10000000));
+	TIME_ZONE_INFORMATION tzInfo;
+	int tzState;
+	LONGLONG longTime;
+	SYSTEMTIME localSysTime;
+	FILETIME localFileTime;
+
+	if (!SystemTimeToTzSpecificLocalTime(NULL, &sysTime, &localSysTime))
+	    goto out;
+	if (!SystemTimeToFileTime(&localSysTime, &localFileTime))
+	    goto out;
+
+	// all the rest is computing the UTC offset and whether DST applies
+	longTime = ((LONGLONG)fileTime.dwHighDateTime << 32) + fileTime.dwLowDateTime;
+	longTime -= ((LONGLONG)localFileTime.dwHighDateTime << 32) + localFileTime.dwLowDateTime;
+	utcOffset = __mkSmallInteger((INT)(longTime / 10000000));
 
 #if 0 // this is not compatible with WIN XP (first supported with Vista)
 # ifdef __BORLANDC__
-        {
-            typedef BOOL (WINAPI *P_GetTimeZoneInformationForYear)(
-                                        USHORT, 
-                                        LPTIME_ZONE_INFORMATION, // - should be, but is not defined: PDYNAMIC_TIME_ZONE_INFORMATION, 
-                                        LPTIME_ZONE_INFORMATION);  
-            static P_GetTimeZoneInformationForYear pGetTimeZoneInformationForYear;
-
-            if (pGetTimeZoneInformationForYear == NULL) {
-                    pGetTimeZoneInformationForYear = 
-                        (P_GetTimeZoneInformationForYear)GetProcAddress(GetModuleHandle("kernel32.dll"), "GetTimeZoneInformationForYear");
-            }
-            if (!pGetTimeZoneInformationForYear(localSysTime.wYear, NULL, &tzInfo)) {
-                reason = @symbol(getTimeZoneFailed);
-                goto out;
-            }
-        }
+	{
+	    typedef BOOL (WINAPI *P_GetTimeZoneInformationForYear)(
+					USHORT,
+					LPTIME_ZONE_INFORMATION, // - should be, but is not defined: PDYNAMIC_TIME_ZONE_INFORMATION,
+					LPTIME_ZONE_INFORMATION);
+	    static P_GetTimeZoneInformationForYear pGetTimeZoneInformationForYear;
+
+	    if (pGetTimeZoneInformationForYear == NULL) {
+		    pGetTimeZoneInformationForYear =
+			(P_GetTimeZoneInformationForYear)GetProcAddress(GetModuleHandle("kernel32.dll"), "GetTimeZoneInformationForYear");
+	    }
+	    if (!pGetTimeZoneInformationForYear(localSysTime.wYear, NULL, &tzInfo)) {
+		reason = @symbol(getTimeZoneFailed);
+		goto out;
+	    }
+	}
 # else
-        if (!GetTimeZoneInformationForYear(localSysTime.wYear, NULL, &tzInfo)) {
-            reason = @symbol(getTimeZoneFailed);
-            goto out;
-        }
+	if (!GetTimeZoneInformationForYear(localSysTime.wYear, NULL, &tzInfo)) {
+	    reason = @symbol(getTimeZoneFailed);
+	    goto out;
+	}
 # endif
 #else // WIN XP compatibility
-        if (!GetTimeZoneInformation(&tzInfo)) {
-            reason = @symbol(getTimeZoneFailed);
-            goto out;
-        }
+	if (!GetTimeZoneInformation(&tzInfo)) {
+	    reason = @symbol(getTimeZoneFailed);
+	    goto out;
+	}
 
 #endif // WIN XP compatibility
 
-        dstOffset = __mkSmallInteger((tzInfo.Bias + tzInfo.DaylightBias) * 60);
-        sysTimePtr = &localSysTime;
+	dstOffset = __mkSmallInteger((tzInfo.Bias + tzInfo.DaylightBias) * 60);
+	sysTimePtr = &localSysTime;
     } else {
-        sysTimePtr = &sysTime;
-        utcOffset = __mkSmallInteger(0);
+	sysTimePtr = &sysTime;
+	utcOffset = __mkSmallInteger(0);
     }
 
     hours = __mkSmallInteger(sysTimePtr->wHour);
@@ -10696,22 +10687,22 @@
 out:;
 %}.
     year isNil ifTrue:[
-        TimeConversionError raiseErrorString:' - out of range'.
+	TimeConversionError raiseErrorString:' - out of range'.
     ].
 
     info := self timeInfoClass new.
     info
-        year:year
-        month:month
-        day:day
-        hours:hours
-        minutes:minutes
-        seconds:seconds
-        milliseconds:millis
-        utcOffset:utcOffset
-        dst:(utcOffset = dstOffset)
-        dayInYear:yDay
-        dayInWeek:weekDay.
+	year:year
+	month:month
+	day:day
+	hours:hours
+	minutes:minutes
+	seconds:seconds
+	milliseconds:millis
+	utcOffset:utcOffset
+	dst:(utcOffset = dstOffset)
+	dayInYear:yDay
+	dayInWeek:weekDay.
 
     LastTimeInfo := info.
     LastOsTimeLow := tLow.
@@ -17845,15 +17836,15 @@
 !Win32OperatingSystem class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/Win32OperatingSystem.st,v 1.509 2014-11-08 17:14:37 stefan Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/Win32OperatingSystem.st,v 1.510 2014-11-10 14:05:02 cg Exp $'
 !
 
 version_CVS
-    ^ '$Header: /cvs/stx/stx/libbasic/Win32OperatingSystem.st,v 1.509 2014-11-08 17:14:37 stefan Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/Win32OperatingSystem.st,v 1.510 2014-11-10 14:05:02 cg Exp $'
 !
 
 version_SVN
-    ^ '$Id: Win32OperatingSystem.st,v 1.509 2014-11-08 17:14:37 stefan Exp $'
+    ^ '$Id: Win32OperatingSystem.st,v 1.510 2014-11-10 14:05:02 cg Exp $'
 
 ! !