Win32OperatingSystem.st
changeset 23130 48acb2bbb580
parent 23070 d45cd560ea79
child 23131 5782474bd56b
--- a/Win32OperatingSystem.st	Mon Jun 25 17:12:22 2018 +0200
+++ b/Win32OperatingSystem.st	Tue Jun 26 17:23:07 2018 +0200
@@ -712,6 +712,7 @@
 }
 
 #if 0
+
 // original: biased for 1.1.1601
 // obsolete...
 OBJ
@@ -725,7 +726,8 @@
     return(__MKLARGEINT64(1, (unsigned INT)(lTime & 0xFFFFFFFF), (unsigned INT)(lTime >> 32)));
 #endif
 }
-#endif
+
+#endif // 0
 
 // biased for 1.1.1970
 // (renamed to catch references from other classes)
@@ -792,7 +794,8 @@
     pft->dwLowDateTime = (UINT)(lTime & 0xFFFFFFFF);
     return(1);
 }
-#endif
+
+#endif // 0
 
 // biased for 1.1.1970
 // renamed to catch any references from other classes.
@@ -814,6 +817,10 @@
     return(1);
 }
 
+UINT WINAPI GetSystemWow64Directory(
+  _Out_ LPTSTR lpBuffer,
+  _In_  UINT   uSize
+);
 %}
 ! !
 
@@ -3653,8 +3660,8 @@
     |shell args wDir cmdName path commandString|
 
     aCommandString isNonByteCollection ifTrue:[
-        "easy: the caller does not want a shell to be executed"
-        ^ Array with:aCommandString first with:(aCommandString asStringWith:' ') with:nil.
+	"easy: the caller does not want a shell to be executed"
+	^ Array with:aCommandString first with:(aCommandString asStringWith:' ') with:nil.
     ].
 
     "/
@@ -3680,57 +3687,57 @@
     cmdName := (aCommandString ? '') withoutSeparators.
 
     (cmdName isEmpty or:[cmdName includesAny:'<>|&']) ifFalse:[
-        "/ test whether the command is a plain executable;
-        "/ if so, no shell is required
-        |index file suffix|
-
-        cmdName first = $" ifTrue:[
-            index := cmdName indexOf:$" startingAt:2.
-        ] ifFalse:[
-            index := 1.
-        ].
-        index := cmdName indexOfSeparatorStartingAt:index.
-        index ~~ 0 ifTrue:[
-            cmdName := cmdName copyFrom:1 to:(index-1).
-            args := cmdName copyFrom:(index+1).
-        ] ifFalse:[
-            args := ''.
-        ].
-
-        (cmdName first = $" and:[cmdName last = $"]) ifTrue:[
-            cmdName := (cmdName copyFrom:2 to:cmdName size - 1) withoutSeparators.
-        ].
-        file := cmdName asFilename.
-        file suffix isEmpty ifTrue:[
-            file := file withSuffix:'exe'.
-        ].
-        path := file fullAlternativePathName.
-        (OperatingSystem getBinaryType:path) notNil ifTrue:[
-            "/ is an executable, no shell required
-            ^ Array with:path with:aCommandString with:nil.
+	"/ test whether the command is a plain executable;
+	"/ if so, no shell is required
+	|index file suffix|
+
+	cmdName first = $" ifTrue:[
+	    index := cmdName indexOf:$" startingAt:2.
+	] ifFalse:[
+	    index := 1.
+	].
+	index := cmdName indexOfSeparatorStartingAt:index.
+	index ~~ 0 ifTrue:[
+	    cmdName := cmdName copyFrom:1 to:(index-1).
+	    args := cmdName copyFrom:(index+1).
+	] ifFalse:[
+	    args := ''.
+	].
+
+	(cmdName first = $" and:[cmdName last = $"]) ifTrue:[
+	    cmdName := (cmdName copyFrom:2 to:cmdName size - 1) withoutSeparators.
+	].
+	file := cmdName asFilename.
+	file suffix isEmpty ifTrue:[
+	    file := file withSuffix:'exe'.
+	].
+	path := file fullAlternativePathName.
+	(OperatingSystem getBinaryType:path) notNil ifTrue:[
+	    "/ is an executable, no shell required
+	    ^ Array with:path with:aCommandString with:nil.
 "/                ^ Array with:path with:(path, ' ', args).
-        ].
-        path := self pathOfCommand:cmdName.
-        (path notNil and:[(OperatingSystem getBinaryType:path) notNil]) ifTrue:[
-            "/ is an executable, no shell required
-            ^ Array with:path with:aCommandString with:nil.
+	].
+	path := self pathOfCommand:cmdName.
+	(path notNil and:[(OperatingSystem getBinaryType:path) notNil]) ifTrue:[
+	    "/ is an executable, no shell required
+	    ^ Array with:path with:aCommandString with:nil.
 "/                ^ Array with:path with:(path, ' ', args).
-        ].
+	].
     ].
 
     shell := self getEnvironment:'COMSPEC'.
     shell isNil ifTrue:[
-        wDir := self getWindowsSystemDirectory asFilename.
-        shell := #('cmd.exe' 'command.com') detect:[:eachCommand|
-                        (wDir / eachCommand) isExecutableProgram
-                    ] ifNone:[
-                        self error:'no cmd.exe available'.
-                    ].
-        shell := (wDir / shell) pathName.
+	wDir := self getWindowsSystemDirectory asFilename.
+	shell := #('cmd.exe' 'command.com') detect:[:eachCommand|
+			(wDir / eachCommand) isExecutableProgram
+		    ] ifNone:[
+			self error:'no cmd.exe available'.
+		    ].
+	shell := (wDir / shell) pathName.
     ].
 
     cmdName isEmpty ifTrue:[
-        ^ Array with:shell with:'' with:nil.
+	^ Array with:shell with:'' with:nil.
     ].
 
     commandString := aCommandString.
