Win32OperatingSystem.st
branchjv
changeset 17742 3fef0ed4c2d5
parent 17735 6a5bc05f696a
child 17746 2c33aabf3828
--- a/Win32OperatingSystem.st	Sun Dec 27 19:45:23 2009 +0000
+++ b/Win32OperatingSystem.st	Sun Dec 27 20:16:54 2009 +0000
@@ -3229,65 +3229,64 @@
     hasRedirection := (aCommandString isNil or:[aCommandString includesAny:'<>|']).
 
     hasRedirection ifFalse:[
-	"/ test whether the commandString is an executable;
-	"/ then, no shell is required
-	cmdName := aCommandString withoutSeparators.
-	(cmdName notEmpty and:[(cmdName startsWith:$") not]) ifTrue:[
-	    |index file suffix|
-
-	    index := cmdName indexOfSeparatorStartingAt:1.
-	    index ~~ 0 ifTrue:[
-		args := cmdName copyFrom:(index+1).
-		cmdName := cmdName copyFrom:1 to:(index-1).
-	    ] ifFalse:[
-		args := ''.
-	    ].
-
-	    file   := cmdName asFilename.
-	    suffix := file suffix.
-
-	    suffix isEmptyOrNil ifTrue:[
-		suffix := 'exe'.
-		file := file withSuffix:suffix.
-	    ].
-
-	    (file exists and:[suffix = 'exe' or:[suffix = 'com']]) ifTrue:[
-		"/ is an executable, no shell required
-		path := file fullAlternativePathName.
-		^ Array with:path with:aCommandString.
+        "/ test whether the commandString is an executable;
+        "/ then, no shell is required
+        cmdName := aCommandString withoutSeparators.
+        (cmdName notEmpty and:[(cmdName startsWith:$") not]) ifTrue:[
+            |index file suffix|
+
+            index := cmdName indexOfSeparatorStartingAt:1.
+            index ~~ 0 ifTrue:[
+                args := cmdName copyFrom:(index+1).
+                cmdName := cmdName copyFrom:1 to:(index-1).
+            ] ifFalse:[
+                args := ''.
+            ].
+
+            file   := cmdName asFilename.
+            suffix := file suffix.
+
+            suffix isEmptyOrNil ifTrue:[
+                suffix := 'exe'.
+                file := file withSuffix:suffix.
+            ].
+
+            (file exists and:[suffix = 'exe' or:[suffix = 'com']]) ifTrue:[
+                "/ is an executable, no shell required
+                path := file fullAlternativePathName.
+                ^ Array with:path with:aCommandString.
 "/                ^ Array with:path with:(path, ' ', args).
-	    ].
-	    path := self pathOfCommand:cmdName.
-	    path notNil ifTrue:[
-		"/ is an executable, no shell required
-		^ Array with:path with:aCommandString.
+            ].
+            path := self pathOfCommand:cmdName.
+            path notNil ifTrue:[
+                "/ is an executable, no shell required
+                ^ Array with:path with:aCommandString.
 "/                ^ Array with:path with:(path, ' ', args).
-	    ].
-	].
+            ].
+        ].
     ].
 
     shell := self getEnvironment:'COMSPEC'.
     shell isNil ifTrue:[
-	wDir := self getWindowsSystemDirectory asFilename.
-	shell := (wDir construct:'cmd.exe').
-	shell isExecutable ifFalse:[
-	    shell := (wDir construct:'command.com').
-	    shell isExecutable ifFalse:[
-		self error:'no command.com available'.
-	    ]
-	].
-	shell := shell pathName.
-    ].
-    aCommandString isNil ifTrue:[
-	^ Array with:shell with:nil
-    ].
-
-    ^ Array with:shell with:('/c "' , aCommandString , '"' )
+        wDir := self getWindowsSystemDirectory asFilename.
+        shell := #('cmd.exe' 'command.com') detect:[:eachCommand|
+                        (wDir / eachCommand) isExecutable
+                    ] ifNone:[
+                        self error:'no cmd.exe available'.
+                    ].
+        shell := (wDir / shell) pathName.
+    ].
+
+    aCommandString isEmptyOrNil ifTrue:[
+        ^ Array with:shell with:nil
+    ].
+
+    ^ Array with:shell with:(' /c "' , aCommandString, '"')
 
    "
      self commandAndArgsForOSCommand:'diff'
      self commandAndArgsForOSCommand:'dir/w'
-     self executeCommand:'dir >nul:'
+     self commandAndArgsForOSCommand:'dir >nul:'
    "
 
     "Modified: / 20-01-1998 / 16:57:19 / md"
@@ -3298,48 +3297,48 @@
     "Internal lowLevel entry for combined fork & exec for WIN32
 
      If fork is false (chain a command):
-	 execute the OS command specified by the argument, aCommandPath, with
-	 arguments in argArray (no arguments, if nil).
-	 If successful, this method does not return and smalltalk is gone.
-	 If not successful, it does return.
-	 Normal use is with forkForCommand.
+         execute the OS command specified by the argument, aCommandPath, with
+         arguments in argArray (no arguments, if nil).
+         If successful, this method does not return and smalltalk is gone.
+         If not successful, it does return.
+         Normal use is with forkForCommand.
 
      If fork is true (subprocess command execution):
-	fork a child to do the above.
-	The process id of the child process is returned; nil if the fork failed.
+        fork a child to do the above.
+        The process id of the child process is returned; nil if the fork failed.
 
      fdArray contains the filedescriptors, to be used for the child (if fork is true).
-	fdArray[1] = 15 -> use fd 15 as stdin.
-	If an element of the array is set to nil, the corresponding filedescriptor
-	will be closed for the child.
-	fdArray[0] == StdIn for child
-	fdArray[1] == StdOut for child
-	fdArray[2] == StdErr for child
-	on VMS, these must be channels as returned by createMailBox.
+        fdArray[1] = 15 -> use fd 15 as stdin.
+        If an element of the array is set to nil, the corresponding filedescriptor
+        will be closed for the child.
+        fdArray[0] == StdIn for child
+        fdArray[1] == StdOut for child
+        fdArray[2] == StdErr for child
+        on VMS, these must be channels as returned by createMailBox.
 
      NOTE that in WIN32 the fds are HANDLES.
 
      If newPgrp is true, the subprocess will be established in a new process group.
-	The processgroup will be equal to id.
-	newPgrp is not used on WIN32 and VMS systems."
+        The processgroup will be equal to id.
+        newPgrp is not used on WIN32 and VMS systems."
 
     |dirPath rslt|
 
     aDirectory notNil ifTrue:[
-	dirPath := aDirectory asFilename asAbsoluteFilename osNameForDirectory.
-	(dirPath endsWith:':') ifTrue:[
-	    dirPath := dirPath , '\'.
-	].
+        dirPath := aDirectory asFilename asAbsoluteFilename osNameForDirectory.
+        (dirPath endsWith:':') ifTrue:[
+            dirPath := dirPath , '\'.
+        ].
     ].
 
     rslt := self
-	primExec:aCommandPath
-	commandLine:argString
-	fileDescriptors:fdArray
-	fork:doFork
-	newPgrp:newPgrp
-	inPath:dirPath
-	createFlags:nil.
+        primExec:aCommandPath
+        commandLine:argString
+        fileDescriptors:fdArray
+        fork:doFork
+        newPgrp:newPgrp
+        inPath:dirPath
+        createFlags:nil.
 
 "/ 'created ' print. cmdLine print. ' -> ' print. rslt printCR.
     ^ rslt
@@ -3366,34 +3365,34 @@
     |nullStream in out err rslt auxFd|
 
     (in := anExternalInStream) isNil ifTrue:[
-	nullStream := Filename nullDevice readWriteStream.
-	in := nullStream.
+        nullStream := Filename nullDevice readWriteStream.
+        in := nullStream.
     ].
     (out := anExternalOutStream) isNil ifTrue:[
-	nullStream isNil ifTrue:[nullStream := Filename nullDevice writeStream].
-	out := nullStream.
+        nullStream isNil ifTrue:[nullStream := Filename nullDevice writeStream].
+        out := nullStream.
     ].
     (err := anExternalErrStream) isNil ifTrue:[
-	err := out
+        err := out
     ].
     anAuxiliaryStream notNil ifTrue:[
-	auxFd := anAuxiliaryStream fileDescriptor
+        auxFd := anAuxiliaryStream fileDescriptor
     ].
 
     rslt := self
-	exec:commandString
-	withArguments:argString
-	environment:anEvironmentDictionary
-	fileDescriptors:(Array with:in fileDescriptor
-			       with:out fileDescriptor
-			       with:err fileDescriptor
-			       with:auxFd)
-	fork:true
-	newPgrp:true "/ false
-	inDirectory:dir.
+        exec:commandString
+        withArguments:argString
+        environment:anEvironmentDictionary
+        fileDescriptors:(Array with:in fileDescriptor
+                               with:out fileDescriptor
+                               with:err fileDescriptor
+                               with:auxFd)
+        fork:true
+        newPgrp:true "/ false
+        inDirectory:dir.
 
     nullStream notNil ifTrue:[
-	nullStream close.
+        nullStream close.
     ].
     ^ rslt
 
@@ -3416,7 +3415,7 @@
      The following will no longer work. monitorPid has disappeared
 
      pid notNil ifTrue:[
-	 Processor monitorPid:pid action:[:OSstatus | sema signal ].
+         Processor monitorPid:pid action:[:OSstatus | sema signal ].
      ].
      in close.
      out close.
@@ -3551,136 +3550,136 @@
     SECURITY_DESCRIPTOR sd;
 
     if ((__isStringLike(commandPath) || (commandPath == nil)) && __isStringLike(commandLine)) {
-	if (commandPath != nil) {
-	    cmdPath = __stringVal(commandPath);
-	}
-	cmdLine = __stringVal(commandLine);
-
-	if (__isStringLike(dirName)) {
-	    dir = __stringVal(dirName);
-	}
-
-	/*
-	 * create descriptors as req'd
-	 */
-	memset(&sa, 0, sizeof (sa));
-	sa.nLength = sizeof( sa );
-	sa.lpSecurityDescriptor = NULL;
-	sa.bInheritHandle = TRUE;
-	InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
-	SetSecurityDescriptorDacl(&sd, -1, 0, 0);
-
-	sa.lpSecurityDescriptor = &sd;
-	memset(&lppiProcInfo, 0, sizeof (lppiProcInfo));
-
-	memset(&lpsiStartInfo, 0, sizeof (lpsiStartInfo));
-	lpsiStartInfo.cb                = sizeof(lpsiStartInfo);
-	lpsiStartInfo.lpReserved        = NULL;
-	lpsiStartInfo.lpDesktop         = NULL;
-	lpsiStartInfo.lpTitle           = NULL;
-	lpsiStartInfo.dwX               = 0;
-	lpsiStartInfo.dwY               = 0;
-	lpsiStartInfo.dwXSize           = 100;
-	lpsiStartInfo.dwYSize           = 100;
-	lpsiStartInfo.dwXCountChars     = 0;
-	lpsiStartInfo.dwYCountChars     = 0;
-	lpsiStartInfo.dwFillAttribute   = 0;
-	if (0 /*__isWinNT*/) {
-	    lpsiStartInfo.dwFlags           = STARTF_USESTDHANDLES;
-	    lpsiStartInfo.wShowWindow       = SW_SHOWDEFAULT;
-	} else {
-	    lpsiStartInfo.dwFlags           = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES /*| STARTF_USEPOSITION*/;
-	    lpsiStartInfo.wShowWindow       = SW_HIDE /*SW_SHOWDEFAULT*/;
-	}
-	lpsiStartInfo.cbReserved2       = 0;
-	lpsiStartInfo.lpReserved2       = NULL;
-	lpsiStartInfo.hStdInput         = NULL;
-	lpsiStartInfo.hStdOutput        = NULL;
-	lpsiStartInfo.hStdError         = NULL;
-
-	/*
-	 * set create process flags
-	 * if the flags arg is nil, use common defaults;
-	 * if non-nil, it must be a positive integer containing the fdwCreate bits.
-	 */
-	if (flagsOrNil != nil) {
-	    fdwCreate = __longIntVal(flagsOrNil);
-	} else {
-	    if (0 /* __isWinNT */)
-		fdwCreate = 0; //IDLE_PRIORITY_CLASS;
-	    else
-		fdwCreate = CREATE_NEW_CONSOLE; //|IDLE_PRIORITY_CLASS; // DETACHED_PROCESS; // NORMAL_PRIORITY_CLASS ;
-
-	    if (newPgrp == true) {
-		fdwCreate |= CREATE_NEW_PROCESS_GROUP;
-	    }
-	    fdwCreate |= CREATE_DEFAULT_ERROR_MODE;
-	}
-
-	if (fdArray == nil) {
-	    lpsiStartInfo.hStdInput  = (HANDLE) _get_osfhandle (0);
-	    lpsiStartInfo.hStdOutput = (HANDLE) _get_osfhandle (1);
-	    lpsiStartInfo.hStdError  = (HANDLE) _get_osfhandle (2);
-	} else if (__isArrayLike(fdArray) && (__arraySize(fdArray) >= 3)) {
-	    if (__ArrayInstPtr(fdArray)->a_element[0] != nil) {
-		if (__isExternalAddressLike(__ArrayInstPtr(fdArray)->a_element[0])) {
-		    lpsiStartInfo.hStdInput = _HANDLEVal(__ArrayInstPtr(fdArray)->a_element[0]);
-		} else {
-		    lpsiStartInfo.hStdInput = (HANDLE) _get_osfhandle (__intVal(__ArrayInstPtr(fdArray)->a_element[0]));
-		}
-	    }
-	    if (__ArrayInstPtr(fdArray)->a_element[1] != nil) {
-		if (__isExternalAddressLike(__ArrayInstPtr(fdArray)->a_element[1])) {
-		    lpsiStartInfo.hStdOutput = _HANDLEVal(__ArrayInstPtr(fdArray)->a_element[1]);
-		} else {
-		    lpsiStartInfo.hStdOutput = (HANDLE) _get_osfhandle (__intVal(__ArrayInstPtr(fdArray)->a_element[1]));
-		}
-	    }
-	    if (__ArrayInstPtr(fdArray)->a_element[2] != nil) {
-		if (__isExternalAddressLike(__ArrayInstPtr(fdArray)->a_element[2])) {
-		    lpsiStartInfo.hStdError  = _HANDLEVal(__ArrayInstPtr(fdArray)->a_element[2]);
-		} else {
-		    lpsiStartInfo.hStdError = (HANDLE) _get_osfhandle (__intVal(__ArrayInstPtr(fdArray)->a_element[2]));
-		}
-	    }
+        if (commandPath != nil) {
+            cmdPath = __stringVal(commandPath);
+        }
+        cmdLine = __stringVal(commandLine);
+
+        if (__isStringLike(dirName)) {
+            dir = __stringVal(dirName);
+        }
+
+        /*
+         * create descriptors as req'd
+         */
+        memset(&sa, 0, sizeof (sa));
+        sa.nLength = sizeof( sa );
+        sa.lpSecurityDescriptor = NULL;
+        sa.bInheritHandle = TRUE;
+        InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
+        SetSecurityDescriptorDacl(&sd, -1, 0, 0);
+
+        sa.lpSecurityDescriptor = &sd;
+        memset(&lppiProcInfo, 0, sizeof (lppiProcInfo));
+
+        memset(&lpsiStartInfo, 0, sizeof (lpsiStartInfo));
+        lpsiStartInfo.cb                = sizeof(lpsiStartInfo);
+        lpsiStartInfo.lpReserved        = NULL;
+        lpsiStartInfo.lpDesktop         = NULL;
+        lpsiStartInfo.lpTitle           = NULL;
+        lpsiStartInfo.dwX               = 0;
+        lpsiStartInfo.dwY               = 0;
+        lpsiStartInfo.dwXSize           = 100;
+        lpsiStartInfo.dwYSize           = 100;
+        lpsiStartInfo.dwXCountChars     = 0;
+        lpsiStartInfo.dwYCountChars     = 0;
+        lpsiStartInfo.dwFillAttribute   = 0;
+        if (0 /*__isWinNT*/) {
+            lpsiStartInfo.dwFlags           = STARTF_USESTDHANDLES;
+            lpsiStartInfo.wShowWindow       = SW_SHOWDEFAULT;
+        } else {
+            lpsiStartInfo.dwFlags           = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES /*| STARTF_USEPOSITION*/;
+            lpsiStartInfo.wShowWindow       = SW_HIDE /*SW_SHOWDEFAULT*/;
+        }
+        lpsiStartInfo.cbReserved2       = 0;
+        lpsiStartInfo.lpReserved2       = NULL;
+        lpsiStartInfo.hStdInput         = NULL;
+        lpsiStartInfo.hStdOutput        = NULL;
+        lpsiStartInfo.hStdError         = NULL;
+
+        /*
+         * set create process flags
+         * if the flags arg is nil, use common defaults;
+         * if non-nil, it must be a positive integer containing the fdwCreate bits.
+         */
+        if (flagsOrNil != nil) {
+            fdwCreate = __longIntVal(flagsOrNil);
+        } else {
+            if (0 /* __isWinNT */)
+                fdwCreate = 0; //IDLE_PRIORITY_CLASS;
+            else
+                fdwCreate = CREATE_NEW_CONSOLE; //|IDLE_PRIORITY_CLASS; // DETACHED_PROCESS; // NORMAL_PRIORITY_CLASS ;
+
+            if (newPgrp == true) {
+                fdwCreate |= CREATE_NEW_PROCESS_GROUP;
+            }
+            fdwCreate |= CREATE_DEFAULT_ERROR_MODE;
+        }
+
+        if (fdArray == nil) {
+            lpsiStartInfo.hStdInput  = (HANDLE) _get_osfhandle (0);
+            lpsiStartInfo.hStdOutput = (HANDLE) _get_osfhandle (1);
+            lpsiStartInfo.hStdError  = (HANDLE) _get_osfhandle (2);
+        } else if (__isArrayLike(fdArray) && (__arraySize(fdArray) >= 3)) {
+            if (__ArrayInstPtr(fdArray)->a_element[0] != nil) {
+                if (__isExternalAddressLike(__ArrayInstPtr(fdArray)->a_element[0])) {
+                    lpsiStartInfo.hStdInput = _HANDLEVal(__ArrayInstPtr(fdArray)->a_element[0]);
+                } else {
+                    lpsiStartInfo.hStdInput = (HANDLE) _get_osfhandle (__intVal(__ArrayInstPtr(fdArray)->a_element[0]));
+                }
+            }
+            if (__ArrayInstPtr(fdArray)->a_element[1] != nil) {
+                if (__isExternalAddressLike(__ArrayInstPtr(fdArray)->a_element[1])) {
+                    lpsiStartInfo.hStdOutput = _HANDLEVal(__ArrayInstPtr(fdArray)->a_element[1]);
+                } else {
+                    lpsiStartInfo.hStdOutput = (HANDLE) _get_osfhandle (__intVal(__ArrayInstPtr(fdArray)->a_element[1]));
+                }
+            }
+            if (__ArrayInstPtr(fdArray)->a_element[2] != nil) {
+                if (__isExternalAddressLike(__ArrayInstPtr(fdArray)->a_element[2])) {
+                    lpsiStartInfo.hStdError  = _HANDLEVal(__ArrayInstPtr(fdArray)->a_element[2]);
+                } else {
+                    lpsiStartInfo.hStdError = (HANDLE) _get_osfhandle (__intVal(__ArrayInstPtr(fdArray)->a_element[2]));
+                }
+            }
+#if defined(PROCESSDEBUGWIN32)
+            console_fprintf(stderr, "stdin %x\n", lpsiStartInfo.hStdInput);
+            console_fprintf(stderr, "stdout %x\n",lpsiStartInfo.hStdOutput);
+            console_fprintf(stderr, "stderr %x\n",lpsiStartInfo.hStdError);
+#endif
+        } else {
+            console_fprintf(stderr, "Win32OS [warning]: bad fd arg in createProcess\n");
+        }
+
+        if (doFork == true) {
 #ifdef PROCESSDEBUGWIN32
-	    console_fprintf(stderr, "stdin %x\n", lpsiStartInfo.hStdInput);
-	    console_fprintf(stderr, "stdout %x\n",lpsiStartInfo.hStdOutput);
-	    console_fprintf(stderr, "stderr %x\n",lpsiStartInfo.hStdError);
-#endif
-	} else {
-	    console_fprintf(stderr, "Win32OS [warning]: bad fd arg in createProcess\n");
-	}
-
-	if (doFork == true) {
+            console_fprintf(stderr, "create process cmdPath:<%s> cmdLine:<%s> in <%s>\n", cmdPath, cmdLine, dir);
+#endif
+            if (CreateProcess(  cmdPath,
+                                cmdLine,
+                                &sa, NULL /* &sa */,           /* sec-attribs */
+                                sa.bInheritHandle,  /* inherit handles */
+                                fdwCreate,
+                                NULL,               /* env */
+                                dir,
+                                &lpsiStartInfo,
+                                &lppiProcInfo ))
+            {
+                CloseHandle(lppiProcInfo.hThread);
 #ifdef PROCESSDEBUGWIN32
-	    console_fprintf(stderr, "create process cmdPath:<%s> cmdLine:<%s> in <%s>\n", cmdPath, cmdLine, dir);
-#endif
-	    if (CreateProcess(  cmdPath,
-				cmdLine,
-				&sa, NULL /* &sa */,           /* sec-attribs */
-				sa.bInheritHandle,  /* inherit handles */
-				fdwCreate,
-				NULL,               /* env */
-				dir,
-				&lpsiStartInfo,
-				&lppiProcInfo ))
-	    {
-		CloseHandle(lppiProcInfo.hThread);
+                console_fprintf(stderr, "created process hProcess=%x\n", lppiProcInfo.hProcess);
+#endif
+                __externalAddressVal(handle) = lppiProcInfo.hProcess;
+                ((struct __Win32OperatingSystem__Win32ProcessHandle_struct *)(handle))->pid = __mkSmallInteger(lppiProcInfo.dwProcessId);
+                RETURN (handle);
+            }
 #ifdef PROCESSDEBUGWIN32
-		console_fprintf(stderr, "created process hProcess=%x\n", lppiProcInfo.hProcess);
-#endif
-		__externalAddressVal(handle) = lppiProcInfo.hProcess;
-		((struct __Win32OperatingSystem__Win32ProcessHandle_struct *)(handle))->pid = __mkSmallInteger(lppiProcInfo.dwProcessId);
-		RETURN (handle);
-	    }
-#ifdef PROCESSDEBUGWIN32
-	    console_fprintf(stderr, "created process error %d\n", GetLastError());
-#endif
-	    RETURN (nil);
-	} else {
-	    ; /* should never be called that way */
-	}
+            console_fprintf(stderr, "created process error %d\n", GetLastError());
+#endif
+            RETURN (nil);
+        } else {
+            ; /* should never be called that way */
+        }
     }
 %}.
     "
@@ -4850,35 +4849,35 @@
     wchar_t _aPathName[MAX_PATH+1];
 
     if (__isStringLike(aPathName)) {
-	int i;
-	int l = __stringSize(aPathName);
-	if (l > MAX_PATH) l = MAX_PATH;
-
-	for (i=0; i<l; i++) {
-	    _aPathName[i] = __stringVal(aPathName)[i];
-	}
-	_aPathName[i] = 0;
+        int i;
+        int l = __stringSize(aPathName);
+        if (l > MAX_PATH) l = MAX_PATH;
+
+        for (i=0; i<l; i++) {
+            _aPathName[i] = __stringVal(aPathName)[i];
+        }
+        _aPathName[i] = 0;
     } else if (__isUnicode16String(aPathName)) {
-	int i;
-	int l = __unicode16StringSize(aPathName);
-	if (l > MAX_PATH) l = MAX_PATH;
-
-	for (i=0; i<l; i++) {
-	    _aPathName[i] = __unicode16StringVal(aPathName)[i];
-	}
-	_aPathName[i] = 0;
+        int i;
+        int l = __unicode16StringSize(aPathName);
+        if (l > MAX_PATH) l = MAX_PATH;
+
+        for (i=0; i<l; i++) {
+            _aPathName[i] = __unicode16StringVal(aPathName)[i];
+        }
+        _aPathName[i] = 0;
     } else
-	goto badArgument;
+        goto badArgument;
 
 #ifdef DO_WRAP_CALLS
      do {
-	 __threadErrno = 0;
-	 ret = STX_API_CALL3( "GetLongPathNameW", GetLongPathNameW, _aPathName, _aPathName, MAX_PATH+1);
+         __threadErrno = 0;
+         ret = STX_API_CALL3( "GetLongPathNameW", GetLongPathNameW, _aPathName, _aPathName, MAX_PATH+1);
      } while ((ret == 0) && (__threadErrno == EINTR));
 #else
      ret = GetLongPathNameW(_aPathName, _aPathName, MAX_PATH+1);
      if (ret == 0) {
-	 __threadErrno = __WIN32_ERR(GetLastError());
+         __threadErrno = __WIN32_ERR(GetLastError());
      }
 #endif
      RETURN ( __MKU16STRING(_aPathName));
@@ -4889,7 +4888,8 @@
 
     "
      self getLongPathName:'x:\'
-     self getLongPathName:'c:\Dokumente und Einstellungen'
+     self getLongPathName:'c:\Dokumente und Einstellungen'    
+     self getShortPathName:'c:\Dokumente und Einstellungen'   
     "
 !
 
@@ -4907,35 +4907,35 @@
     wchar_t _aPathName[MAX_PATH+1];
 
     if (__isStringLike(aPathName)) {
-	int i;
-	int l = __stringSize(aPathName);
-	if (l > MAX_PATH) l = MAX_PATH;
-
-	for (i=0; i<l; i++) {
-	    _aPathName[i] = __stringVal(aPathName)[i];
-	}
-	_aPathName[i] = 0;
+        int i;
+        int l = __stringSize(aPathName);
+        if (l > MAX_PATH) l = MAX_PATH;
+
+        for (i=0; i<l; i++) {
+            _aPathName[i] = __stringVal(aPathName)[i];
+        }
+        _aPathName[i] = 0;
     } else if (__isUnicode16String(aPathName)) {
-	int i;
-	int l = __unicode16StringSize(aPathName);
-	if (l > MAX_PATH) l = MAX_PATH;
-
-	for (i=0; i<l; i++) {
-	    _aPathName[i] = __unicode16StringVal(aPathName)[i];
-	}
-	_aPathName[i] = 0;
+        int i;
+        int l = __unicode16StringSize(aPathName);
+        if (l > MAX_PATH) l = MAX_PATH;
+
+        for (i=0; i<l; i++) {
+            _aPathName[i] = __unicode16StringVal(aPathName)[i];
+        }
+        _aPathName[i] = 0;
     } else
-	goto badArgument;
+        goto badArgument;
 
 #ifdef DO_WRAP_CALLS
      do {
-	 __threadErrno = 0;
-	 ret = STX_API_CALL3( "GetShortPathNameW", GetShortPathNameW, _aPathName, _aPathName, MAX_PATH+1);
+         __threadErrno = 0;
+         ret = STX_API_CALL3( "GetShortPathNameW", GetShortPathNameW, _aPathName, _aPathName, MAX_PATH+1);
      } while ((ret == 0) && (__threadErrno == EINTR));
 #else
      ret = GetShortPathNameW(_aPathName, _aPathName, MAX_PATH+1);
      if (ret == 0) {
-	 __threadErrno = __WIN32_ERR(GetLastError());
+         __threadErrno = __WIN32_ERR(GetLastError());
      }
 #endif
      RETURN ( __MKU16STRING(_aPathName));
@@ -4946,7 +4946,8 @@
 
     "
      self getShortPathName:'x:\'
-     self getShortPathName:'c:\Dokumente und Einstellungen'
+     self getShortPathName:'c:\Dokumente und Einstellungen' 
+     self getLongPathName:'c:\Dokumente und Einstellungen'   
     "
 !
 
@@ -5790,8 +5791,9 @@
     "
 !
 
-primSetCurrentDirectory:pathName
+primSetCurrentDirectoryA:pathName
     <apicall: bool "SetCurrentDirectoryA" ( pointer ) module: "kernel32.dll" >
+
     self primitiveFailed.
 
     "
@@ -5801,6 +5803,12 @@
     "Created: / 27-07-2006 / 14:47:12 / fm"
 !
 
+primSetCurrentDirectoryW:pathName
+    <apicall: bool "SetCurrentDirectoryW" ( pointer ) module: "kernel32.dll" >
+
+    self primitiveFailed.
+!
+
 primSetFileAttributes:aPathName to:anInteger
     "set the file-attributes; return true if the set did happen"
 
@@ -5864,6 +5872,21 @@
     ^ self primitiveFailed
 !
 
+setCurrentDirectory:pathName
+    pathName bitsPerCharacter == 16 ifTrue:[
+        self primSetCurrentDirectoryW:(pathName copyWith:(Character value:0))
+    ] ifFalse:[
+        self primSetCurrentDirectoryA:pathName
+    ].
+
+    "
+     self getCurrentDirectory
+     self setCurrentDirectory:'C:\Users\cg\work\stx\projects'
+     self getCurrentDirectory
+     self setCurrentDirectory:'C:\Users\cg\work\stx\projects\smalltalk'
+    "
+!
+
 setHidden:aPathName
     "set the hidden attribute. Return true if it is set"
 
@@ -8262,6 +8285,27 @@
     "
 !
 
+setEnvironment:aStringOrSymbol to:newValueString
+    "set an environment variable"
+
+%{  /* NOCONTEXT */
+    char *env;
+
+    if (__isStringLike(aStringOrSymbol)
+     && __isStringLike(newValueString) ) {
+        if (SetEnvironmentVariable(__stringVal(aStringOrSymbol), __stringVal(newValueString)) != 0) {
+            RETURN(self);
+        }
+    }
+%}.
+    self primitiveFailed
+
+    "
+     OperatingSystem getEnvironment:'PATH'   
+     OperatingSystem setEnvironment:'PATH' to:('c:\cygwin\bin;' , (OperatingSystem getEnvironment:'PATH'))
+    "
+!
+
 setLocaleInfo:anInfoDictionary
     "set the locale information; if set, this oerrides the OS's settings.
      (internal in ST/X only - the OS's settings remain unaffected)
@@ -10526,63 +10570,79 @@
     DWORD endStatus;
 
     if (__isExternalAddressLike(pidToWait) ) {
-	HANDLE __pidToWait = _HANDLEVal(pidToWait);
-	int t;
+        HANDLE __pidToWait = _HANDLEVal(pidToWait);
+        int t;
 
 #ifdef PROCESSDEBUG_CHILDPROCESSWAIT
-	console_printf("childProcessWait %x b %d\n",__pidToWait,blocking==true);
-#endif
-	t = blocking==true ? INFINITE : 0;
+        console_printf("childProcessWait %x b %d\n",__pidToWait,blocking==true);
+#endif
+        t = (blocking==true) ? INFINITE : 0;
 
 #ifdef DO_WRAP_CALLS
-	do {
-	    __threadErrno = 0;
-	    endStatus = STX_API_CALL2( "WaitForSingleObject", WaitForSingleObject, __pidToWait, t);
-	} while ((endStatus < 0) && (__threadErrno == EINTR));
-#else
-	endStatus = WaitForSingleObject(__pidToWait, t);
-	if (endStatus < 0) {
-	    __threadErrno = __WIN32_ERR(GetLastError());
-	}
-#endif
-	if ( endStatus == WAIT_TIMEOUT ) {
-	    if (blocking==true)
-		status = @symbol(timeout);
-	    else {
-		status = @symbol(continue);
+        if (t == 0) {
+            /* no need for WRAP-call; does not block */
+            endStatus = WaitForSingleObject(__pidToWait, t);
+            if (endStatus < 0) {
+                __threadErrno = __WIN32_ERR(GetLastError());
+            }
+        } else {
+            do {
+                __threadErrno = 0;
+                endStatus = STX_API_CALL2( "WaitForSingleObject", WaitForSingleObject, __pidToWait, t);
+            } while ((endStatus < 0) && (__threadErrno == EINTR));
+        }
+#else
+        endStatus = WaitForSingleObject(__pidToWait, t);
+        if (endStatus < 0) {
+            __threadErrno = __WIN32_ERR(GetLastError());
+        }
+#endif
+        if ( endStatus == WAIT_TIMEOUT ) {
+            if (blocking==true)
+                status = @symbol(timeout);
+            else {
+                status = @symbol(continue);
 #ifdef PROCESSDEBUG_CHILDPROCESSWAIT
-		console_printf("ret nil\n");
-#endif
-		RETURN(nil);
-	    }
-	} else {
-	    status = @symbol(exit);
+                console_printf("ret nil\n");
+#endif
+                RETURN(nil);
+            }
+        } else {
+            status = @symbol(exit);
+#ifdef PROCESSDEBUG_CHILDPROCESSWAIT
+            console_printf("exit\n");
+#endif
+            if (endStatus == WAIT_OBJECT_0) {
+                DWORD exitCode;
+
+                if (GetExitCodeProcess(__pidToWait, &exitCode)) {
 #ifdef PROCESSDEBUG_CHILDPROCESSWAIT
-	    console_printf("exit\n");
-#endif
-	    if (endStatus == WAIT_OBJECT_0) {
-		if (GetExitCodeProcess(__pidToWait, &endStatus)) {
-		    if (endStatus == STILL_ACTIVE) {
-			RETURN(nil);
-		    }
+                    console_printf("exitCode: %d\n", exitCode);
+#endif
+                    if (exitCode == STILL_ACTIVE) {
+                        RETURN(nil);
+                    }
+#ifdef PROCESSDEBUG_CHILDPROCESSWAIT
+                    console_printf("exit %d\n", exitCode);
+#endif
+                    code = __mkSmallInteger(exitCode);
+                } else {
 #ifdef PROCESSDEBUG_CHILDPROCESSWAIT
-		    console_printf("exit %d\n",endStatus);
-#endif
-		    code = __mkSmallInteger(endStatus);
-		} else {
-		    code = __mkSmallInteger(GetLastError());
-		}
-	    } else {
-		code = __mkSmallInteger(-1);
-	    }
-	}
-	core = false;
-	pid = pidToWait;
+                    console_printf("GetExitCodeProcess failed\n");
+#endif
+                    code = __mkSmallInteger(GetLastError());
+                }
+            } else {
+                code = __mkSmallInteger(-1);
+            }
+        }
+        core = false;
+        pid = pidToWait;
     }
 %}.
 
     (status isNil or:[pid isNil]) ifTrue:[
-	^ self primitiveFailed
+        ^ self primitiveFailed
     ].
 
 "/ Transcript show:'pid: '; show:pid; show:' status: '; show:status;
@@ -15237,6 +15297,16 @@
     ^ pid
 ! !
 
+!Win32OperatingSystem::Win32ProcessHandle methodsFor:'printing & storing'!
+
+printOn:aStream
+    "return a printed representation of the receiver"
+
+    super printOn:aStream.
+    aStream nextPutAll:' pid:'.
+    pid printOn:aStream.
+! !
+
 !Win32OperatingSystem::Win32SerialPortHandle methodsFor:'opening'!
 
 open:portName baudRate:baudRate stopBitsType:stopBitsType
@@ -16300,11 +16370,11 @@
 !Win32OperatingSystem class methodsFor:'documentation'!
 
 version
-    ^ '$Id: Win32OperatingSystem.st 10480 2009-12-02 21:30:55Z vranyj1 $'
+    ^ '$Id: Win32OperatingSystem.st 10489 2009-12-27 20:16:54Z vranyj1 $'
 !
 
 version_CVS
-    ^ '§Header: /cvs/stx/stx/libbasic/Win32OperatingSystem.st,v 1.380 2009/11/05 16:46:51 cg Exp §'
+    ^ '§Header: /cvs/stx/stx/libbasic/Win32OperatingSystem.st,v 1.384 2009/12/21 15:43:33 stefan Exp §'
 ! !
 
 Win32OperatingSystem initialize!
@@ -16313,3 +16383,4 @@
 
 
 
+