Win32OperatingSystem.st
changeset 20896 c88fbd0cb367
parent 20677 e3fe2f476abb
child 20897 49ffdb7d9c18
equal deleted inserted replaced
20895:0210e874e38b 20896:c88fbd0cb367
   290 # ifndef _FCNTL_H_INCLUDED_
   290 # ifndef _FCNTL_H_INCLUDED_
   291 #  include <fcntl.h>
   291 #  include <fcntl.h>
   292 #  define _FCNTL_H_INCLUDED_
   292 #  define _FCNTL_H_INCLUDED_
   293 # endif
   293 # endif
   294 
   294 
   295 // # define PROCESSDEBUGWIN32
   295 # define PROCESSDEBUGWIN32
   296 // # define PROCESS1DEBUGWIN32
   296 // # define PROCESS1DEBUGWIN32
   297 // # define PROCESS2DEBUGWIN32
   297 // # define PROCESS2DEBUGWIN32
   298 // # define PROCESSDEBUG_CHILDPROCESSWAIT
   298 // # define PROCESSDEBUG_CHILDPROCESSWAIT
   299 // # define SELECTDEBUGWIN32
   299 // # define SELECTDEBUGWIN32
   300 // # define SELECT1DEBUGWIN32
   300 // # define SELECT1DEBUGWIN32
   549 # define TokenElevationType (TOKEN_INFORMATION_CLASS)nTokenElevationType
   549 # define TokenElevationType (TOKEN_INFORMATION_CLASS)nTokenElevationType
   550 # define TokenElevation     (TOKEN_INFORMATION_CLASS)nTokenElevation
   550 # define TokenElevation     (TOKEN_INFORMATION_CLASS)nTokenElevation
   551 
   551 
   552 #endif /* BORLAND */
   552 #endif /* BORLAND */
   553 
   553 
       
   554 #ifdef PROCESSDEBUGWIN32
       
   555 static int flag_PROCESSDEBUGWIN32 = 0;
       
   556 #endif
       
   557 
   554 %}
   558 %}
   555 ! !
   559 ! !
   556 
   560 
   557 !Win32OperatingSystem primitiveVariables!
   561 !Win32OperatingSystem primitiveVariables!
   558 %{
   562 %{
   897     ]
   901     ]
   898 								[exBegin]
   902 								[exBegin]
   899 "
   903 "
   900 ! !
   904 ! !
   901 
   905 
       
   906 !Win32OperatingSystem class methodsFor:'debugging'!
       
   907 
       
   908 verbose:aBoolean
       
   909 %{
       
   910 #ifdef PROCESSDEBUGWIN32
       
   911     flag_PROCESSDEBUGWIN32 = (aBoolean == true);
       
   912 #endif
       
   913 %}
       
   914 ! !
       
   915 
   902 !Win32OperatingSystem class methodsFor:'initialization'!
   916 !Win32OperatingSystem class methodsFor:'initialization'!
   903 
   917 
   904 coInitialize
   918 coInitialize
   905 %{
   919 %{
   906     HRESULT hres;
   920     HRESULT hres;
  3660     "Modified: / 20-01-1998 / 16:57:19 / md"
  3674     "Modified: / 20-01-1998 / 16:57:19 / md"
  3661     "Modified: / 11-02-2007 / 20:51:08 / cg"
  3675     "Modified: / 11-02-2007 / 20:51:08 / cg"
  3662 !
  3676 !
  3663 
  3677 
  3664 exec:aCommandPath withArguments:argString environment:environment fileDescriptors:fdArray fork:doFork
  3678 exec:aCommandPath withArguments:argString environment:environment fileDescriptors:fdArray fork:doFork
  3665         newPgrp:newPgrp inDirectory:aDirectory
  3679 	newPgrp:newPgrp inDirectory:aDirectory
  3666         showWindow:showWindowBooleanOrNil
  3680 	showWindow:showWindowBooleanOrNil
  3667 
  3681 
  3668     "Internal lowLevel entry for combined fork & exec for WIN32
  3682     "Internal lowLevel entry for combined fork & exec for WIN32
  3669 
  3683 
  3670      If fork is false (chain a command):
  3684      If fork is false (chain a command):
  3671          execute the OS command specified by the argument, aCommandPath, with
  3685 	 execute the OS command specified by the argument, aCommandPath, with
  3672          arguments in argArray (no arguments, if nil).
  3686 	 arguments in argArray (no arguments, if nil).
  3673          If successful, this method does not return and smalltalk is gone.
  3687 	 If successful, this method does not return and smalltalk is gone.
  3674          If not successful, it does return.
  3688 	 If not successful, it does return.
  3675          Normal use is with forkForCommand.
  3689 	 Normal use is with forkForCommand.
  3676 
  3690 
  3677      If fork is true (subprocess command execution):
  3691      If fork is true (subprocess command execution):
  3678         fork a child to do the above.
  3692 	fork a child to do the above.
  3679         The Win32ProcessHandle of the child process is returned; nil if the fork failed.
  3693 	The Win32ProcessHandle of the child process is returned; nil if the fork failed.
  3680 
  3694 
  3681      fdArray contains the filedescriptors, to be used for the child (if fork is true).
  3695      fdArray contains the filedescriptors, to be used for the child (if fork is true).
  3682         fdArray[1] = 15 -> use fd 15 as stdin.
  3696 	fdArray[1] = 15 -> use fd 15 as stdin.
  3683         If an element of the array is set to nil, the corresponding filedescriptor
  3697 	If an element of the array is set to nil, the corresponding filedescriptor
  3684         will be closed for the child.
  3698 	will be closed for the child.
  3685         fdArray[0] == StdIn for child
  3699 	fdArray[0] == StdIn for child
  3686         fdArray[1] == StdOut for child
  3700 	fdArray[1] == StdOut for child
  3687         fdArray[2] == StdErr for child
  3701 	fdArray[2] == StdErr for child
  3688 
  3702 
  3689      NOTE that in WIN32 the fds are HANDLES.
  3703      NOTE that in WIN32 the fds are HANDLES.
  3690 
  3704 
  3691      If newPgrp is true, the subprocess will be established in a new process group.
  3705      If newPgrp is true, the subprocess will be established in a new process group.
  3692         The processgroup will be equal to id.
  3706 	The processgroup will be equal to id.
  3693         newPgrp is not used on WIN32 and VMS systems.
  3707 	newPgrp is not used on WIN32 and VMS systems.
  3694 
  3708 
  3695      showWindowOrBoolean may be:
  3709      showWindowOrBoolean may be:
  3696         true  - a window is shown on start of the command
  3710 	true  - a window is shown on start of the command
  3697         false - the command window is hidden
  3711 	false - the command window is hidden
  3698         nil   - the nCmdShown parameter of the commans's winmain function determins,
  3712 	nil   - the nCmdShown parameter of the commans's winmain function determins,
  3699                 if a window is shown.
  3713 		if a window is shown.
  3700         #default
  3714 	#default
  3701               - same as nil
  3715 	      - same as nil
  3702     "
  3716     "
  3703 
  3717 
  3704     |dirPath rslt|
  3718     |dirPath rslt|
  3705 
  3719 
  3706     aDirectory notNil ifTrue:[
  3720     aDirectory notNil ifTrue:[
  3707         dirPath := aDirectory asFilename asAbsoluteFilename osNameForDirectory.
  3721 	dirPath := aDirectory asFilename asAbsoluteFilename osNameForDirectory.
  3708         (dirPath endsWith:':') ifTrue:[
  3722 	(dirPath endsWith:':') ifTrue:[
  3709             dirPath := dirPath , '\'.
  3723 	    dirPath := dirPath , '\'.
  3710         ].
  3724 	].
  3711     ].
  3725     ].
  3712 
  3726 
  3713     rslt := self
  3727     rslt := self
  3714         primExec:aCommandPath
  3728 	primExec:aCommandPath
  3715         commandLine:argString
  3729 	commandLine:argString
  3716         fileDescriptors:fdArray
  3730 	fileDescriptors:fdArray
  3717         fork:doFork
  3731 	fork:doFork
  3718         newPgrp:newPgrp
  3732 	newPgrp:newPgrp
  3719         inPath:dirPath
  3733 	inPath:dirPath
  3720         createFlags:nil
  3734 	createFlags:nil
  3721         inheritHandles:true
  3735 	inheritHandles:true
  3722         showWindow:showWindowBooleanOrNil.
  3736 	showWindow:showWindowBooleanOrNil.
  3723 
  3737 
  3724 "/ 'created ' print. cmdLine print. ' -> ' print. rslt printCR.
  3738 "/ 'created ' print. cmdLine print. ' -> ' print. rslt printCR.
  3725     ^ rslt
  3739     ^ rslt
  3726 
  3740 
  3727     "Modified: / 31-01-1998 / 10:54:24 / md"
  3741     "Modified: / 31-01-1998 / 10:54:24 / md"
  3750 #endif
  3764 #endif
  3751 	    if (endStatus != WAIT_FAILED) {
  3765 	    if (endStatus != WAIT_FAILED) {
  3752 		if (GetExitCodeProcess(handle,&endStatus)) {
  3766 		if (GetExitCodeProcess(handle,&endStatus)) {
  3753 		    status = endStatus;
  3767 		    status = endStatus;
  3754 #ifdef PROCESSDEBUGWIN32
  3768 #ifdef PROCESSDEBUGWIN32
  3755 		    console_fprintf(stderr, "getexitcode status = %d\n",status);
  3769 		    if (flag_PROCESSDEBUGWIN32) {
       
  3770 			console_fprintf(stderr, "getexitcode status = %d\n",status);
       
  3771 		    }
  3756 		} else {
  3772 		} else {
  3757 		    console_fprintf(stderr, "getexitcode failed.\n");
  3773 		    if (flag_PROCESSDEBUGWIN32) {
       
  3774 			console_fprintf(stderr, "getexitcode failed.\n");
       
  3775 		    }
  3758 #endif
  3776 #endif
  3759 		}
  3777 		}
  3760 	    }
  3778 	    }
  3761 	}
  3779 	}
  3762 	RETURN ( __mkSmallInteger(status));
  3780 	RETURN ( __mkSmallInteger(status));
  3838     "Modified: / 23-08-2011 / 21:11:47 / jv"
  3856     "Modified: / 23-08-2011 / 21:11:47 / jv"
  3839     "Modified: / 20-01-2012 / 13:32:55 / cg"
  3857     "Modified: / 20-01-2012 / 13:32:55 / cg"
  3840 !
  3858 !
  3841 
  3859 
  3842 primExec:commandPath commandLine:commandLine fileDescriptors:fdArray fork:doFork newPgrp:newPgrp
  3860 primExec:commandPath commandLine:commandLine fileDescriptors:fdArray fork:doFork newPgrp:newPgrp
  3843         inPath:dirName createFlags:flagsOrNil inheritHandles:inheritHandles
  3861 	inPath:dirName createFlags:flagsOrNil inheritHandles:inheritHandles
  3844         showWindow:showWindowBooleanOrNil
  3862 	showWindow:showWindowBooleanOrNil
  3845     "Internal lowLevel entry for combined fork & exec for WIN32
  3863     "Internal lowLevel entry for combined fork & exec for WIN32
  3846 
  3864 
  3847      showWindowBooleanOrNil may be:
  3865      showWindowBooleanOrNil may be:
  3848         true  - a window is shown on start of the command
  3866 	true  - a window is shown on start of the command
  3849         false - the command window is hidden
  3867 	false - the command window is hidden
  3850         nil   - the nCmdShown parameter of the commans's winmain function determins,
  3868 	nil   - the nCmdShown parameter of the commans's winmain function determins,
  3851                 if a window is shown.
  3869 		if a window is shown.
  3852         #default
  3870 	#default
  3853               - same as nil
  3871 	      - same as nil
  3854     "
  3872     "
  3855 
  3873 
  3856     |handle commandPathUni16 commandLineUni16 dirNameUni16|
  3874     |handle commandPathUni16 commandLineUni16 dirNameUni16|
  3857 
  3875 
  3858     handle := Win32ProcessHandle new.
  3876     handle := Win32ProcessHandle new.
  3860     commandPathUni16 := commandPath.
  3878     commandPathUni16 := commandPath.
  3861     commandLineUni16 := commandLine.
  3879     commandLineUni16 := commandLine.
  3862     dirNameUni16 := dirName.
  3880     dirNameUni16 := dirName.
  3863 
  3881 
  3864     commandPathUni16 notNil ifTrue:[
  3882     commandPathUni16 notNil ifTrue:[
  3865         commandPathUni16 := commandPathUni16 asUnicode16String.
  3883 	commandPathUni16 := commandPathUni16 asUnicode16String.
  3866     ].
  3884     ].
  3867     commandLineUni16 notNil ifTrue:[
  3885     commandLineUni16 notNil ifTrue:[
  3868         commandLineUni16 := commandLineUni16 asUnicode16String.
  3886 	commandLineUni16 := commandLineUni16 asUnicode16String.
  3869     ].
  3887     ].
  3870     dirNameUni16 notNil ifTrue:[
  3888     dirNameUni16 notNil ifTrue:[
  3871         dirNameUni16 := dirNameUni16 asUnicode16String.
  3889 	dirNameUni16 := dirNameUni16 asUnicode16String.
  3872     ].
  3890     ].
  3873 
  3891 
  3874 
  3892 
  3875 %{
  3893 %{
  3876 
  3894 
  3904     PROCESS_INFORMATION lppiProcInfo;
  3922     PROCESS_INFORMATION lppiProcInfo;
  3905     SECURITY_ATTRIBUTES securityAttributes;
  3923     SECURITY_ATTRIBUTES securityAttributes;
  3906     SECURITY_DESCRIPTOR securityDescriptor;
  3924     SECURITY_DESCRIPTOR securityDescriptor;
  3907 
  3925 
  3908     if ((__isUnicode16String(commandPathUni16) || (commandPathUni16 == nil)) && __isUnicode16String(commandLineUni16)) {
  3926     if ((__isUnicode16String(commandPathUni16) || (commandPathUni16 == nil)) && __isUnicode16String(commandLineUni16)) {
  3909         HANDLE stdinHandle = NULL;
  3927 	HANDLE stdinHandle = NULL;
  3910         HANDLE stdoutHandle = NULL;
  3928 	HANDLE stdoutHandle = NULL;
  3911         HANDLE stderrHandle = NULL;
  3929 	HANDLE stderrHandle = NULL;
  3912         int mustClose_stdinHandle = 0;
  3930 	int mustClose_stdinHandle = 0;
  3913         int mustClose_stdoutHandle = 0;
  3931 	int mustClose_stdoutHandle = 0;
  3914         int mustClose_stderrHandle = 0;
  3932 	int mustClose_stderrHandle = 0;
  3915 
  3933 
  3916         /*
  3934 	/*
  3917          * terminate the multi byte strings
  3935 	 * terminate the multi byte strings
  3918          */
  3936 	 */
  3919         // #commandPathUni16
  3937 	// #commandPathUni16
  3920         if (commandPathUni16 != nil) {
  3938 	if (commandPathUni16 != nil) {
  3921             l = __unicode16StringSize(commandPathUni16);
  3939 	    l = __unicode16StringSize(commandPathUni16);
  3922             if (l >= 4096) { // >= need 1 space for terminator
  3940 	    if (l >= 4096) { // >= need 1 space for terminator
  3923                 #ifdef PROCESSDEBUGWIN32
  3941 # ifdef PROCESSDEBUGWIN32
  3924                 console_fprintf(stderr, "argument #commandPathUni16 is to long\n");
  3942 		if (flag_PROCESSDEBUGWIN32) {
  3925                 #endif
  3943 		    console_fprintf(stderr, "argument #commandPathUni16 is to long\n");
  3926                 RETURN(nil);
  3944 		}
  3927             }
  3945 # endif
  3928             for (i = 0; i < l; i++) {
  3946 		RETURN(nil);
  3929                 cmdPathW[i] = __unicode16StringVal(commandPathUni16)[i];
  3947 	    }
  3930             }
  3948 	    for (i = 0; i < l; i++) {
  3931             cmdPathW[i] = 0; // set terminator
  3949 		cmdPathW[i] = __unicode16StringVal(commandPathUni16)[i];
  3932             cmdPathWP = &cmdPathW[0];
  3950 	    }
  3933         }
  3951 	    cmdPathW[i] = 0; // set terminator
  3934 
  3952 	    cmdPathWP = &cmdPathW[0];
  3935         // commandLineUni16
  3953 	}
  3936         l = __unicode16StringSize(commandLineUni16);
  3954 
  3937         if (l >= 4096) { // >= need 1 space for terminator
  3955 	// commandLineUni16
  3938             #ifdef PROCESSDEBUGWIN32
  3956 	l = __unicode16StringSize(commandLineUni16);
  3939             console_fprintf(stderr, "argument #commandLineUni16 is to long\n");
  3957 	if (l >= 4096) { // >= need 1 space for terminator
  3940             #endif
  3958 # ifdef PROCESSDEBUGWIN32
  3941             RETURN(nil);
  3959 	    if (flag_PROCESSDEBUGWIN32) {
  3942         }
  3960 		console_fprintf(stderr, "argument #commandLineUni16 is to long\n");
  3943         for (i = 0; i < l; i++) {
  3961 	    }
  3944             cmdLineW[i] = __unicode16StringVal(commandLineUni16)[i];
  3962 # endif
  3945         }
  3963 	    RETURN(nil);
  3946         cmdLineW[i] = 0; // set terminator
  3964 	}
  3947         cmdLineWP = &cmdLineW[0];
  3965 	for (i = 0; i < l; i++) {
  3948 
  3966 	    cmdLineW[i] = __unicode16StringVal(commandLineUni16)[i];
  3949         // #dirNameUni16
  3967 	}
  3950         if (__isUnicode16String(dirNameUni16)) {
  3968 	cmdLineW[i] = 0; // set terminator
  3951             l = __unicode16StringSize(dirNameUni16);
  3969 	cmdLineWP = &cmdLineW[0];
  3952             if (l >= 4096) { // >= need 1 space for terminator
  3970 
  3953                 #ifdef PROCESSDEBUGWIN32
  3971 	// #dirNameUni16
  3954                 console_fprintf(stderr, "argument #dirNameUni16 is to long\n");
  3972 	if (__isUnicode16String(dirNameUni16)) {
  3955                 #endif
  3973 	    l = __unicode16StringSize(dirNameUni16);
  3956                 RETURN(nil);
  3974 	    if (l >= 4096) { // >= need 1 space for terminator
  3957             }
  3975 # ifdef PROCESSDEBUGWIN32
  3958             for (i = 0; i < l; i++) {
  3976 		if (flag_PROCESSDEBUGWIN32) {
  3959                 dirNameW[i] = __unicode16StringVal(dirNameUni16)[i];
  3977 		    console_fprintf(stderr, "argument #dirNameUni16 is to long\n");
  3960             }
  3978 		}
  3961             dirNameW[i] = 0; // set terminator
  3979 # endif
  3962             dirNameWP = &dirNameW[0];
  3980 		RETURN(nil);
  3963         }
  3981 	    }
  3964 
  3982 	    for (i = 0; i < l; i++) {
  3965         /*
  3983 		dirNameW[i] = __unicode16StringVal(dirNameUni16)[i];
  3966          * create descriptors as req'd
  3984 	    }
  3967          */
  3985 	    dirNameW[i] = 0; // set terminator
  3968         memset(&securityAttributes, 0, sizeof(securityAttributes));
  3986 	    dirNameWP = &dirNameW[0];
  3969         securityAttributes.nLength = sizeof(securityAttributes);
  3987 	}
  3970         securityAttributes.bInheritHandle = (inheritHandles == true) ? TRUE : FALSE;
  3988 
  3971 
  3989 	/*
  3972         InitializeSecurityDescriptor(&securityDescriptor, SECURITY_DESCRIPTOR_REVISION);
  3990 	 * create descriptors as req'd
  3973         SetSecurityDescriptorDacl(&securityDescriptor, -1, 0, 0);
  3991 	 */
  3974 
  3992 	memset(&securityAttributes, 0, sizeof(securityAttributes));
  3975         securityAttributes.lpSecurityDescriptor = &securityDescriptor;
  3993 	securityAttributes.nLength = sizeof(securityAttributes);
  3976         memset(&lppiProcInfo, 0, sizeof (lppiProcInfo));
  3994 	securityAttributes.bInheritHandle = (inheritHandles == true) ? TRUE : FALSE;
  3977 
  3995 
  3978         memset(&lpsiStartInfo, 0, sizeof(lpsiStartInfo));
  3996 	InitializeSecurityDescriptor(&securityDescriptor, SECURITY_DESCRIPTOR_REVISION);
  3979         lpsiStartInfo.cb                = sizeof(lpsiStartInfo);
  3997 	SetSecurityDescriptorDacl(&securityDescriptor, -1, 0, 0);
  3980         lpsiStartInfo.lpReserved        = NULL;
  3998 
  3981         lpsiStartInfo.lpDesktop         = NULL;
  3999 	securityAttributes.lpSecurityDescriptor = &securityDescriptor;
  3982         lpsiStartInfo.lpTitle           = NULL;
  4000 
  3983         lpsiStartInfo.dwX               = 0;
  4001 	memset(&lpsiStartInfo, 0, sizeof(lpsiStartInfo));
  3984         lpsiStartInfo.dwY               = 0;
  4002 	lpsiStartInfo.cb                = sizeof(lpsiStartInfo);
  3985         lpsiStartInfo.dwXSize           = 100;
  4003 	lpsiStartInfo.lpReserved        = NULL;
  3986         lpsiStartInfo.dwYSize           = 100;
  4004 	lpsiStartInfo.lpDesktop         = NULL;
  3987         lpsiStartInfo.dwXCountChars     = 0;
  4005 	lpsiStartInfo.lpTitle           = NULL;
  3988         lpsiStartInfo.dwYCountChars     = 0;
  4006 	lpsiStartInfo.dwX               = 0;
  3989         lpsiStartInfo.dwFillAttribute   = 0;
  4007 	lpsiStartInfo.dwY               = 0;
  3990         lpsiStartInfo.dwFlags           = STARTF_USESTDHANDLES /*| STARTF_USEPOSITION*/;
  4008 	lpsiStartInfo.dwXSize           = 100;
  3991         if ((showWindowBooleanOrNil != nil) && (showWindowBooleanOrNil != @symbol(default))) {
  4009 	lpsiStartInfo.dwYSize           = 100;
  3992             lpsiStartInfo.dwFlags |= STARTF_USESHOWWINDOW;
  4010 	lpsiStartInfo.dwXCountChars     = 0;
  3993             lpsiStartInfo.wShowWindow = showWindowBooleanOrNil == true ? SW_SHOWNORMAL : SW_HIDE;
  4011 	lpsiStartInfo.dwYCountChars     = 0;
  3994         }
  4012 	lpsiStartInfo.dwFillAttribute   = 0;
  3995         lpsiStartInfo.cbReserved2       = 0;
  4013 	lpsiStartInfo.dwFlags           = STARTF_USESTDHANDLES /*| STARTF_USEPOSITION*/;
  3996         lpsiStartInfo.lpReserved2       = NULL;
  4014 	if ((showWindowBooleanOrNil != nil) && (showWindowBooleanOrNil != @symbol(default))) {
  3997         lpsiStartInfo.hStdInput         = NULL;
  4015 	    lpsiStartInfo.dwFlags |= STARTF_USESHOWWINDOW;
  3998         lpsiStartInfo.hStdOutput        = NULL;
  4016 	    lpsiStartInfo.wShowWindow = showWindowBooleanOrNil == true ? SW_SHOWNORMAL : SW_HIDE;
  3999         lpsiStartInfo.hStdError         = NULL;
  4017 	}
  4000 
  4018 	lpsiStartInfo.cbReserved2       = 0;
  4001         /*
  4019 	lpsiStartInfo.lpReserved2       = NULL;
  4002          * set create process flags
  4020 	lpsiStartInfo.hStdInput         = NULL;
  4003          * if the flags arg is nil, use common defaults;
  4021 	lpsiStartInfo.hStdOutput        = NULL;
  4004          * if non-nil, it must be a positive integer containing the fdwCreate bits.
  4022 	lpsiStartInfo.hStdError         = NULL;
  4005          */
  4023 
  4006         if (flagsOrNil != nil) {
  4024 	/*
  4007             fdwCreate = __longIntVal(flagsOrNil);
  4025 	 * set create process flags
  4008         } else {
  4026 	 * if the flags arg is nil, use common defaults;
  4009             fdwCreate = CREATE_NEW_CONSOLE; //|IDLE_PRIORITY_CLASS; // DETACHED_PROCESS; // NORMAL_PRIORITY_CLASS ;
  4027 	 * if non-nil, it must be a positive integer containing the fdwCreate bits.
  4010             if (newPgrp == true) {
  4028 	 */
  4011                 fdwCreate |= CREATE_NEW_PROCESS_GROUP;
  4029 	if (flagsOrNil != nil) {
  4012             }
  4030 	    fdwCreate = __longIntVal(flagsOrNil);
  4013             fdwCreate |= CREATE_DEFAULT_ERROR_MODE;
  4031 	} else {
  4014         }
  4032 	    fdwCreate = CREATE_NEW_CONSOLE; //|IDLE_PRIORITY_CLASS; // DETACHED_PROCESS; // NORMAL_PRIORITY_CLASS ;
  4015 
  4033 	    if (newPgrp == true) {
  4016         if (fdArray == nil) {
  4034 		fdwCreate |= CREATE_NEW_PROCESS_GROUP;
  4017             stdinHandle  = (HANDLE) _get_osfhandle (0);
  4035 	    }
  4018             stdoutHandle = (HANDLE) _get_osfhandle (1);
  4036 	    fdwCreate |= CREATE_DEFAULT_ERROR_MODE;
  4019             stderrHandle  = (HANDLE) _get_osfhandle (2);
  4037 	}
  4020         } else if (__isArrayLike(fdArray) && (__arraySize(fdArray) >= 3)) {
  4038 
  4021             if (__ArrayInstPtr(fdArray)->a_element[0] != nil) {
  4039 	if (fdArray == nil) {
  4022                 if (__isExternalAddressLike(__ArrayInstPtr(fdArray)->a_element[0])) {
  4040 	    stdinHandle  = (HANDLE) _get_osfhandle (0);
  4023                     stdinHandle = _HANDLEVal(__ArrayInstPtr(fdArray)->a_element[0]);
  4041 	    stdoutHandle = (HANDLE) _get_osfhandle (1);
  4024                 } else {
  4042 	    stderrHandle  = (HANDLE) _get_osfhandle (2);
  4025                     stdinHandle = (HANDLE) _get_osfhandle (__intVal(__ArrayInstPtr(fdArray)->a_element[0]));
  4043 	} else if (__isArrayLike(fdArray) && (__arraySize(fdArray) >= 3)) {
  4026                 }
  4044 	    if (__ArrayInstPtr(fdArray)->a_element[0] != nil) {
  4027             }
  4045 		if (__isExternalAddressLike(__ArrayInstPtr(fdArray)->a_element[0])) {
  4028             if (__ArrayInstPtr(fdArray)->a_element[1] != nil) {
  4046 		    stdinHandle = _HANDLEVal(__ArrayInstPtr(fdArray)->a_element[0]);
  4029                 if (__isExternalAddressLike(__ArrayInstPtr(fdArray)->a_element[1])) {
  4047 		} else {
  4030                     stdoutHandle = _HANDLEVal(__ArrayInstPtr(fdArray)->a_element[1]);
  4048 		    stdinHandle = (HANDLE) _get_osfhandle (__intVal(__ArrayInstPtr(fdArray)->a_element[0]));
  4031                 } else {
  4049 		}
  4032                     stdoutHandle = (HANDLE) _get_osfhandle (__intVal(__ArrayInstPtr(fdArray)->a_element[1]));
  4050 	    }
  4033                 }
  4051 	    if (__ArrayInstPtr(fdArray)->a_element[1] != nil) {
  4034             }
  4052 		if (__isExternalAddressLike(__ArrayInstPtr(fdArray)->a_element[1])) {
  4035             if (__ArrayInstPtr(fdArray)->a_element[2] != nil) {
  4053 		    stdoutHandle = _HANDLEVal(__ArrayInstPtr(fdArray)->a_element[1]);
  4036                 if (__isExternalAddressLike(__ArrayInstPtr(fdArray)->a_element[2])) {
  4054 		} else {
  4037                     stderrHandle  = _HANDLEVal(__ArrayInstPtr(fdArray)->a_element[2]);
  4055 		    stdoutHandle = (HANDLE) _get_osfhandle (__intVal(__ArrayInstPtr(fdArray)->a_element[1]));
  4038                 } else {
  4056 		}
  4039                     stderrHandle = (HANDLE) _get_osfhandle (__intVal(__ArrayInstPtr(fdArray)->a_element[2]));
  4057 	    }
  4040                 }
  4058 	    if (__ArrayInstPtr(fdArray)->a_element[2] != nil) {
  4041             }
  4059 		if (__isExternalAddressLike(__ArrayInstPtr(fdArray)->a_element[2])) {
  4042         } else {
  4060 		    stderrHandle  = _HANDLEVal(__ArrayInstPtr(fdArray)->a_element[2]);
  4043             console_fprintf(stderr, "Win32OS [warning]: bad fd arg in createProcess\n");
  4061 		} else {
  4044         }
  4062 		    stderrHandle = (HANDLE) _get_osfhandle (__intVal(__ArrayInstPtr(fdArray)->a_element[2]));
       
  4063 		}
       
  4064 	    }
       
  4065 	} else {
       
  4066 	    console_fprintf(stderr, "Win32OS [warning]: bad fd arg in createProcess\n");
       
  4067 	}
  4045 
  4068 
  4046 #if defined(PROCESSDEBUGWIN32)
  4069 #if defined(PROCESSDEBUGWIN32)
  4047         console_fprintf(stderr, "stdin %x\n", stdinHandle);
  4070 	if (flag_PROCESSDEBUGWIN32) {
  4048         console_fprintf(stderr, "stdout %x\n", stdoutHandle);
  4071 	    console_fprintf(stderr, "stdin %x\n", stdinHandle);
  4049         console_fprintf(stderr, "stderr %x\n", stderrHandle);
  4072 	    console_fprintf(stderr, "stdout %x\n", stdoutHandle);
  4050 #endif
  4073 	    console_fprintf(stderr, "stderr %x\n", stderrHandle);
  4051 
  4074 	}
  4052         {
  4075 #endif
  4053             HANDLE childHandle;
  4076 
  4054             int sameHandle = (stdoutHandle == stderrHandle);
  4077 	{
  4055 
  4078 	    HANDLE childHandle;
  4056             // these MUST be inheritable!
  4079 	    int sameHandle = (stdoutHandle == stderrHandle);
  4057             if (stdinHandle) {
  4080 
       
  4081 	    // these MUST be inheritable!
       
  4082 	    if (stdinHandle) {
  4058 #if 0
  4083 #if 0
  4059                 if (SetHandleInformation(stdinHandle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) {
  4084 		if (SetHandleInformation(stdinHandle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) {
  4060                     // good
  4085 		    // good
  4061                 } else {
  4086 		} else {
  4062                     console_fprintf(stderr, "Win32OS [warning]: SetHandleInformation failed in createProcess\n");
  4087 		    console_fprintf(stderr, "Win32OS [warning]: SetHandleInformation failed in createProcess\n");
  4063                 }
  4088 		}
  4064 #else
  4089 #else
  4065                 if (DuplicateHandle(GetCurrentProcess(), stdinHandle, GetCurrentProcess(),
  4090 		if (DuplicateHandle(GetCurrentProcess(), stdinHandle, GetCurrentProcess(),
  4066                                       &childHandle, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
  4091 				      &childHandle, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
  4067                     stdinHandle = childHandle;
  4092 		    stdinHandle = childHandle;
  4068                     mustClose_stdinHandle = 1;
  4093 		    mustClose_stdinHandle = 1;
  4069                 } else {
  4094 		} else {
  4070                     console_fprintf(stderr, "Win32OS [warning]: duplicateHandle failed in createProcess\n");
  4095 		    console_fprintf(stderr, "Win32OS [warning]: duplicateHandle failed in createProcess\n");
  4071                 }
  4096 		}
  4072 #endif
  4097 #endif
  4073             }
  4098 	    }
  4074             if (stdoutHandle) {
  4099 	    if (stdoutHandle) {
  4075 #if 0
  4100 #if 0
  4076                 if (SetHandleInformation(stdoutHandle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) {
  4101 		if (SetHandleInformation(stdoutHandle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) {
  4077                     // good
  4102 		    // good
  4078                 } else {
  4103 		} else {
  4079                     console_fprintf(stderr, "Win32OS [warning]: SetHandleInformation failed in createProcess\n");
  4104 		    console_fprintf(stderr, "Win32OS [warning]: SetHandleInformation failed in createProcess\n");
  4080                 }
  4105 		}
  4081 #else
  4106 #else
  4082                 if (DuplicateHandle(GetCurrentProcess(), stdoutHandle, GetCurrentProcess(),
  4107 		if (DuplicateHandle(GetCurrentProcess(), stdoutHandle, GetCurrentProcess(),
  4083                                       &childHandle, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
  4108 				      &childHandle, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
  4084                     stdoutHandle = childHandle;
  4109 		    stdoutHandle = childHandle;
  4085                     mustClose_stdoutHandle = 1;
  4110 		    mustClose_stdoutHandle = 1;
  4086                 } else {
  4111 		} else {
  4087                     console_fprintf(stderr, "Win32OS [warning]: duplicateHandle failed in createProcess\n");
  4112 		    console_fprintf(stderr, "Win32OS [warning]: duplicateHandle failed in createProcess\n");
  4088                 }
  4113 		}
  4089 #endif
  4114 #endif
  4090             }
  4115 	    }
  4091             if (stderrHandle) {
  4116 	    if (stderrHandle) {
  4092                 if (sameHandle) {
  4117 		if (sameHandle) {
  4093                     stderrHandle = stdoutHandle;
  4118 		    stderrHandle = stdoutHandle;
  4094                 } else {
  4119 		} else {
  4095 #if 0
  4120 #if 0
  4096                     if (SetHandleInformation(stderrHandle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) {
  4121 		    if (SetHandleInformation(stderrHandle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) {
  4097                         // good
  4122 			// good
  4098                     } else {
  4123 		    } else {
  4099                         console_fprintf(stderr, "Win32OS [warning]: SetHandleInformation failed in createProcess\n");
  4124 			console_fprintf(stderr, "Win32OS [warning]: SetHandleInformation failed in createProcess\n");
  4100                     }
  4125 		    }
  4101 #else
  4126 #else
  4102                     if (DuplicateHandle(GetCurrentProcess(), stderrHandle, GetCurrentProcess(),
  4127 		    if (DuplicateHandle(GetCurrentProcess(), stderrHandle, GetCurrentProcess(),
  4103                                           &childHandle, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
  4128 					  &childHandle, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
  4104                         stderrHandle = childHandle;
  4129 			stderrHandle = childHandle;
  4105                         mustClose_stderrHandle = 1;
  4130 			mustClose_stderrHandle = 1;
  4106                     } else {
  4131 		    } else {
  4107                         console_fprintf(stderr, "Win32OS [warning]: duplicateHandle failed in createProcess\n");
  4132 			console_fprintf(stderr, "Win32OS [warning]: duplicateHandle failed in createProcess\n");
  4108                     }
  4133 		    }
  4109 #endif
  4134 #endif
  4110                 }
  4135 		}
  4111             }
  4136 	    }
  4112         }
  4137 	}
  4113         lpsiStartInfo.hStdInput  = stdinHandle;
  4138 	lpsiStartInfo.hStdInput  = stdinHandle;
  4114         lpsiStartInfo.hStdOutput = stdoutHandle;
  4139 	lpsiStartInfo.hStdOutput = stdoutHandle;
  4115         lpsiStartInfo.hStdError  = stderrHandle;
  4140 	lpsiStartInfo.hStdError  = stderrHandle;
  4116 
  4141 
  4117         if (doFork == true) {
  4142 	if (doFork == true) {
  4118 #ifdef PROCESSDEBUGWIN32
  4143 #ifdef PROCESSDEBUGWIN32
  4119             console_fprintf(stderr, "create process cmdPath:<%s> cmdLine:<%s> in <%s>\n", cmdPath, cmdLine, dir);
  4144 	    if (flag_PROCESSDEBUGWIN32) {
  4120 #endif
  4145 		console_fprintf(stderr, "create process cmdPath:<%s> cmdLine:<%s> in <%s>\n", cmdPath, cmdLine, dir);
  4121             if (CreateProcessW( cmdPathWP,
  4146 	    }
  4122                                 cmdLineWP,
  4147 #endif
  4123                                 &securityAttributes, NULL /* &securityAttributes */,
  4148 	    memset(&lppiProcInfo, 0, sizeof (lppiProcInfo));
  4124                                 securityAttributes.bInheritHandle,      /* inherit handles */
  4149 
  4125                                 fdwCreate | CREATE_SUSPENDED,           /* resume after setting affinity */
  4150 	    if (CreateProcessW( cmdPathWP,
  4126                                 NULL,                                   /* env */
  4151 				cmdLineWP,
  4127                                 dirNameWP,
  4152 				&securityAttributes, NULL /* &securityAttributes */,
  4128                                 &lpsiStartInfo,
  4153 				securityAttributes.bInheritHandle,      /* inherit handles */
  4129                                 &lppiProcInfo ))
  4154 				fdwCreate | CREATE_SUSPENDED,           /* resume after setting affinity */
  4130             {
  4155 				NULL,                                   /* env */
  4131                 DWORD_PTR processAffinityMask, systemAffinityMask;
  4156 				dirNameWP,
  4132 
  4157 				&lpsiStartInfo,
  4133                 /*
  4158 				&lppiProcInfo ))
  4134                  * Process was created suspended, now set the affinity mask
  4159 	    {
  4135                  * to any processor, and resume the processes main thread.
  4160 		DWORD_PTR processAffinityMask, systemAffinityMask;
  4136                  * (librun/process.s limited the affinity to a single processor).
  4161 
  4137                  */
  4162 		/*
  4138                 GetProcessAffinityMask(lppiProcInfo.hProcess, &processAffinityMask, &systemAffinityMask);
  4163 		 * Process was created suspended, now set the affinity mask
  4139                 SetProcessAffinityMask(lppiProcInfo.hProcess, systemAffinityMask);
  4164 		 * to any processor, and resume the processes main thread.
  4140                 if ((fdwCreate & CREATE_SUSPENDED) == 0) {
  4165 		 * (librun/process.s limited the affinity to a single processor).
  4141                     ResumeThread(lppiProcInfo.hThread);
  4166 		 */
  4142                 }
  4167 		GetProcessAffinityMask(lppiProcInfo.hProcess, &processAffinityMask, &systemAffinityMask);
  4143                 CloseHandle(lppiProcInfo.hThread);
  4168 		SetProcessAffinityMask(lppiProcInfo.hProcess, systemAffinityMask);
       
  4169 		if ((fdwCreate & CREATE_SUSPENDED) == 0) {
       
  4170 		    ResumeThread(lppiProcInfo.hThread);
       
  4171 		}
       
  4172 		CloseHandle(lppiProcInfo.hThread);
  4144 
  4173 
  4145 #if 0
  4174 #if 0
  4146                 // only works with real console handles
  4175 		// only works with real console handles
  4147                 {
  4176 		{
  4148                     // change the child's stdIn (console) mode
  4177 		    // change the child's stdIn (console) mode
  4149                     DWORD mode = 0;
  4178 		    DWORD mode = 0;
  4150 
  4179 
  4151                     if (! GetConsoleMode(stdinHandle, &mode)) {
  4180 		    if (! GetConsoleMode(stdinHandle, &mode)) {
  4152                         console_fprintf(stderr, "Win32OS [warning]: GetConsoleMode failed in createProcess\n");
  4181 			console_fprintf(stderr, "Win32OS [warning]: GetConsoleMode failed in createProcess\n");
  4153                     }
  4182 		    }
  4154                     if (! SetConsoleMode(stdinHandle, mode & (~ENABLE_ECHO_INPUT))){
  4183 		    if (! SetConsoleMode(stdinHandle, mode & (~ENABLE_ECHO_INPUT))){
  4155                         console_fprintf(stderr, "Win32OS [warning]: SetConsoleMode failed in createProcess\n");
  4184 			console_fprintf(stderr, "Win32OS [warning]: SetConsoleMode failed in createProcess\n");
  4156                     }
  4185 		    }
  4157                 }
  4186 		}
  4158 #endif
  4187 #endif
  4159                 if (mustClose_stdinHandle) {
  4188 		if (mustClose_stdinHandle) {
  4160                     CloseHandle(stdinHandle);
  4189 		    CloseHandle(stdinHandle);
  4161                 }
  4190 		}
  4162                 if (mustClose_stdoutHandle) {
  4191 		if (mustClose_stdoutHandle) {
  4163                     CloseHandle(stdoutHandle);
  4192 		    CloseHandle(stdoutHandle);
  4164                 }
  4193 		}
  4165                 if (mustClose_stderrHandle) {
  4194 		if (mustClose_stderrHandle) {
  4166                     CloseHandle(stderrHandle);
  4195 		    CloseHandle(stderrHandle);
  4167                 }
  4196 		}
  4168 #ifdef PROCESSDEBUGWIN32
  4197 #ifdef PROCESSDEBUGWIN32
  4169                 console_fprintf(stderr, "created process hProcess=%x\n", lppiProcInfo.hProcess);
  4198 		if (flag_PROCESSDEBUGWIN32) {
  4170 #endif
  4199 		    console_fprintf(stderr, "created process hProcess=%x pid=%d\n", lppiProcInfo.hProcess, lppiProcInfo.dwProcessId);
  4171 
  4200 		}
  4172                 __externalAddressVal(handle) = lppiProcInfo.hProcess;
  4201 #endif
  4173                 ((struct __Win32OperatingSystem__Win32ProcessHandle_struct *)(handle))->pid = __mkSmallInteger(lppiProcInfo.dwProcessId);
  4202 
  4174                 RETURN (handle);
  4203 		__externalAddressVal(handle) = lppiProcInfo.hProcess;
  4175             }
  4204 		((struct __Win32OperatingSystem__Win32ProcessHandle_struct *)(handle))->pid = __mkSmallInteger(lppiProcInfo.dwProcessId);
       
  4205 		RETURN (handle);
       
  4206 	    }
  4176 #ifdef PROCESSDEBUGWIN32
  4207 #ifdef PROCESSDEBUGWIN32
  4177             console_fprintf(stderr, "created process error %d\n", GetLastError());
  4208 	    if (flag_PROCESSDEBUGWIN32) {
  4178 #endif
  4209 		console_fprintf(stderr, "created process error %d\n", GetLastError());
  4179             RETURN (nil);
  4210 	    }
  4180         } else {
  4211 #endif
  4181             ; /* should never be called that way */
  4212 	    RETURN (nil);
  4182         }
  4213 	} else {
       
  4214 	    ; /* should never be called that way */
       
  4215 	}
  4183     }
  4216     }
  4184 %}.
  4217 %}.
  4185     "
  4218     "
  4186      path-argument not string
  4219      path-argument not string
  4187      or argArray not an array/nil
  4220      or argArray not an array/nil
  4737 	fileHandle = nil;
  4770 	fileHandle = nil;
  4738 	argumentError = @symbol(missingCreateMode);
  4771 	argumentError = @symbol(missingCreateMode);
  4739 	goto badArgument;
  4772 	goto badArgument;
  4740     }
  4773     }
  4741 #ifdef PROCESSDEBUGWIN32
  4774 #ifdef PROCESSDEBUGWIN32
  4742     console_fprintf(stderr, "name:<%s> access:%x share:%x create:%x attr:%x\n",
  4775     if (flag_PROCESSDEBUGWIN32) {
  4743 		name, access, share, create, attr);
  4776 	console_fprintf(stderr, "name:<%s> access:%x share:%x create:%x attr:%x\n",
       
  4777 			name, access, share, create, attr);
       
  4778     }
  4744 #endif
  4779 #endif
  4745     if (__isStringLike(pathName)) {
  4780     if (__isStringLike(pathName)) {
  4746 	h = CreateFileA(name, access, share, 0 /* sa */, create, attr, 0 /* hTempl */);
  4781 	h = CreateFileA(name, access, share, 0 /* sa */, create, attr, 0 /* hTempl */);
  4747     } else {
  4782     } else {
  4748 	h = CreateFileW(_wPathName, access, share, 0 /* sa */, create, attr, 0 /* hTempl */);
  4783 	h = CreateFileW(_wPathName, access, share, 0 /* sa */, create, attr, 0 /* hTempl */);
  7447 #else
  7482 #else
  7448     /*
  7483     /*
  7449      * make fileDescriptors from handles
  7484      * make fileDescriptors from handles
  7450      */
  7485      */
  7451 # ifdef PROCESSDEBUGWIN32
  7486 # ifdef PROCESSDEBUGWIN32
  7452     console_printf("piperead %x\n",pipeRead);
  7487     if (flag_PROCESSDEBUGWIN32) {
  7453     console_printf("pipewrite %x\n",pipeWrite);
  7488 	console_printf("piperead %x\n",pipeRead);
       
  7489 	console_printf("pipewrite %x\n",pipeWrite);
       
  7490     }
  7454 # endif
  7491 # endif
  7455     fd1 = __mkSmallInteger(_open_osfhandle(pipeRead, O_BINARY));
  7492     fd1 = __mkSmallInteger(_open_osfhandle(pipeRead, O_BINARY));
  7456     fd2 = __mkSmallInteger(_open_osfhandle(pipeWrite, O_BINARY));
  7493     fd2 = __mkSmallInteger(_open_osfhandle(pipeWrite, O_BINARY));
  7457 #endif
  7494 #endif
  7458 out:;
  7495 out:;
  7474     if (__isExternalAddressLike(pid) ) {
  7511     if (__isExternalAddressLike(pid) ) {
  7475 	HANDLE __pid = _HANDLEVal(pid);
  7512 	HANDLE __pid = _HANDLEVal(pid);
  7476 
  7513 
  7477 	if (__pid != 0) {
  7514 	if (__pid != 0) {
  7478 #ifdef PROCESSDEBUGWIN32
  7515 #ifdef PROCESSDEBUGWIN32
  7479 	    console_printf("Close ProcessHandle %x\n", __pid);
  7516 	    if (flag_PROCESSDEBUGWIN32) {
       
  7517 		console_printf("Close ProcessHandle %x\n", __pid);
       
  7518 	    }
  7480 #endif
  7519 #endif
  7481 	    CloseHandle(__pid);
  7520 	    CloseHandle(__pid);
  7482 	    _SETHANDLEVal(pid, 0);
  7521 	    _SETHANDLEVal(pid, 0);
  7483 	}
  7522 	}
  7484     }
  7523     }
  7784 %}.
  7823 %}.
  7785 
  7824 
  7786     "/ <apicall: dword "GetLastError" () module: "kernel32.dll" >
  7825     "/ <apicall: dword "GetLastError" () module: "kernel32.dll" >
  7787 
  7826 
  7788     "
  7827     "
  7789         self primGetLastError
  7828 	self primGetLastError
  7790     "
  7829     "
  7791 !
  7830 !
  7792 
  7831 
  7793 primSetLastError: i
  7832 primSetLastError: i
  7794     "mostly used to clear the last error code"
  7833     "mostly used to clear the last error code"
  7911 
  7950 
  7912     handle := Win32MutexHandle new.
  7951     handle := Win32MutexHandle new.
  7913 %{
  7952 %{
  7914     if (__isString(lpName)
  7953     if (__isString(lpName)
  7915      && ((bInitialOwner == true) || (bInitialOwner == false))) {
  7954      && ((bInitialOwner == true) || (bInitialOwner == false))) {
  7916         void *c_descr = NULL;
  7955 	void *c_descr = NULL;
  7917         char *c_name;
  7956 	char *c_name;
  7918         HANDLE c_handle;
  7957 	HANDLE c_handle;
  7919 
  7958 
  7920         c_name = __stringVal(lpName);
  7959 	c_name = __stringVal(lpName);
  7921 
  7960 
  7922         if (lpSecurityDescriptor != nil) {
  7961 	if (lpSecurityDescriptor != nil) {
  7923             if (__isExternalAddressLike(lpSecurityDescriptor)
  7962 	    if (__isExternalAddressLike(lpSecurityDescriptor)
  7924              || __isExternalBytesLike(lpSecurityDescriptor) ) {
  7963 	     || __isExternalBytesLike(lpSecurityDescriptor) ) {
  7925                 c_descr = __externalAddressVal(lpSecurityDescriptor);
  7964 		c_descr = __externalAddressVal(lpSecurityDescriptor);
  7926             } else
  7965 	    } else
  7927                 goto badArg;
  7966 		goto badArg;
  7928         }
  7967 	}
  7929         c_handle = CreateMutexA(c_descr, bInitialOwner == true, c_name);
  7968 	c_handle = CreateMutexA(c_descr, bInitialOwner == true, c_name);
  7930         if (c_handle == NULL) {
  7969 	if (c_handle == NULL) {
  7931             RETURN(nil);
  7970 	    RETURN(nil);
  7932         }
  7971 	}
  7933         __externalAddressVal(handle) = c_handle;
  7972 	__externalAddressVal(handle) = c_handle;
  7934         RETURN(handle);
  7973 	RETURN(handle);
  7935     }
  7974     }
  7936     badArg: ;
  7975     badArg: ;
  7937 %}.
  7976 %}.
  7938     "/ <apicall: handle "CreateMutexA" (lpstr bool lpstr) module: "kernel32.dll" >
  7977     "/ <apicall: handle "CreateMutexA" (lpstr bool lpstr) module: "kernel32.dll" >
  7939     ^ self primitiveFailed
  7978     ^ self primitiveFailed
  7950 
  7989 
  7951     handle := Win32MutexHandle new.
  7990     handle := Win32MutexHandle new.
  7952 %{
  7991 %{
  7953     if (__isString(lpName)
  7992     if (__isString(lpName)
  7954      && ((bInitialOwner == true) || (bInitialOwner == false))) {
  7993      && ((bInitialOwner == true) || (bInitialOwner == false))) {
  7955         DWORD c_dwDesiredAccess = 0;
  7994 	DWORD c_dwDesiredAccess = 0;
  7956         char *c_name;
  7995 	char *c_name;
  7957         BOOL c_initialOwner = (bInitialOwner == true);
  7996 	BOOL c_initialOwner = (bInitialOwner == true);
  7958         HANDLE c_handle;
  7997 	HANDLE c_handle;
  7959 
  7998 
  7960         c_name = __stringVal(lpName);
  7999 	c_name = __stringVal(lpName);
  7961 
  8000 
  7962         if (dwDesiredAccess != nil) {
  8001 	if (dwDesiredAccess != nil) {
  7963             if (! __isSmallInteger(dwDesiredAccess)) {
  8002 	    if (! __isSmallInteger(dwDesiredAccess)) {
  7964                 goto badArg;
  8003 		goto badArg;
  7965             }
  8004 	    }
  7966             c_dwDesiredAccess = __intVal(dwDesiredAccess);
  8005 	    c_dwDesiredAccess = __intVal(dwDesiredAccess);
  7967         }
  8006 	}
  7968         c_handle = OpenMutexA(c_dwDesiredAccess, c_initialOwner, c_name);
  8007 	c_handle = OpenMutexA(c_dwDesiredAccess, c_initialOwner, c_name);
  7969         if (c_handle == NULL) {
  8008 	if (c_handle == NULL) {
  7970             RETURN(nil);
  8009 	    RETURN(nil);
  7971         }
  8010 	}
  7972         __externalAddressVal(handle) = c_handle;
  8011 	__externalAddressVal(handle) = c_handle;
  7973         RETURN(handle);
  8012 	RETURN(handle);
  7974     }
  8013     }
  7975     badArg: ;
  8014     badArg: ;
  7976 %}.
  8015 %}.
  7977     "/ <apicall: handle "OpenMutexA" (lpstr bool lpstr) module: "kernel32.dll" >
  8016     "/ <apicall: handle "OpenMutexA" (lpstr bool lpstr) module: "kernel32.dll" >
  7978     ^ self primitiveFailed
  8017     ^ self primitiveFailed