| ... | @@ -13780,7 +13780,29 @@ fn windowsCreateProcessPathExt( | ... | @@ -13780,7 +13780,29 @@ fn windowsCreateProcessPathExt( |
| 13780 | const prefixed_path = try windows.wToPrefixedFileW(null, dir_path_z); | 13780 | const prefixed_path = try windows.wToPrefixedFileW(null, dir_path_z); |
| 13781 | break :dir dirOpenDirWindows(.cwd(), prefixed_path.span(), .{ | 13781 | break :dir dirOpenDirWindows(.cwd(), prefixed_path.span(), .{ |
| 13782 | .iterate = true, | 13782 | .iterate = true, |
| 13783 | }) catch return error.FileNotFound; | 13783 | }) catch |err| switch (err) { |
| | 13784 | // These errors must not be ignored because they should not be able |
| | 13785 | // to affect which file is chosen to execute. Also `error.Canceled` |
| | 13786 | // must never be swallowed. |
| | 13787 | error.Canceled, |
| | 13788 | error.SystemResources, |
| | 13789 | error.Unexpected, |
| | 13790 | error.ProcessFdQuotaExceeded, |
| | 13791 | error.SystemFdQuotaExceeded, |
| | 13792 | => |e| return e, |
| | 13793 | |
| | 13794 | error.AccessDenied, |
| | 13795 | error.PermissionDenied, |
| | 13796 | error.SymLinkLoop, |
| | 13797 | error.FileNotFound, |
| | 13798 | error.NotDir, |
| | 13799 | error.NoDevice, |
| | 13800 | error.NetworkNotFound, |
| | 13801 | error.NameTooLong, |
| | 13802 | error.BadPathName, |
| | 13803 | error.DeviceBusy, |
| | 13804 | => return error.FileNotFound, |
| | 13805 | }; |
| 13784 | }; | 13806 | }; |
| 13785 | defer windows.CloseHandle(dir.handle); | 13807 | defer windows.CloseHandle(dir.handle); |
| 13786 | | 13808 | |
| ... | @@ -13984,55 +14006,67 @@ fn windowsCreateProcess( | ... | @@ -13984,55 +14006,67 @@ fn windowsCreateProcess( |
| 13984 | lpStartupInfo: *windows.STARTUPINFOW, | 14006 | lpStartupInfo: *windows.STARTUPINFOW, |
| 13985 | lpProcessInformation: *windows.PROCESS_INFORMATION, | 14007 | lpProcessInformation: *windows.PROCESS_INFORMATION, |
| 13986 | ) !void { | 14008 | ) !void { |
| 13987 | if (windows.kernel32.CreateProcessW( | 14009 | const syscall: Syscall = try .start(); |
| 13988 | app_name, | 14010 | while (true) { |
| 13989 | cmd_line, | 14011 | if (windows.kernel32.CreateProcessW( |
| 13990 | null, | 14012 | app_name, |
| 13991 | null, | 14013 | cmd_line, |
| 13992 | windows.TRUE, | 14014 | null, |
| 13993 | flags, | 14015 | null, |
| 13994 | env_ptr, | 14016 | windows.TRUE, |
| 13995 | cwd_ptr, | 14017 | flags, |
| 13996 | lpStartupInfo, | 14018 | env_ptr, |
| 13997 | lpProcessInformation, | 14019 | cwd_ptr, |
| 13998 | ) == 0) switch (windows.GetLastError()) { | 14020 | lpStartupInfo, |
| 13999 | .FILE_NOT_FOUND => return error.FileNotFound, | 14021 | lpProcessInformation, |
| 14000 | .PATH_NOT_FOUND => return error.FileNotFound, | 14022 | ) != 0) { |
| 14001 | .DIRECTORY => return error.FileNotFound, | 14023 | return syscall.finish(); |
| 14002 | .ACCESS_DENIED => return error.AccessDenied, | 14024 | } else switch (windows.GetLastError()) { |
| 14003 | .INVALID_PARAMETER => unreachable, | 14025 | .INVALID_PARAMETER => unreachable, |
| 14004 | .INVALID_NAME => return error.InvalidName, | 14026 | .OPERATION_ABORTED => { |
| 14005 | .FILENAME_EXCED_RANGE => return error.NameTooLong, | 14027 | try syscall.checkCancel(); |
| 14006 | .SHARING_VIOLATION => return error.FileBusy, | 14028 | continue; |
| 14007 | | 14029 | }, |
| 14008 | // These are all the system errors that are mapped to ENOEXEC by | 14030 | .FILE_NOT_FOUND => return syscall.fail(error.FileNotFound), |
| 14009 | // the undocumented _dosmaperr (old CRT) or __acrt_errno_map_os_error | 14031 | .PATH_NOT_FOUND => return syscall.fail(error.FileNotFound), |
| 14010 | // (newer CRT) functions. Their code can be found in crt/src/dosmap.c (old SDK) | 14032 | .DIRECTORY => return syscall.fail(error.FileNotFound), |
| 14011 | // or urt/misc/errno.cpp (newer SDK) in the Windows SDK. | 14033 | .ACCESS_DENIED => return syscall.fail(error.AccessDenied), |
| 14012 | .BAD_FORMAT, | 14034 | .INVALID_NAME => return syscall.fail(error.InvalidName), |
| 14013 | .INVALID_STARTING_CODESEG, // MIN_EXEC_ERROR in errno.cpp | 14035 | .FILENAME_EXCED_RANGE => return syscall.fail(error.NameTooLong), |
| 14014 | .INVALID_STACKSEG, | 14036 | .SHARING_VIOLATION => return syscall.fail(error.FileBusy), |
| 14015 | .INVALID_MODULETYPE, | 14037 | .COMMITMENT_LIMIT => return syscall.fail(error.SystemResources), |
| 14016 | .INVALID_EXE_SIGNATURE, | 14038 | |
| 14017 | .EXE_MARKED_INVALID, | 14039 | // These are all the system errors that are mapped to ENOEXEC by |
| 14018 | .BAD_EXE_FORMAT, | 14040 | // the undocumented _dosmaperr (old CRT) or __acrt_errno_map_os_error |
| 14019 | .ITERATED_DATA_EXCEEDS_64k, | 14041 | // (newer CRT) functions. Their code can be found in crt/src/dosmap.c (old SDK) |
| 14020 | .INVALID_MINALLOCSIZE, | 14042 | // or urt/misc/errno.cpp (newer SDK) in the Windows SDK. |
| 14021 | .DYNLINK_FROM_INVALID_RING, | 14043 | .BAD_FORMAT, |
| 14022 | .IOPL_NOT_ENABLED, | 14044 | .INVALID_STARTING_CODESEG, // MIN_EXEC_ERROR in errno.cpp |
| 14023 | .INVALID_SEGDPL, | 14045 | .INVALID_STACKSEG, |
| 14024 | .AUTODATASEG_EXCEEDS_64k, | 14046 | .INVALID_MODULETYPE, |
| 14025 | .RING2SEG_MUST_BE_MOVABLE, | 14047 | .INVALID_EXE_SIGNATURE, |
| 14026 | .RELOC_CHAIN_XEEDS_SEGLIM, | 14048 | .EXE_MARKED_INVALID, |
| 14027 | .INFLOOP_IN_RELOC_CHAIN, // MAX_EXEC_ERROR in errno.cpp | 14049 | .BAD_EXE_FORMAT, |
| 14028 | // This one is not mapped to ENOEXEC but it is possible, for example | 14050 | .ITERATED_DATA_EXCEEDS_64k, |
| 14029 | // when calling CreateProcessW on a plain text file with a .exe extension | 14051 | .INVALID_MINALLOCSIZE, |
| 14030 | .EXE_MACHINE_TYPE_MISMATCH, | 14052 | .DYNLINK_FROM_INVALID_RING, |
| 14031 | => return error.InvalidExe, | 14053 | .IOPL_NOT_ENABLED, |
| 14032 | | 14054 | .INVALID_SEGDPL, |
| 14033 | .COMMITMENT_LIMIT => return error.SystemResources, | 14055 | .AUTODATASEG_EXCEEDS_64k, |
| 14034 | else => |err| return windows.unexpectedError(err), | 14056 | .RING2SEG_MUST_BE_MOVABLE, |
| 14035 | }; | 14057 | .RELOC_CHAIN_XEEDS_SEGLIM, |
| | 14058 | .INFLOOP_IN_RELOC_CHAIN, // MAX_EXEC_ERROR in errno.cpp |
| | 14059 | // This one is not mapped to ENOEXEC but it is possible, for example |
| | 14060 | // when calling CreateProcessW on a plain text file with a .exe extension |
| | 14061 | .EXE_MACHINE_TYPE_MISMATCH, |
| | 14062 | => return syscall.fail(error.InvalidExe), |
| | 14063 | |
| | 14064 | else => |err| { |
| | 14065 | syscall.finish(); |
| | 14066 | return windows.unexpectedError(err); |
| | 14067 | }, |
| | 14068 | } |
| | 14069 | } |
| 14036 | } | 14070 | } |
| 14037 | | 14071 | |
| 14038 | /// Case-insensitive WTF-16 lookup | 14072 | /// Case-insensitive WTF-16 lookup |