#BUGFIX by sr
authorsr
Thu, 14 Apr 2016 12:45:21 +0200
changeset 19578 65f1cf4136a7
parent 19576 e84a1ba22872
child 19579 9a62e43aedf5
#BUGFIX by sr class: Win32OperatingSystem
Win32OperatingSystem.st
--- a/Win32OperatingSystem.st	Wed Apr 13 09:27:57 2016 +0200
+++ b/Win32OperatingSystem.st	Thu Apr 14 12:45:21 2016 +0200
@@ -889,7 +889,6 @@
     "Modified: 7.1.1997 / 19:36:11 / stefan"
 ! !
 
-
 !Win32OperatingSystem class methodsFor:'OS signal constants'!
 
 sigABRT
@@ -3741,9 +3740,26 @@
 primExec:commandPath commandLine:commandLine fileDescriptors:fdArray fork:doFork newPgrp:newPgrp inPath:dirName createFlags:flagsOrNil inheritHandles:inheritHandles
     "Internal lowLevel entry for combined fork & exec for WIN32"
 
-    |handle|
+    |handle 
+	 commandPathUni16 commandLineUni16 dirNameUni16|
 
     handle := Win32ProcessHandle new.
+	
+    commandPathUni16 := commandPath.
+    commandLineUni16 := commandLine.
+    dirNameUni16 := dirName.
+
+    commandPathUni16 notNil ifTrue:[
+        commandPathUni16 := commandPathUni16 asUnicode16String.
+    ].
+    commandLineUni16 notNil ifTrue:[
+        commandLineUni16 := commandLineUni16 asUnicode16String.
+    ].
+    dirNameUni16 notNil ifTrue:[
+        dirNameUni16 := dirNameUni16 asUnicode16String.
+    ].
+	
+	
 %{
 
     /*
@@ -3751,247 +3767,304 @@
      * otherwise, spawn a subprocess and let it execute the command.
      * Currently, only the forking version is supported (who chains anyway ?)
      */
-    char *cmdPath = 0;
-    char *cmdLine = 0;
-    char *dir = 0;
+    int i, l; // i -> for iteration, l -> for length
+
+    /* 
+     * CreateProcess supports 32767 characters/bytes including all variables and values 
+     * so take a good average for its arguments 4096
+     * ATTENTION this value is also used hardcoded in the following code to check the length
+     */
+    wchar_t cmdPathW[4096];
+    wchar_t cmdLineW[4096];
+    wchar_t dirNameW[4096];     
+
+    /* 
+     * pass pointers to CreateProcess  
+     * NULL pointers used to indicate no value
+     * so only set the pointer if the value is valid
+     */          
+    wchar_t *cmdPathWP = NULL; 
+    wchar_t *cmdLineWP = NULL; 
+    wchar_t *dirNameWP = NULL; 
+
     DWORD               fdwCreate = 0;
-    STARTUPINFO         lpsiStartInfo;
+    STARTUPINFOW        lpsiStartInfo;
     PROCESS_INFORMATION lppiProcInfo;
     SECURITY_ATTRIBUTES securityAttributes;
     SECURITY_DESCRIPTOR securityDescriptor;
 
-    if ((__isStringLike(commandPath) || (commandPath == nil)) && __isStringLike(commandLine)) {
-	HANDLE stdinHandle = NULL;
-	HANDLE stdoutHandle = NULL;
-	HANDLE stderrHandle = NULL;
-	int mustClose_stdinHandle = 0;
-	int mustClose_stdoutHandle = 0;
-	int mustClose_stderrHandle = 0;
-
-	if (commandPath != nil) {
-	    cmdPath = __stringVal(commandPath);
-	}
-	cmdLine = __stringVal(commandLine);
-
-	if (__isStringLike(dirName)) {
-	    dir = __stringVal(dirName);
-	}
-
-	/*
-	 * create descriptors as req'd
-	 */
-	memset(&securityAttributes, 0, sizeof(securityAttributes));
-	securityAttributes.nLength = sizeof(securityAttributes);
-	securityAttributes.bInheritHandle = (inheritHandles == true) ? TRUE : FALSE;
-
-	InitializeSecurityDescriptor(&securityDescriptor, SECURITY_DESCRIPTOR_REVISION);
-	SetSecurityDescriptorDacl(&securityDescriptor, -1, 0, 0);
-
-	securityAttributes.lpSecurityDescriptor = &securityDescriptor;
-	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;
-	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 {
-	    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) {
-	    stdinHandle  = (HANDLE) _get_osfhandle (0);
-	    stdoutHandle = (HANDLE) _get_osfhandle (1);
-	    stderrHandle  = (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])) {
-		    stdinHandle = _HANDLEVal(__ArrayInstPtr(fdArray)->a_element[0]);
-		} else {
-		    stdinHandle = (HANDLE) _get_osfhandle (__intVal(__ArrayInstPtr(fdArray)->a_element[0]));
-		}
-	    }
-	    if (__ArrayInstPtr(fdArray)->a_element[1] != nil) {
-		if (__isExternalAddressLike(__ArrayInstPtr(fdArray)->a_element[1])) {
-		    stdoutHandle = _HANDLEVal(__ArrayInstPtr(fdArray)->a_element[1]);
-		} else {
-		    stdoutHandle = (HANDLE) _get_osfhandle (__intVal(__ArrayInstPtr(fdArray)->a_element[1]));
-		}
-	    }
-	    if (__ArrayInstPtr(fdArray)->a_element[2] != nil) {
-		if (__isExternalAddressLike(__ArrayInstPtr(fdArray)->a_element[2])) {
-		    stderrHandle  = _HANDLEVal(__ArrayInstPtr(fdArray)->a_element[2]);
-		} else {
-		    stderrHandle = (HANDLE) _get_osfhandle (__intVal(__ArrayInstPtr(fdArray)->a_element[2]));
-		}
-	    }
-	} else {
-	    console_fprintf(stderr, "Win32OS [warning]: bad fd arg in createProcess\n");
-	}
+    if ((__isUnicode16String(commandPathUni16) || (commandPathUni16 == nil)) && __isUnicode16String(commandLineUni16)) {
+        HANDLE stdinHandle = NULL;
+        HANDLE stdoutHandle = NULL;
+        HANDLE stderrHandle = NULL;
+        int mustClose_stdinHandle = 0;
+        int mustClose_stdoutHandle = 0;
+        int mustClose_stderrHandle = 0;
+
+        /*
+         * terminate the multi byte strings
+         */
+        // #commandPathUni16
+        if (commandPathUni16 != nil) {
+            l = __unicode16StringSize(commandPathUni16);
+            if (l >= 4096) { // >= need 1 space for terminator
+                #ifdef PROCESSDEBUGWIN32
+                console_fprintf(stderr, "argument #commandPathUni16 is to long\n");
+                #endif
+                RETURN(nil);
+            }
+            for (i = 0; i < l; i++) {
+                cmdPathW[i] = __unicode16StringVal(commandPathUni16)[i];
+            }
+            cmdPathW[i] = 0; // set terminator
+            cmdPathWP = &cmdPathW[0];
+        }
+
+        // commandLineUni16
+        l = __unicode16StringSize(commandLineUni16);
+        if (l >= 4096) { // >= need 1 space for terminator
+            #ifdef PROCESSDEBUGWIN32
+            console_fprintf(stderr, "argument #commandLineUni16 is to long\n");
+            #endif
+            RETURN(nil);
+        }
+        for (i = 0; i < l; i++) {
+            cmdLineW[i] = __unicode16StringVal(commandLineUni16)[i];
+        }
+        cmdLineW[i] = 0; // set terminator
+        cmdLineWP = &cmdLineW[0];
+
+        // #dirNameUni16
+        if (__isUnicode16String(dirNameUni16)) {
+            l = __unicode16StringSize(dirNameUni16);
+            if (l >= 4096) { // >= need 1 space for terminator
+                #ifdef PROCESSDEBUGWIN32
+                console_fprintf(stderr, "argument #dirNameUni16 is to long\n");
+                #endif
+                RETURN(nil);
+            }
+            for (i = 0; i < l; i++) {
+                dirNameW[i] = __unicode16StringVal(dirNameUni16)[i];
+            }
+            dirNameW[i] = 0; // set terminator
+            dirNameWP = &dirNameW[0];
+        }
+
+        /*
+         * create descriptors as req'd
+         */
+        memset(&securityAttributes, 0, sizeof(securityAttributes));
+        securityAttributes.nLength = sizeof(securityAttributes);
+        securityAttributes.bInheritHandle = (inheritHandles == true) ? TRUE : FALSE;
+
+        InitializeSecurityDescriptor(&securityDescriptor, SECURITY_DESCRIPTOR_REVISION);
+        SetSecurityDescriptorDacl(&securityDescriptor, -1, 0, 0);
+
+        securityAttributes.lpSecurityDescriptor = &securityDescriptor;
+        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;
+        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 {
+            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) {
+            stdinHandle  = (HANDLE) _get_osfhandle (0);
+            stdoutHandle = (HANDLE) _get_osfhandle (1);
+            stderrHandle  = (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])) {
+                    stdinHandle = _HANDLEVal(__ArrayInstPtr(fdArray)->a_element[0]);
+                } else {
+                    stdinHandle = (HANDLE) _get_osfhandle (__intVal(__ArrayInstPtr(fdArray)->a_element[0]));
+                }
+            }
+            if (__ArrayInstPtr(fdArray)->a_element[1] != nil) {
+                if (__isExternalAddressLike(__ArrayInstPtr(fdArray)->a_element[1])) {
+                    stdoutHandle = _HANDLEVal(__ArrayInstPtr(fdArray)->a_element[1]);
+                } else {
+                    stdoutHandle = (HANDLE) _get_osfhandle (__intVal(__ArrayInstPtr(fdArray)->a_element[1]));
+                }
+            }
+            if (__ArrayInstPtr(fdArray)->a_element[2] != nil) {
+                if (__isExternalAddressLike(__ArrayInstPtr(fdArray)->a_element[2])) {
+                    stderrHandle  = _HANDLEVal(__ArrayInstPtr(fdArray)->a_element[2]);
+                } else {
+                    stderrHandle = (HANDLE) _get_osfhandle (__intVal(__ArrayInstPtr(fdArray)->a_element[2]));
+                }
+            }
+        } else {
+            console_fprintf(stderr, "Win32OS [warning]: bad fd arg in createProcess\n");
+        }
 
 #if defined(PROCESSDEBUGWIN32)