@@ -4594,46 +4601,46 @@
 
     if (__isStringLike(fullPathName)) {
 #ifdef DO_WRAP_CALLS
-        {
-            char _aPathName[MAXPATHLEN];
-
-            strncpy(_aPathName, __stringVal(fullPathName), MAXPATHLEN-1); _aPathName[MAXPATHLEN-1] = '\0';
-            do {
-                // do not cast to INT - will loose sign bit then!
-                success = (int)STX_API_NOINT_CALL1( "DeleteFileA", DeleteFileA, _aPathName);
-            } while (!success && (__threadErrno == EINTR));
-        }
-#else
-        success = DeleteFileA((char *)__stringVal(fullPathName));
-        if (!success) __threadErrno = __WIN32_ERR(GetLastError());
+	{
+	    char _aPathName[MAXPATHLEN];
+
+	    strncpy(_aPathName, __stringVal(fullPathName), MAXPATHLEN-1); _aPathName[MAXPATHLEN-1] = '\0';
+	    do {
+		// do not cast to INT - will loose sign bit then!
+		success = (int)STX_API_NOINT_CALL1( "DeleteFileA", DeleteFileA, _aPathName);
+	    } while (!success && (__threadErrno == EINTR));
+	}
+#else
+	success = DeleteFileA((char *)__stringVal(fullPathName));
+	if (!success) __threadErrno = __WIN32_ERR(GetLastError());
 #endif
     } else if (__isUnicode16String(fullPathName)) {
 #ifdef DO_WRAP_CALLS
-        {
-            wchar_t _wPathName[MAXPATHLEN+1];
-
-            _makeWchar(fullPathName, _wPathName, sizeof(_wPathName));
-            do {
-                // do not cast to INT - will loose sign bit then!
-                success = (int)(STX_API_NOINT_CALL1( "DeleteFileW", DeleteFileW, _wPathName));
-            } while (!success && (__threadErrno == EINTR));
-        }
-#else
-        success = DeleteFileW((wchar_t *)__unicode16StringVal(fullPathName));
-        if (!success) __threadErrno = __WIN32_ERR(GetLastError());
+	{
+	    wchar_t _wPathName[MAXPATHLEN+1];
+
+	    _makeWchar(fullPathName, _wPathName, sizeof(_wPathName));
+	    do {
+		// do not cast to INT - will loose sign bit then!
+		success = (int)(STX_API_NOINT_CALL1( "DeleteFileW", DeleteFileW, _wPathName));
+	    } while (!success && (__threadErrno == EINTR));
+	}
+#else
+	success = DeleteFileW((wchar_t *)__unicode16StringVal(fullPathName));
+	if (!success) __threadErrno = __WIN32_ERR(GetLastError());
 #endif
     }
 
     if (success) {
-        RETURN (nil);
+	RETURN (nil);
     }
 
     error = __mkSmallInteger(__threadErrno);
 %}.
 
     error notNil ifTrue:[
-        LastErrorNumber := error.
-        ^ self errorHolderForNumber:error.
+	LastErrorNumber := error.
+	^ self errorHolderForNumber:error.
     ].
 
     ^ self primitiveFailed
