diff -r 53cee4c20659 -r 48acb2bbb580 Win32OperatingSystem.st --- 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) {