-	console_fprintf(stderr, "stdin %x\n", stdinHandle);
-	console_fprintf(stderr, "stdout %x\n", stdoutHandle);
-	console_fprintf(stderr, "stderr %x\n", stderrHandle);
-#endif
-
-	{
-	    HANDLE childHandle;
-	    int sameHandle = (stdoutHandle == stderrHandle);
-
-	    // these MUST be inheritable!
-	    if (stdinHandle) {
+        console_fprintf(stderr, "stdin %x\n", stdinHandle);
+        console_fprintf(stderr, "stdout %x\n", stdoutHandle);
+        console_fprintf(stderr, "stderr %x\n", stderrHandle);
+#endif
+
+        {
+            HANDLE childHandle;
+            int sameHandle = (stdoutHandle == stderrHandle);
+
+            // these MUST be inheritable!
+            if (stdinHandle) {
 #if 0
-		if (SetHandleInformation(stdinHandle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) {
-		    // good
-		} else {
-		    console_fprintf(stderr, "Win32OS [warning]: SetHandleInformation failed in createProcess\n");
-		}
-#else
-		if (DuplicateHandle(GetCurrentProcess(), stdinHandle, GetCurrentProcess(),
-				      &childHandle, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
-		    stdinHandle = childHandle;
-		    mustClose_stdinHandle = 1;
-		} else {
-		    console_fprintf(stderr, "Win32OS [warning]: duplicateHandle failed in createProcess\n");
-		}
-#endif
-	    }
-	    if (stdoutHandle) {
+                if (SetHandleInformation(stdinHandle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) {
+                    // good
+                } else {
+                    console_fprintf(stderr, "Win32OS [warning]: SetHandleInformation failed in createProcess\n");
+                }
+#else
+                if (DuplicateHandle(GetCurrentProcess(), stdinHandle, GetCurrentProcess(),
+                                      &childHandle, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
+                    stdinHandle = childHandle;
+                    mustClose_stdinHandle = 1;
+                } else {
+                    console_fprintf(stderr, "Win32OS [warning]: duplicateHandle failed in createProcess\n");
+                }
+#endif
+            }
+            if (stdoutHandle) {
 #if 0
-		if (SetHandleInformation(stdoutHandle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) {
-		    // good
-		} else {
-		    console_fprintf(stderr, "Win32OS [warning]: SetHandleInformation failed in createProcess\n");
-		}
-#else
-		if (DuplicateHandle(GetCurrentProcess(), stdoutHandle, GetCurrentProcess(),
-				      &childHandle, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
-		    stdoutHandle = childHandle;
-		    mustClose_stdoutHandle = 1;
-		} else {
-		    console_fprintf(stderr, "Win32OS [warning]: duplicateHandle failed in createProcess\n");
-		}
-#endif
-	    }
-	    if (stderrHandle) {
-		if (sameHandle) {
-		    stderrHandle = stdoutHandle;
-		} else {
+                if (SetHandleInformation(stdoutHandle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) {
+                    // good
+                } else {
+                    console_fprintf(stderr, "Win32OS [warning]: SetHandleInformation failed in createProcess\n");
+                }
+#else
+                if (DuplicateHandle(GetCurrentProcess(), stdoutHandle, GetCurrentProcess(),
+                                      &childHandle, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
+                    stdoutHandle = childHandle;
+                    mustClose_stdoutHandle = 1;
+                } else {
+                    console_fprintf(stderr, "Win32OS [warning]: duplicateHandle failed in createProcess\n");
+                }
+#endif
+            }
+            if (stderrHandle) {
+                if (sameHandle) {
+                    stderrHandle = stdoutHandle;
+                } else {
 #if 0
-		    if (SetHandleInformation(stderrHandle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) {
-			// good
-		    } else {
-			console_fprintf(stderr, "Win32OS [warning]: SetHandleInformation failed in createProcess\n");
-		    }
-#else
-		    if (DuplicateHandle(GetCurrentProcess(), stderrHandle, GetCurrentProcess(),
-					  &childHandle, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
-			stderrHandle = childHandle;
-			mustClose_stderrHandle = 1;
-		    } else {
-			console_fprintf(stderr, "Win32OS [warning]: duplicateHandle failed in createProcess\n");
-		    }
-#endif
-		}
-	    }
-	}
-	lpsiStartInfo.hStdInput  = stdinHandle;
-	lpsiStartInfo.hStdOutput = stdoutHandle;
-	lpsiStartInfo.hStdError  = stderrHandle;
-
-	if (doFork == true) {
+                    if (SetHandleInformation(stderrHandle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) {
+                        // good
+                    } else {
+                        console_fprintf(stderr, "Win32OS [warning]: SetHandleInformation failed in createProcess\n");
+                    }
+#else
+                    if (DuplicateHandle(GetCurrentProcess(), stderrHandle, GetCurrentProcess(),
+                                          &childHandle, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
+                        stderrHandle = childHandle;
+                        mustClose_stderrHandle = 1;
+                    } else {
+                        console_fprintf(stderr, "Win32OS [warning]: duplicateHandle failed in createProcess\n");
+                    }
+#endif
+                }
+            }
+        }
+        lpsiStartInfo.hStdInput  = stdinHandle;
+        lpsiStartInfo.hStdOutput = stdoutHandle;
+        lpsiStartInfo.hStdError  = stderrHandle;
+
+        if (doFork == true) {
 #ifdef PROCESSDEBUGWIN32
-	    console_fprintf(stderr, "create process cmdPath:<%s> cmdLine:<%s> in <%s>\n", cmdPath, cmdLine, dir);
-#endif
-	    if (CreateProcessA( cmdPath,
-				cmdLine,
-				&securityAttributes, NULL /* &securityAttributes */,
-				securityAttributes.bInheritHandle,      /* inherit handles */
-				fdwCreate | CREATE_SUSPENDED,           /* resume after setting affinity */
-				NULL,                                   /* env */
-				dir,
-				&lpsiStartInfo,
-				&lppiProcInfo ))
-	    {
-		DWORD_PTR processAffinityMask, systemAffinityMask;
-
-		/*
-		 * Process was created suspended, now set the affinity mask
-		 * to any processor, and resume the processes main thread.
-		 * (librun/process.s limited the affinity to a single processor).
-		 */
-		GetProcessAffinityMask(lppiProcInfo.hProcess, &processAffinityMask, &systemAffinityMask);
-		SetProcessAffinityMask(lppiProcInfo.hProcess, systemAffinityMask);
-		if ((fdwCreate & CREATE_SUSPENDED) == 0) {
-		    ResumeThread(lppiProcInfo.hThread);
-		}
-		CloseHandle(lppiProcInfo.hThread);
+            console_fprintf(stderr, "create process cmdPath:<%s> cmdLine:<%s> in <%s>\n", cmdPath, cmdLine, dir);
+#endif
+            if (CreateProcessW( cmdPathWP,
+                                cmdLineWP,
+                                &securityAttributes, NULL /* &securityAttributes */,
+                                securityAttributes.bInheritHandle,      /* inherit handles */
+                                fdwCreate | CREATE_SUSPENDED,           /* resume after setting affinity */
+                                NULL,                                   /* env */
+                                dirNameWP,
+                                &lpsiStartInfo,
+                                &lppiProcInfo ))
+            {
+                DWORD_PTR processAffinityMask, systemAffinityMask;
+
+                /*
+                 * Process was created suspended, now set the affinity mask
+                 * to any processor, and resume the processes main thread.
+                 * (librun/process.s limited the affinity to a single processor).
+                 */
+                GetProcessAffinityMask(lppiProcInfo.hProcess, &processAffinityMask, &systemAffinityMask);
+                SetProcessAffinityMask(lppiProcInfo.hProcess, systemAffinityMask);
+                if ((fdwCreate & CREATE_SUSPENDED) == 0) {
+                    ResumeThread(lppiProcInfo.hThread);
+                }
+                CloseHandle(lppiProcInfo.hThread);
 
 #if 0
-		// only works with real console handles
-		{
-		    // change the child's stdIn (console) mode
-		    DWORD mode = 0;
-
-		    if (! GetConsoleMode(stdinHandle, &mode)) {
-			console_fprintf(stderr, "Win32OS [warning]: GetConsoleMode failed in createProcess\n");
-		    }
-		    if (! SetConsoleMode(stdinHandle, mode & (~ENABLE_ECHO_INPUT))){
-			console_fprintf(stderr, "Win32OS [warning]: SetConsoleMode failed in createProcess\n");
-		    }
-		}
-#endif
-		if (mustClose_stdinHandle) {
-		    CloseHandle(stdinHandle);
-		}
-		if (mustClose_stdoutHandle) {
-		    CloseHandle(stdoutHandle);
-		}
-		if (mustClose_stderrHandle) {
-		    CloseHandle(stderrHandle);
-		}
+                // only works with real console handles
+                {
+                    // change the child's stdIn (console) mode
+                    DWORD mode = 0;
+
+                    if (! GetConsoleMode(stdinHandle, &mode)) {
+                        console_fprintf(stderr, "Win32OS [warning]: GetConsoleMode failed in createProcess\n");
+                    }
+                    if (! SetConsoleMode(stdinHandle, mode & (~ENABLE_ECHO_INPUT))){
+                        console_fprintf(stderr, "Win32OS [warning]: SetConsoleMode failed in createProcess\n");
+                    }
+                }
+#endif
+                if (mustClose_stdinHandle) {
+                    CloseHandle(stdinHandle);
+                }
+                if (mustClose_stdoutHandle) {
+                    CloseHandle(stdoutHandle);
+                }
+                if (mustClose_stderrHandle) {
+                    CloseHandle(stderrHandle);
+                }
 #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);
-	    }
+                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 */
+        }
     }
 %}.
     "