@@ -5071,37 +5078,37 @@
     retryCtr := 10.
 
     [
-        |linkInfo|
-
-        lastErrorHolder := self basicRemoveFile:fullPathName.
-        lastErrorHolder isNil ifTrue:[
-            "succesfully removed"
-            ^ nil
-        ].
-
-        retryCtr := retryCtr - 1.
-
-        linkInfo := self linkInfoOf:fullPathName.
-        (linkInfo isNil             "/ file does not exist
-         or:[linkInfo isDirectory   "/ cannot remove directory
-         or:[(self isWritable:fullPathName) not]]) ifTrue:[
-            "when the file is not writable, we know defintely,
-             that the remove fails - no need to retry"
-            ^ lastErrorHolder
-        ].
-
-        Transcript showCR:('error caught while removing %1: %2'
-                            bindWith:fullPathName with:lastErrorHolder).
-
-        Delay waitForSeconds:0.1.
+	|linkInfo|
+
+	lastErrorHolder := self basicRemoveFile:fullPathName.
+	lastErrorHolder isNil ifTrue:[
+	    "succesfully removed"
+	    ^ nil
+	].
+
+	retryCtr := retryCtr - 1.
+
+	linkInfo := self linkInfoOf:fullPathName.
+	(linkInfo isNil             "/ file does not exist
+	 or:[linkInfo isDirectory   "/ cannot remove directory
+	 or:[(self isWritable:fullPathName) not]]) ifTrue:[
+	    "when the file is not writable, we know defintely,
+	     that the remove fails - no need to retry"
+	    ^ lastErrorHolder
+	].
+
+	Transcript showCR:('error caught while removing %1: %2'
+			    bindWith:fullPathName with:lastErrorHolder).
+
+	Delay waitForSeconds:0.1.
     ] doWhile:[retryCtr > 0].
 
     ^ lastErrorHolder.
 
     "
-        self removeFile:'c:\windows'
-        self removeFile:'CVS'
-        self removeFile:'.....xxxxx.....Murks'
+	self removeFile:'c:\windows'
+	self removeFile:'CVS'
+	self removeFile:'.....xxxxx.....Murks'
     "
 !
 
