| ... | ... | @@ -13780,7 +13780,29 @@ fn windowsCreateProcessPathExt( |
| 13780 | 13780 | const prefixed_path = try windows.wToPrefixedFileW(null, dir_path_z); |
| 13781 | 13781 | break :dir dirOpenDirWindows(.cwd(), prefixed_path.span(), .{ |
| 13782 | 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 | 13807 | defer windows.CloseHandle(dir.handle); |
| 13786 | 13808 | |
| ... | ... | @@ -13984,55 +14006,67 @@ fn windowsCreateProcess( |
| 13984 | 14006 | lpStartupInfo: *windows.STARTUPINFOW, |
| 13985 | 14007 | lpProcessInformation: *windows.PROCESS_INFORMATION, |
| 13986 | 14008 | ) !void { |
| 13987 | | if (windows.kernel32.CreateProcessW( |
| 13988 | | app_name, |
| 13989 | | cmd_line, |
| 13990 | | null, |
| 13991 | | null, |
| 13992 | | windows.TRUE, |
| 13993 | | flags, |
| 13994 | | env_ptr, |
| 13995 | | cwd_ptr, |
| 13996 | | lpStartupInfo, |
| 13997 | | lpProcessInformation, |
| 13998 | | ) == 0) switch (windows.GetLastError()) { |
| 13999 | | .FILE_NOT_FOUND => return error.FileNotFound, |
| 14000 | | .PATH_NOT_FOUND => return error.FileNotFound, |
| 14001 | | .DIRECTORY => return error.FileNotFound, |
| 14002 | | .ACCESS_DENIED => return error.AccessDenied, |
| 14003 | | .INVALID_PARAMETER => unreachable, |
| 14004 | | .INVALID_NAME => return error.InvalidName, |
| 14005 | | .FILENAME_EXCED_RANGE => return error.NameTooLong, |
| 14006 | | .SHARING_VIOLATION => return error.FileBusy, |
| 14007 | | |
| 14008 | | // These are all the system errors that are mapped to ENOEXEC by |
| 14009 | | // the undocumented _dosmaperr (old CRT) or __acrt_errno_map_os_error |
| 14010 | | // (newer CRT) functions. Their code can be found in crt/src/dosmap.c (old SDK) |
| 14011 | | // or urt/misc/errno.cpp (newer SDK) in the Windows SDK. |
| 14012 | | .BAD_FORMAT, |
| 14013 | | .INVALID_STARTING_CODESEG, // MIN_EXEC_ERROR in errno.cpp |
| 14014 | | .INVALID_STACKSEG, |
| 14015 | | .INVALID_MODULETYPE, |
| 14016 | | .INVALID_EXE_SIGNATURE, |
| 14017 | | .EXE_MARKED_INVALID, |
| 14018 | | .BAD_EXE_FORMAT, |
| 14019 | | .ITERATED_DATA_EXCEEDS_64k, |
| 14020 | | .INVALID_MINALLOCSIZE, |
| 14021 | | .DYNLINK_FROM_INVALID_RING, |
| 14022 | | .IOPL_NOT_ENABLED, |
| 14023 | | .INVALID_SEGDPL, |
| 14024 | | .AUTODATASEG_EXCEEDS_64k, |
| 14025 | | .RING2SEG_MUST_BE_MOVABLE, |
| 14026 | | .RELOC_CHAIN_XEEDS_SEGLIM, |
| 14027 | | .INFLOOP_IN_RELOC_CHAIN, // MAX_EXEC_ERROR in errno.cpp |
| 14028 | | // This one is not mapped to ENOEXEC but it is possible, for example |
| 14029 | | // when calling CreateProcessW on a plain text file with a .exe extension |
| 14030 | | .EXE_MACHINE_TYPE_MISMATCH, |
| 14031 | | => return error.InvalidExe, |
| 14032 | | |
| 14033 | | .COMMITMENT_LIMIT => return error.SystemResources, |
| 14034 | | else => |err| return windows.unexpectedError(err), |
| 14035 | | }; |
| 14009 | const syscall: Syscall = try .start(); |
| 14010 | while (true) { |
| 14011 | if (windows.kernel32.CreateProcessW( |
| 14012 | app_name, |
| 14013 | cmd_line, |
| 14014 | null, |
| 14015 | null, |
| 14016 | windows.TRUE, |
| 14017 | flags, |
| 14018 | env_ptr, |
| 14019 | cwd_ptr, |
| 14020 | lpStartupInfo, |
| 14021 | lpProcessInformation, |
| 14022 | ) != 0) { |
| 14023 | return syscall.finish(); |
| 14024 | } else switch (windows.GetLastError()) { |
| 14025 | .INVALID_PARAMETER => unreachable, |
| 14026 | .OPERATION_ABORTED => { |
| 14027 | try syscall.checkCancel(); |
| 14028 | continue; |
| 14029 | }, |
| 14030 | .FILE_NOT_FOUND => return syscall.fail(error.FileNotFound), |
| 14031 | .PATH_NOT_FOUND => return syscall.fail(error.FileNotFound), |
| 14032 | .DIRECTORY => return syscall.fail(error.FileNotFound), |
| 14033 | .ACCESS_DENIED => return syscall.fail(error.AccessDenied), |
| 14034 | .INVALID_NAME => return syscall.fail(error.InvalidName), |
| 14035 | .FILENAME_EXCED_RANGE => return syscall.fail(error.NameTooLong), |
| 14036 | .SHARING_VIOLATION => return syscall.fail(error.FileBusy), |
| 14037 | .COMMITMENT_LIMIT => return syscall.fail(error.SystemResources), |
| 14038 | |
| 14039 | // These are all the system errors that are mapped to ENOEXEC by |
| 14040 | // the undocumented _dosmaperr (old CRT) or __acrt_errno_map_os_error |
| 14041 | // (newer CRT) functions. Their code can be found in crt/src/dosmap.c (old SDK) |
| 14042 | // or urt/misc/errno.cpp (newer SDK) in the Windows SDK. |
| 14043 | .BAD_FORMAT, |
| 14044 | .INVALID_STARTING_CODESEG, // MIN_EXEC_ERROR in errno.cpp |
| 14045 | .INVALID_STACKSEG, |
| 14046 | .INVALID_MODULETYPE, |
| 14047 | .INVALID_EXE_SIGNATURE, |
| 14048 | .EXE_MARKED_INVALID, |
| 14049 | .BAD_EXE_FORMAT, |
| 14050 | .ITERATED_DATA_EXCEEDS_64k, |
| 14051 | .INVALID_MINALLOCSIZE, |
| 14052 | .DYNLINK_FROM_INVALID_RING, |
| 14053 | .IOPL_NOT_ENABLED, |
| 14054 | .INVALID_SEGDPL, |
| 14055 | .AUTODATASEG_EXCEEDS_64k, |
| 14056 | .RING2SEG_MUST_BE_MOVABLE, |
| 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 | 14072 | /// Case-insensitive WTF-16 lookup |