--- a/Win32OperatingSystem.st Fri Mar 20 13:00:25 2020 +0100
+++ b/Win32OperatingSystem.st Mon Mar 23 16:11:42 2020 +0100
@@ -1733,7 +1733,7 @@
"/ should handle more codePages via GetConsoleOutputCP
outputEncoder := CharacterEncoder encoderNamed:('cp%1' bindWith:cp).
outputEncoder isNullEncoder ifTrue:[
- ('no encoder for CP%1' bindWith:cp) _errorPrintCR.
+ "/ ('no encoder for cp%1' bindWith:cp) _errorPrintCR.
"/ should we fallback here???
] ifFalse:[
ConsoleOutputEncoder := outputEncoder
@@ -5158,8 +5158,10 @@
%{
HANDLE h;
+ char _pathNameBuffer[MAXPATHLEN+1];
+ wchar_t _wPathNameBuffer[MAXPATHLEN+1];
char *name;
- wchar_t _wPathName[MAXPATHLEN+1];
+ wchar_t wName;
OBJ *ap;
int numAttrib;
int i, l;
@@ -5167,8 +5169,13 @@
if (__isStringLike(pathName)) {
name = __stringVal(pathName);
+ if (strlen(name) < MAXPATHLEN) {
+ strncpy(_pathNameBuffer, name, sizeof(_pathNameBuffer));
+ name = _pathNameBuffer;
+ } // else: CreateA will use object's string (and execute uninterruptable)
} else if (__isUnicode16String(pathName)) {
- _makeWchar(pathName, _wPathName, sizeof(_wPathName));
+ _makeWchar(pathName, _wPathNameBuffer, sizeof(_wPathNameBuffer));
+ wName = _wPathNameBuffer;
} else {
fileHandle = nil;
argumentError = @symbol(badPathName);
@@ -5242,7 +5249,7 @@
if (__isStringLike(pathName)) {
h = CreateFileA(name, access, share, 0 /* sa */, create, attr, 0 /* hTempl */);
} else {
- h = CreateFileW(_wPathName, access, share, 0 /* sa */, create, attr, 0 /* hTempl */);
+ h = CreateFileW(wName, access, share, 0 /* sa */, create, attr, 0 /* hTempl */);
}
if (h != INVALID_HANDLE_VALUE) {
@@ -5310,9 +5317,9 @@
if (__isStringLike(fullPathName)) {
#ifdef DO_WRAP_CALLS
{
- char _aPathName[MAXPATHLEN];
-
- strncpy(_aPathName, __stringVal(fullPathName), MAXPATHLEN-1); _aPathName[MAXPATHLEN-1] = '\0';
+ char _aPathName[MAXPATHLEN+1];
+
+ strncpy(_aPathName, __stringVal(fullPathName), MAXPATHLEN); _aPathName[MAXPATHLEN] = '\0';
do {
// do not cast to INT - will loose sign bit then!
success = (int)STX_API_NOINT_CALL1( "RemoveDirectoryA", RemoveDirectoryA, _aPathName);
@@ -8968,25 +8975,25 @@
getDomainName
"return the DNS domain this host is in.
Notice:
- not all systems support this; on some, 'unknown' is returned."
+ not all systems support this; on some, 'unknown' is returned."
|domainName|
DomainName notNil ifTrue:[
- ^ DomainName
+ ^ DomainName
].
domainName := self primGetComputerName:2.
domainName isEmptyOrNil ifTrue:[
- domainName := self getEnvironment:'DOMAIN'.
- domainName isNil ifTrue:[
- domainName := self getEnvironment:'DOMAINNAME'.
- ].
+ domainName := self getEnvironment:'DOMAIN'.
+ domainName isNil ifTrue:[
+ domainName := self getEnvironment:'DOMAINNAME'.
+ ].
].
domainName isEmptyOrNil ifTrue:[
- ^ 'unknown'.
+ ^ 'unknown'.
].
DomainName := domainName. "cache only, if it is fixed"
@@ -10297,16 +10304,16 @@
primGetComputerName:whatEnum
"return the domain or hostname we are running on:
typedef enum _COMPUTER_NAME_FORMAT {
- ComputerNameNetBIOS, // 0
- ComputerNameDnsHostname, // 1
- ComputerNameDnsDomain, // 2
- ComputerNameDnsFullyQualified, // 3
- ComputerNamePhysicalNetBIOS,
- ComputerNamePhysicalDnsHostname,
- ComputerNamePhysicalDnsDomain,
- ComputerNamePhysicalDnsFullyQualified,
- ComputerNameMax // 7
- } COMPUTER_NAME_FORMAT; "
+ ComputerNameNetBIOS, // 0
+ ComputerNameDnsHostname, // 1
+ ComputerNameDnsDomain, // 2
+ ComputerNameDnsFullyQualified, // 3
+ ComputerNamePhysicalNetBIOS,
+ ComputerNamePhysicalDnsHostname,
+ ComputerNamePhysicalDnsDomain,
+ ComputerNamePhysicalDnsFullyQualified,
+ ComputerNameMax // 7
+ } COMPUTER_NAME_FORMAT; "
%{ /* STACK: 2048 */
// Note: GetComputerNameExA can fail in certain locales!
@@ -10315,21 +10322,21 @@
DWORD buffSize = sizeof(bufferA);
if (GetComputerNameA(bufferA, &buffSize) == TRUE) {
- RETURN(__MKSTRING_L(bufferA, buffSize));
+ RETURN(__MKSTRING_L(bufferA, buffSize));
}
#else
WCHAR buffer[512];
DWORD buffSize = sizeof(buffer)/sizeof(buffer[0]);
if (GetComputerNameExW((COMPUTER_NAME_FORMAT)__intVal(whatEnum), buffer, &buffSize) == TRUE) {
- RETURN(__mkStringOrU16String_maxlen(buffer, buffSize));
- }
-#endif
-%}.
-
- "
- 0 to: 7 collect:[:i|
- OperatingSystem primGetComputerName:i
+ RETURN(__mkStringOrU16String_maxlen(buffer, buffSize));
+ }
+#endif
+%}.
+
+ "
+ 0 to: 7 collect:[:i|
+ OperatingSystem primGetComputerName:i
]
"
@@ -11401,8 +11408,8 @@
dateFormat
"Answer the date format string to be used dep. on the OS system value for date format.
One of DfMDY = Month-Day-Year
- DfDMY = Day-Month-Year
- DfYMD = Year-Month-Day
+ DfDMY = Day-Month-Year
+ DfYMD = Year-Month-Day
is mapped to the ST/X dateFormatString %(mon)-%(day)-%(year)"
|separatorString code|
@@ -11417,7 +11424,7 @@
^ '%(day)', separatorString, '%(mon)', separatorString, '%(year)'
"
- self dateFormat
+ self dateFormat
Date today printStringFormat:(self dateFormat)
"
@@ -11428,8 +11435,8 @@
dateFormatCode
"Answer the current system value for date format.
Answer DfMDY = Month-Day-Year = 0
- DfDMY = Day-Month-Year = 1
- DfYMD = Year-Month-Day = 2
+ DfDMY = Day-Month-Year = 1
+ DfYMD = Year-Month-Day = 2
"
"/ this is somewhat outdated, but windows maps the initProfile query to
@@ -11503,8 +11510,8 @@
language
"Answer the current system value for country name.
- Notice that windows uses a different format (iso 639-2/b ???),
- where the first two chars correspond to the standard iso language,
+ Notice that windows uses a different format (iso 639-2/b ???),
+ where the first two chars correspond to the standard iso language,
and the 3 third char represents the territory (somehow).
US-english which is 'en-us', is in windows ENU,
GB-english which is 'en-gb', is in windows ENG,
@@ -11539,8 +11546,8 @@
answer := self primGetProfileInt: 'Intl' keyName: aKeyName default:(-1 asUnsigned32).
^ answer = -1 asUnsigned32
- ifTrue: [ defaultValue ]
- ifFalse: [ answer ]
+ ifTrue: [ defaultValue ]
+ ifFalse: [ answer ]
"
self queryNationalProfileInt: 'iDate' default: 0
@@ -11557,12 +11564,12 @@
| extString result |
extString := String new: 80.
- result := self
- primGetProfileString:'Intl' keyName:aKeyName default:''
- returnedString:extString
- size:(extString size).
+ result := self
+ primGetProfileString:'Intl' keyName:aKeyName default:''
+ returnedString:extString
+ size:(extString size).
result > 0 ifTrue: [
- ^ extString copyFrom: 1 to: result
+ ^ extString copyFrom: 1 to: result
].
^ defaultValue
@@ -11701,16 +11708,16 @@
"commands to try for speech output"
^ #(
- "/ triples are:
- "/ -command
- "/ -commandline for default voice
- "/ -commandline for specific voice
- "/ -commandline for Speech Synthesis Markup Language (SSML) voice
- ('powershell'
- 'powershell -Command "Add-Type -AssemblyName System.Speech; (New-Object System.Speech.Synthesis.SpeechSynthesizer).Speak(''%2'');"'
- 'powershell -Command "Add-Type -AssemblyName System.Speech; $S=(New-Object System.Speech.Synthesis.SpeechSynthesizer);$S.SelectVoice(''%1'');$S.Speak(''%2'');"'
- 'powershell -Command "Add-Type -AssemblyName System.Speech; (New-Object System.Speech.Synthesis.SpeechSynthesizer).SpeakSsml(''%2'');"'
- )
+ "/ triples are:
+ "/ -command
+ "/ -commandline for default voice
+ "/ -commandline for specific voice
+ "/ -commandline for Speech Synthesis Markup Language (SSML) voice
+ ('powershell'
+ 'powershell -Command "Add-Type -AssemblyName System.Speech; (New-Object System.Speech.Synthesis.SpeechSynthesizer).Speak(''%2'');"'
+ 'powershell -Command "Add-Type -AssemblyName System.Speech; $S=(New-Object System.Speech.Synthesis.SpeechSynthesizer);$S.SelectVoice(''%1'');$S.Speak(''%2'');"'
+ 'powershell -Command "Add-Type -AssemblyName System.Speech; (New-Object System.Speech.Synthesis.SpeechSynthesizer).SpeakSsml(''%2'');"'
+ )
)
"
@@ -11727,26 +11734,26 @@
'powershell -Command "Add-Type -AssemblyName System.Speech; (New-Object System.Speech.Synthesis.SpeechSynthesizer).Speak(''hello'');"'
OperatingSystem
- executeCommand:
+ executeCommand:
'powershell -Command "Add-Type -AssemblyName System.Speech;$S = New-Object -TypeName System.Speech.Synthesis.SpeechSynthesizer;$S.voice;"'
- outputTo:Transcript
+ outputTo:Transcript
OperatingSystem
- executeCommand:
+ executeCommand:
'powershell -Command "Add-Type -AssemblyName System.Speech;$S = New-Object -TypeName System.Speech.Synthesis.SpeechSynthesizer;$S.GetInstalledVoices();"'
- outputTo:Transcript
+ outputTo:Transcript
OperatingSystem
- executeCommand:
+ executeCommand:
'powershell -Command "Add-Type -AssemblyName System.Speech; foreach ($v in (New-Object System.Speech.Synthesis.SpeechSynthesizer).GetInstalledVoices() ){ Write-Host $v.VoiceInfo.Name }"'
- outputTo:Transcript
+ outputTo:Transcript
END"
!
voiceInfo
"return a list of available (OS-specific) voice names plus info.
For each available voice, a triple is returned, containing:
- voiceName language_territory comment/description
+ voiceName language_territory comment/description
the language_territory (of the form en_EN / en_US etc.) gives a hint,
for which language the voice is best used.
@@ -11754,21 +11761,21 @@
For now, this is experimental and will be enhanced to ask the OS..."
^ #(
- ('default' 'en_US' 'the default system voice')
-
- #('Microsoft Zira Desktop' 'en_US' 'Isn''t it nice to have a computer that will talk to you?')
- #('Microsoft Hazel Desktop' 'en_GB' 'Isn''t it nice to have a computer that will talk to you?')
- #('Microsoft Hedda Desktop' 'de_DE' 'Danke, daß Sie mir zuhören')
- #('Microsoft Helena Desktop' 'es_ES' 'holla mondo')
- #('Microsoft Irina Desktop' 'ru_RU' 'привет мир')
- #('Microsoft Elsa Desktop' 'it_IT' 'ciao mondo')
- #('Microsoft Hortense Desktop' 'fr_FR' 'bonjour monde')
- #('Microsoft Helia Desktop' 'pt_PT' 'olá mundo')
- #('Microsoft Hanhan Desktop' 'zh_TW' '你好世界')
- #('Microsoft Tracy Desktop' 'zh_HK' '你好世界')
- #('Microsoft Huihui Desktop' 'zh_CN' '你好世界')
- #('Microsoft Haruka Desktop' 'ja_JP' 'こんにちは世界')
- )
+ ('default' 'en_US' 'the default system voice')
+
+ #('Microsoft Zira Desktop' 'en_US' 'Isn''t it nice to have a computer that will talk to you?')
+ #('Microsoft Hazel Desktop' 'en_GB' 'Isn''t it nice to have a computer that will talk to you?')
+ #('Microsoft Hedda Desktop' 'de_DE' 'Danke, daß Sie mir zuhören')
+ #('Microsoft Helena Desktop' 'es_ES' 'holla mondo')
+ #('Microsoft Irina Desktop' 'ru_RU' 'привет мир')
+ #('Microsoft Elsa Desktop' 'it_IT' 'ciao mondo')
+ #('Microsoft Hortense Desktop' 'fr_FR' 'bonjour monde')
+ #('Microsoft Helia Desktop' 'pt_PT' 'olá mundo')
+ #('Microsoft Hanhan Desktop' 'zh_TW' '你好世界')
+ #('Microsoft Tracy Desktop' 'zh_HK' '你好世界')
+ #('Microsoft Huihui Desktop' 'zh_CN' '你好世界')
+ #('Microsoft Haruka Desktop' 'ja_JP' 'こんにちは世界')
+ )
"<<END
OperatingSystem voiceInfo
@@ -11785,18 +11792,18 @@
OperatingSystem speak:'ciao mondo' voiceName:'Microsoft Elsa Desktop'
OperatingSystem speak:'olá mundo' voiceName:'Microsoft Helia Desktop'
OperatingSystem speak:'привет мир' voiceName:'Microsoft Irina Desktop'
- OperatingSystem speak:'こんにちは世界' voiceName:'Microsoft Haruka Desktop' "Kon'nichiwa sekai"
- OperatingSystem speak:'你好世界' voiceName:'Microsoft Hanhan Desktop' "Nǐ hǎo shìjiè"
- OperatingSystem speak:'你好世界' voiceName:'Microsoft Huihui Desktop' "Nǐ hǎo shìjiè"
- OperatingSystem speak:'hello' voiceName:'Microsoft Huihui Desktop' "Nǐ hǎo shìjiè"
+ OperatingSystem speak:'こんにちは世界' voiceName:'Microsoft Haruka Desktop' "Kon'nichiwa sekai"
+ OperatingSystem speak:'你好世界' voiceName:'Microsoft Hanhan Desktop' "Nǐ hǎo shìjiè"
+ OperatingSystem speak:'你好世界' voiceName:'Microsoft Huihui Desktop' "Nǐ hǎo shìjiè"
+ OperatingSystem speak:'hello' voiceName:'Microsoft Huihui Desktop' "Nǐ hǎo shìjiè"
Do do:
OperatingSystem
- executeCommand:
+ executeCommand:
'powershell -Command "Add-Type -AssemblyName System.Speech; foreach ($v in (New-Object System.Speech.Synthesis.SpeechSynthesizer).GetInstalledVoices() ){ Write-Host $v.VoiceInfo.Name; Write-Host $v.VoiceInfo.Culture }"'
- outputTo:Transcript
-END
+ outputTo:Transcript
+END
! !
!Win32OperatingSystem class methodsFor:'system management'!
@@ -20168,6 +20175,7 @@
char host[NI_MAXHOST];
char service[NI_MAXSERV];
+ char sockAddrLocal[1024];
char *hp = NULL, *sp = NULL;
int hsz = 0, ssz = 0;
int ret;
@@ -20196,10 +20204,19 @@
sockAddrSize = __byteArraySize(socketAddress);
sockAddrSize -= nInstBytes;
+ if (sockAddrSize > sizeof(sockAddrLocal)) {
+ error = @symbol(badArgument1);
+ goto err;
+ }
+ bp = (char *)(__byteArrayVal(socketAddress));
+ bp += nInstBytes;
+ memcpy(sockAddrLocal, bp, sockAddrSize);
+
if (!__isSmallInteger(flags)) {
error = @symbol(badArgument5);
goto err;
}
+
__flags = __intVal(flags);
#if defined(NI_NUMERICHOST)
@@ -20214,12 +20231,11 @@
do {
__threadErrno = 0;
// do not cast to INT - will loose sign bit then!
- ret = (int)(STX_WSA_NOINT_CALL7( "getnameinfo", getnameinfo, (struct sockaddr *)bp, (INT)sockAddrSize, hp, (INT)hsz, sp, (INT)ssz, (INT)__flags));
+ ret = (int)(STX_WSA_NOINT_CALL7( "getnameinfo", getnameinfo, (struct sockaddr *)sockAddrLocal, (INT)sockAddrSize, hp, (INT)hsz, sp, (INT)ssz, (INT)__flags));
} while ((ret < 0) && (__threadErrno == EINTR));
# else
__BEGIN_INTERRUPTABLE__
- ret = getnameinfo((struct sockaddr *)bp, sockAddrSize,
- hp, hsz, sp, ssz, __flags);
+ ret = getnameinfo((struct sockaddr *)sockAddrLocal, sockAddrSize, hp, hsz, sp, ssz, __flags);
__END_INTERRUPTABLE__
# endif
} while (ret != 0 && __threadErrno == EINTR);