@@ -5834,7 +5841,7 @@
 	  */
 	pGetDiskFreeSpaceEx = (P_GDFSE)GetProcAddress (
 					    GetModuleHandle ("kernel32.dll"),
-							     "GetDiskFreeSpaceExA");
+					    "GetDiskFreeSpaceExA");
 	if (pGetDiskFreeSpaceEx) {
 	    fResult = pGetDiskFreeSpaceEx (__stringVal(volumeName),
 				 (PULARGE_INTEGER)&i64FreeBytesForUsersQuota,
@@ -6130,6 +6137,29 @@
     "
 !
 
+getSystemWow64Directory
+    "retrieves the system's wow64 directory,
+     or nil, if running on a 32bit system"
+
+    | rslt |
+
+%{  /* STACK: 8000*/
+    char buffer[MAXPATHLEN+1];
+
+    int __rslt;
+
+    __rslt = GetSystemWow64DirectoryW(buffer, MAXPATHLEN);
+    if (__rslt == TRUE) {
+	rslt = __mkStringOrU16String_maxlen(_aPathName, MAXPATHLEN);
+    } else {
+	rslt = false;
+    }
+%}.
+    ^ rslt
+
+    "Modified: / 11-02-2014 / 21:18:20 / cg"
+!
+
 getVolumeInformation: rootPath
     name: volumeNameBuffer
     nameSize: volumeNameSize
@@ -6202,42 +6232,42 @@
 
     if (__isStringLike(aPathName)) {
 #ifdef DO_WRAP_CALLS
-        char _aPathName[MAXPATHLEN];
-
-        strncpy(_aPathName, __stringVal(aPathName), MAXPATHLEN-1); _aPathName[MAXPATHLEN-1] = '\0';
-        do {
-            __threadErrno = 0;
-            // do not cast to INT - will loose sign bit then!
-            ret = (int)(STX_API_NOINT_CALL1( "GetFileAttributesA", GetFileAttributesA, _aPathName));
-        } while ((ret == INVALID_FILE_ATTRIBUTES) && (__threadErrno == EINTR));
-#else
-        ret = GetFileAttributesA((char *) __stringVal(aPathName));
-        if (ret == INVALID_FILE_ATTRIBUTES) {
-            __threadErrno = __WIN32_ERR(GetLastError());
-        }
+	char _aPathName[MAXPATHLEN];
+
+	strncpy(_aPathName, __stringVal(aPathName), MAXPATHLEN-1); _aPathName[MAXPATHLEN-1] = '\0';
+	do {
+	    __threadErrno = 0;
+	    // do not cast to INT - will loose sign bit then!
+	    ret = (int)(STX_API_NOINT_CALL1( "GetFileAttributesA", GetFileAttributesA, _aPathName));
+	} while ((ret == INVALID_FILE_ATTRIBUTES) && (__threadErrno == EINTR));
+#else
+	ret = GetFileAttributesA((char *) __stringVal(aPathName));
+	if (ret == INVALID_FILE_ATTRIBUTES) {
+	    __threadErrno = __WIN32_ERR(GetLastError());
+	}
 #endif
     } else if (__isUnicode16String(aPathName)) {
-        wchar_t _wPathName[MAXPATHLEN+1];
-
-        _makeWchar(aPathName, _wPathName, sizeof(_wPathName));
+	wchar_t _wPathName[MAXPATHLEN+1];
+
+	_makeWchar(aPathName, _wPathName, sizeof(_wPathName));
 #ifdef DO_WRAP_CALLS
-        do {
-            __threadErrno = 0;
-            // do not cast to INT - will loose sign bit then!
-            ret = (int)(STX_API_NOINT_CALL1( "GetFileAttributesW", GetFileAttributesW, _wPathName));
-        } while ((ret == INVALID_FILE_ATTRIBUTES) && (__threadErrno == EINTR));
-#else
-        ret = GetFileAttributesW(_wPathName);
-        if (ret == INVALID_FILE_ATTRIBUTES) {
-            __threadErrno = __WIN32_ERR(GetLastError());
-        }
+	do {
+	    __threadErrno = 0;
+	    // do not cast to INT - will loose sign bit then!
+	    ret = (int)(STX_API_NOINT_CALL1( "GetFileAttributesW", GetFileAttributesW, _wPathName));
+	} while ((ret == INVALID_FILE_ATTRIBUTES) && (__threadErrno == EINTR));
+#else
+	ret = GetFileAttributesW(_wPathName);
+	if (ret == INVALID_FILE_ATTRIBUTES) {
+	    __threadErrno = __WIN32_ERR(GetLastError());
+	}
 #endif
     } else
-        goto err;
+	goto err;
 
     if (ret == INVALID_FILE_ATTRIBUTES) {
-        @global(LastErrorNumber) = __mkSmallInteger(__threadErrno);
-        RETURN ( false );
+	@global(LastErrorNumber) = __mkSmallInteger(__threadErrno);
+	RETURN ( false );
     }
     RETURN ( (ret & FILE_ATTRIBUTE_DIRECTORY) ? true : false);
 err:;
@@ -6245,7 +6275,7 @@
     ^ self primitiveFailed
 
     "an alternative implementation would be:
-        ^ (self infoOf:aPathName) type == #directory
+	^ (self infoOf:aPathName) type == #directory
     "
     "
      self isDirectory:'c:\bbbbbb'
@@ -9880,7 +9910,8 @@
 	// console_printf("hAdvapi32: %x\n", hAdvapi32);
 	if (hAdvapi32) {
 	    P_RtlGenRandom = (BOOL (__stdcall *)(PVOID , ULONG))
-				GetProcAddress(hAdvapi32, "SystemFunction036");
+				GetProcAddress(hAdvapi32,
+				"SystemFunction036");
 	    // console_printf("P_RtlGenRandom: %x\n", P_RtlGenRandom);
 	    if (P_RtlGenRandom == 0) {
 		goto error;
@@ -11169,7 +11200,7 @@
 		    pTzSpecificLocalTimeToSystemTime =
 			(P_TzSpecificLocalTimeToSystemTime)
 			    GetProcAddress ( GetModuleHandle ("kernel32.dll"),
-							      "TzSpecificLocalTimeToSystemTime");
+					     "TzSpecificLocalTimeToSystemTime");
 		}
 		if (!pTzSpecificLocalTimeToSystemTime(0, &sysTime, &sysTime))
 		    goto error;
@@ -11473,7 +11504,9 @@
 
 	    if (! haveTriedToGet_P_GetTimeZoneInformationForYear) {
 		pGetTimeZoneInformationForYear =
-		    (P_GetTimeZoneInformationForYear)GetProcAddress(GetModuleHandle("kernel32.dll"), "GetTimeZoneInformationForYear");
+		    (P_GetTimeZoneInformationForYear)GetProcAddress(
+							GetModuleHandle("kernel32.dll"),
+							"GetTimeZoneInformationForYear");
 		haveTriedToGet_P_GetTimeZoneInformationForYear = 1;
 	    }
 	    if (pGetTimeZoneInformationForYear == NULL) {
@@ -11666,7 +11699,9 @@
 
 	    if (! haveTriedToGet_P_GetTimeZoneInformationForYear) {
 		pGetTimeZoneInformationForYear =
-		    (P_GetTimeZoneInformationForYear)GetProcAddress(GetModuleHandle("kernel32.dll"), "GetTimeZoneInformationForYear");
+		    (P_GetTimeZoneInformationForYear)GetProcAddress(
+							GetModuleHandle("kernel32.dll"),
+							"GetTimeZoneInformationForYear");
 		haveTriedToGet_P_GetTimeZoneInformationForYear = 1;
 	    }
 	    if (pGetTimeZoneInformationForYear == NULL) {