aboutsummaryrefslogtreecommitdiff
path: root/win32/mingw.c (follow)
Commit message (Collapse)AuthorAgeFilesLines
* win32: retry when command needs elevated privilegesRon Yorston2025-02-031-0/+22
| | | | | | | | | | | | | | Some installer programs have an entry in their manifest to indicate that they need elevated privileges. The shell in busybox-w32 was unable to run such programs. When a program fails to run with ERROR_ELEVATION_REQUIRED, try again using ShellExecuteEx() with the 'runas' verb to give it elevated privileges. Adds 272-288 bytes. (GitHub issue #481)
* ash: strip trailing slash from directory if necessaryRon Yorston2024-12-291-0/+5
| | | | | | | | | | | The previous commit removed trailing dots and spaces from the last component of a pathname when changing directory. If the result has a trailing slash remove that too. But not if it's a drive root, to avoid 'cd C:/' showing a current directory of 'C:'. Adds 48 bytes. (GitHub issue #478)
* ash: match behaviour of cmd.exe in cd builtinRon Yorston2024-11-191-0/+13
| | | | | | | | | | | | | | The Windows API strips trailing dots and spaces from the last component of a path. cmd.exe handles this quirk when changing directory by adjusting its idea of the current directory to match reality. The shell in busybox-w32 didn't do this, leading to some confusion. Fix the shell's cd builtin so it works more like cmd.exe. Adds 64-80 bytes. (GitHub issue #478)
* win32: fix regression in chdir(2)Ron Yorston2024-10-101-7/+9
| | | | | | | | | | | | | When mingw_chdir() was introduced it canonicalised its argument (585d17d26). This had the side effect of making its case match that of the directory as stored on disk. Subsequent changes retained that behaviour for symlinks but not otherwise (69d328022, b99032390). This was noted to affect the appearance of the directory specified by the (undocumented) 'sh -d' option. Fix the case of non-symlink directories too. Adds 16-32 bytes.
* id: code shrinkRon Yorston2024-10-091-0/+2
| | | | | | | | The bogus user/group ids we use on Windows are very limited. Make these limitations explicit in the 'id' applet. Saves 464 bytes.
* win32: code shrinkRon Yorston2024-08-161-13/+13
| | | | | Add the FAST_FUNC qualifier to several Windows-specific functions. This has no effect in 64-bit builds but saves 336 bytes for 32-bit.
* win32: fix strftime(3) '%s' formatRon Yorston2024-08-141-1/+1
| | | | | | | | | | | | The '%s' format of our strftime(3) wrapper (display number of seconds since the Unix epoch) returned incorrect results on 64-bit systems for times more than 2^31 seconds after the epoch. Use the correct format. Adds 16 bytes. (GitHub issue #446)
* win32: fix another problem with stat(2)Ron Yorston2024-08-091-2/+3
| | | | | | | | | | | If we can't open a file to preserve its access time (perhaps because it doesn't belong to us) just try again without bothering about the access time. I thought I'd already done that, but that must have been in an alternative reality. Adds 16 bytes. (GitHub issue #443)
* su: detect inability to raise privilegeRon Yorston2024-08-031-22/+22
| | | | | | | | | | | | When privilege has been dropped by the 'drop' applet, the 'su' applet is unable to raise it again because ShellExecuteEx() thinks it unnecessary. Detect this situation, report an error and return exit code 2. Costs 72-112 bytes. (GitHub issue #437)
* ash: read profile script relative to binaryRon Yorston2024-07-081-0/+8
| | | | | | | As well as trying to read '/etc/profile' also look for the script 'etc/profile' relative to the location of the running binary. Adds 64-96 bytes.
* win32: code shrink system drive handling (2)Ron Yorston2024-07-071-1/+1
| | | | | | Now that get_system_drive() no longer returns a NULL pointer on error chdir_system_drive() needs to check for an empty string instead.
* win32: code shrink system drive handlingRon Yorston2024-07-071-27/+14
| | | | | | | | | | | | | | | | | | | | | | | | | | A previous commit (e3bfe3695) revised the use of getsysdir() to obtain the system directory, and hence the system drive. See the commit message for the history to that point. Further improvements are possible: - Remove getsysdir() and push the calls to GetSystemDirectory() down into get_system_drive() and get_proc_addr(). - Check the return value of GetSystemDirectory(). It's unlikely to fail, but better safe than sorry. - Instead of making all callers of get_system_drive() check for a NULL return value always return a non-NULL pointer. If the drive can't be found an empty string is returned instead (which is what the callers were using anyway). - The function need_system_drive() was only used in one place (in httpd). Move the code there and remove the function. - Use concat_path_file() where possible. Saves 76-144 bytes.
* win32: add definition for old mingw-w64FRP-5398-g89ae34445Ron Yorston2024-06-251-0/+4
|
* win32: code shrink BB_CRITICAL_ERROR_DIALOGSRon Yorston2024-06-231-1/+2
| | | | | | Rewrite the test for the value of BB_CRITICAL_ERROR_DIALOGS. Saves 16-48 bytes.
* win32: only access mode argument of open(2) if requiredRon Yorston2024-06-221-3/+5
| | | | | | | | | The wrapper function 'mingw_open()' should only read the optional third argument if the 'O_CREAT' flag bit is set. Adds 16 bytes. (GitHub issue #425)
* win32: add env var to control error dialogsRon Yorston2024-06-221-0/+6
| | | | | | | | | | | | | | | If the environment variable BB_CRITICAL_ERROR_DIALOGS is set to 1 critical error dialogs are enabled. If unset or set to any other value they aren't. In either case the error messages introduced by commit 790e37727 (win32: revert 'don't set error mode') are issued. The shell exports BB_CRITICAL_ERROR_DIALOGS to the environment immediately on any change so the setting takes effect at once. Adds 104-160 bytes. (GitHub issue #423)
* ash: allow HISTFILE=/dev/null to work as intendedRon Yorston2024-06-191-3/+8
| | | | | | | | | | | | | | | It was noted that setting HISTFILE=/dev/null in upstream BusyBox prevented shell history from being saved to a history file. This failed in busybox-w32 with an error from lseek(2). The lseek(2) wrapper was rather conservative in the file types it accepted. Allowing FILE_TYPE_CHAR makes it possible to seek on /dev/null, thus avoiding the issue with HISTFILE. In addition, the wrapper for open(2) now converts the Unix-style mode argument to Windows-style. (GitHub issue #425)
* win32: code shrink APE detection; avoid UBRon Yorston2024-06-191-3/+7
| | | | | | | | | | | | | Detecting Actually Portable Executable binaries used a longer signature than seems necessary. Six characters should be enough for anyone. When right shifting a byte by 24 bits, cast it to unsigned to avoid undefined behaviour. Saves 24-32 bytes. (GitHub issue #424)
* win32: detect Actually Portable Executable binariesRon Yorston2024-06-161-15/+23
| | | | | | | | | Check for the signature of Actually Portable Executable binaries and treat them as executable. Adds 40-64 bytes. (GitHub issue #424)
* win32: allow for trailing separator in PATHRon Yorston2024-06-141-0/+26
| | | | | | | | | | | | | | | | | | | In recent versions of Windows the PATH environment variable has a trailing semicolon. This is insignificant to Windows because it's ignored. busybox-w32 conforms to the POSIX interpretation of PATH which treats an empty path element as denoting the current directory. As result, on these versions of Windows executables may by default be run from the current directory, contrary to usual Unix practice. Attempt to detect and remove the trailing semicolon on applet start up. If the user insists, they can add a trailing semicolon to the shell variable PATH and it will be respected in the conventional manner. Adds 88-112 bytes. (GitHub issue #422)
* win32: try to avoid downloading offline filesRon Yorston2024-04-301-2/+5
| | | | | | | | It's possible that files in remote storage may not be available locally. Avoid downloading such files just to obtain file attributes. (GitHub issue #414)
* win32: adjust handling of executable extensionsRon Yorston2024-04-221-8/+12
| | | | | | | | | | | | | | | Mixing Windows and Unix-style filename extensions was causing problems. Tweak how extensions are handled to try and improve matters: - Consistently check whether the unaltered filename is an executable before trying adding extensions. - Check .exe and .com before .sh. Saves up to 16 bytes. (GitHub issue #405)
* win32: make stat(2) fail for /dev/zero, /dev/urandomRon Yorston2024-04-201-1/+2
| | | | | | | | | | /dev/zero and /dev/urandom are only available internally and as arguments to 'dd'. Since users can't otherwise access them they shouldn't be treated as existing by stat(2). With this change stat(1) and test(1) will deny their existence. (GitHub issue #282)
* win32: improvements to realpath(3)Ron Yorston2024-03-091-2/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | The previous commit unnecessarily duplicated the path returned from resolve_symlinks(), resulting in a memory leak. Thanks to avih for spotting this. Even if we can't canonicalise the path in resolve_symlinks() we can at least return the result of resolving the trailing symlink. Moreover, this can be done both when the necessary API is missing and when the filesystem doesn't support it. Not perfect, but better than nothing, and there's no cost. This change gets rid of a handful of realpath-related test failures on ReactOS and Windows XP. Some background: Commit 8ebe81483 returned the raw path when the required API was missing. This was reverted in commit f902184fa because it caused an infinite loop (GitHub issue #204). Commit 31467ddfc fixed the cause of the loop, which is why it's now safe to reintroduce a fallback return. (GitHub commit #389)
* win32: let realpath(3) work on flaky filesystemsRon Yorston2024-03-081-0/+3
| | | | | | | | | | | | Some filesystems don't support the feature required to resolve symlinks for realpath(3). In such cases just carry on without resolving symlinks. This is a trade-off between correctness and convenience. Adds 16 bytes. (GitHub issue #389)
* win32: fix detection of directories in stat(2)Ron Yorston2024-01-041-3/+5
| | | | | | | | | | | | | | | | The implementation of stat(2) detected whether a pathname ending with a directory separator was valid by checking for the error code ERROR_INVALID_NAME when GetFileAttributesExA() failed. This works if the path refers to an actual disk but not if it's on a share. In the latter case the glob '*/' incorrectly returned files that weren't directories. Add code to handle this case. Costs 16-32 bytes. (GitHub issue #381)
* win32: fix handling of relative pathsRon Yorston2023-10-041-12/+3
| | | | | | | | | | | | | | Commit 548ec7045b (win32: interpret absolute paths as relative to %SYSTEMDRIVE%) introduced the function xabsolute_path() to make relative paths absolute. This is used in 'dkpg' and 'man' to avoid having to tinker with absolute paths from upstream. Unfortunately, it's too eager to use the relative path. This results in dpkg failing to install deb files with a relative path. Saves 32-48 bytes. (GitHub issue #371)
* win32: replace readlink(2)Ron Yorston2023-08-211-11/+15
| | | | | | | | | | | | | | | The Windows implementation of readlink(2) has caused problems in the past. As, for example, with commit c29dc205d2 (win32: fix implementation of readlink(2)). Most uses of readlink(2) in BusyBox are actually calls to the (considerably more convenient) library function xmalloc_readlink(). Implement a Windows version of that and used it instead of readlink(2). This improves the handling of symbolic links (and similar reparse points) in CJK and UTF-8 code pages. Saves 48-80 bytes.
* ash: detect console state on shell start upnoconsole2Ron Yorston2023-08-201-14/+0
| | | | | | | | | | | Set 'noconsole' to match the actual state of the console (normal/ iconified) when the shell is started. Thus ShowWindow() will only be called if the actual state differs from the default or user defined state. Costs 20-24 bytes. (GitHub issue #325)
* win32: support build with FEATURE_UNICODE_SUPPORTAvi Halachmi (:avih)2023-07-221-0/+14
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | FEATURE_UTF8_MANIFEST enables Unicode args and filenames on Win 10+. FEATURE_UTF8_INPUT allows the shell prompt to digest correctly Unicode strings (as UTF8) which are typed or pasted. This commit adds support for building with FEATURE_UNICODE_SUPPORT (mostly by supporting 32 bit wchar_t which busybox expects): - Unicode-aware line-edit - for the most part cursor movement/del being (UTF8) codepoint-aware rather than assuming that one-byte equals one-char-on-screen. - Codepoint-aware operations in some other utils, like rev or wc -c. - When UNICODE_COMBINING_WCHARS and UNICODE_WIDE_WCHARS are enabled, some screen-width-aware operations, like with fold, ls, expand, etc. The busybox Unicode support is incomplete, and even less so with the builtin libc replacement functions, like wcwidth, which are active when UNICODE_USING_LOCALE is unset (mingw lacks those functions). FEATURE_CHECK_UNICODE_IN_ENV should be set so that Unicode is not hardcoded but rather depends on the ANSI codepage and some env vars: LC_ALL=C disables Unicode support, else it's enabled if ACP is UTF8. There's at least one known issue where the tab-completion-prefix-case is not updated correctly, e.g. ~/desk<tab> completes to ~/desktop/ instead of ~/Desktop/, because the code which handles it exists only at the non-unicode code paths, but that's not very critical. That seems to be the only case where mingw-specific code is disabled when Unicode is enabled, but there could be other unknown issues. None of the Unicode options is enabled by default, and the next commit will make it easier to create a build which supports Unicode.
* date: allow system date to be setRon Yorston2023-07-161-0/+23
| | | | | | | | | Implement clock_settime(2) and enable the '-s' option to allow the system time to be set. This requires elevated privileges. The code in date.c is now identical to upstream BusyBox. Costs 256-272 bytes.
* win32: code shrinkRon Yorston2023-06-041-7/+2
| | | | | | | | | | | | | | | | | | | getsysdir() wasn't used in get_proc_addr() because the former called realpath() which in turn called the latter. (Commit 4c6c8d61bc) realpath() was used to adjust the case of the path name as it was visible to the user as root's home directory. (Commit b04bbc0109) Later the home directory for "root" was changed so it no longer needed getsysdir(). (Commit 385decd6bf) The remaining uses of getsysdir() don't require the path to be canonicalised, so realpath() can be removed from getsysdir() and getsysdir() can be used in get_proc_addr(). Saves 32-64 bytes
* ash: enable 'set -/+o noconsole'Ron Yorston2023-06-011-8/+6
| | | | | | | | | | | | | | Previously the 'noconsole' shell option could only be set as a shell command line option. Allow it to be changed from within the shell by 'set -o noconsole' or 'set +o noconsole'. The console window is now minimised rather than hidden. This makes it easier for the user to access the console when 'noconsole' is in effect. Adds 8-32 bytes. (GitHub issue #325)
* win32: support "app exec link" reparse pointsRon Yorston2023-05-271-1/+36
| | | | | | | | | | | | | | | | | | Reparse points with the tag IO_REPARSE_TAG_APPEXECLINK are present in ~/AppData/Local/Microsoft/WindowsApps in Windows 10 and 11. They are: Used by Universal Windows Platform (UWP) packages to encode information that allows the application to be launched by CreateProcess. Modify readlink(2) and lsattr(1) to treat them as symbolic links, in much the same way as was done previously for junctions. They aren't really symbolic links but they're similar. Costs 128-160 bytes. (GitHub issue #327)
* win32: export xappendword()Ron Yorston2023-04-231-0/+12
| | | | | | | Export the function xappendword() from make. Use it in drop and watch. Saves 8-80 bytes, an unusually large disparity.
* win32: use CheckTokenMembership() to check privilegeRon Yorston2023-03-251-14/+16
| | | | | | | Rewrite the test for the reduced-privilege token: check whether the BUILTIN\Administrators group is enabled. This seems more directly relevant than the previous check for restrictions on the token.
* drop: add cdrop and pdrop aliasesRon Yorston2023-03-191-1/+1
| | | | | | | | | | | | | | | | Add cdrop and pdrop applets as aliases for drop. If a command isn't specified these use cmd.exe and PowerShell instead of the BusyBox shell. This makes it possible to choose the default shell used for SSH connections even in older versions of OpenSSH that don't support the DefaultShellArguments registry key. Note that to get cmd.exe to run a command rather than an interactive shell it's necessary to set the DefaultShellCommandOption registry key to '/c'. Costs 248-272 bytes.
* runuser,drop: drop runuser, tweak dropRon Yorston2023-03-191-1/+1
| | | | | | | | | | | | | | Remove the runuser applet, leaving only drop. Move drop from util-linux to miscutils. A command of the form 'drop -c command' causes the BusyBox shell to be used, just like 'drop' without any arguments. A simple OpenSSH configuration with 'drop.exe' as DefaultShell and no DefaultShellArguments now works both for interactive login and to run a command. This is useful for older versions of OpenSSH which don't support DefaultShellArguments. Saves 208-232 bytes.
* runuser: add 'drop' as an alias for runuserRon Yorston2023-03-161-1/+1
| | | | | | | | | | | | | | | | | | | The 'drop' alias for 'runuser' relaxes a number of constraints that were introduced for compatibility: - It works even if the current process doesn't have elevated privileges. - It isn't necessary to specify the name of the user. - Any command can be invoked, not just the BusyBox shell. - If the command doesn't specify a path 'drop' will first look for a BusyBox applet then search PATH. Adds 320-336 when built along with runuser. (GitHub issue #240)
* win32: code shrink detection of executablesRon Yorston2023-03-161-9/+25
| | | | | | | | | | | | Add a function, file_is_win32_exe(), to detect if a path refers to an executable. It tries adding extensions if necessary. Use this in a number of places to replace common code of the form path = alloc_ext_space(cmd); if (add_win32_extension(path) || file_is_executable(path)) Saves 32-48 bytes.
* runuser: new appletRon Yorston2023-03-131-12/+31
| | | | | | | | | | | | | | | | | | | | | Add a cut down, Windows-specific implementation of `runuser` from util-linux. This allows elevated privileges to be dropped when running in an SSH session. It also works when using `su` or starting busybox-w32 'as administrator'. There are complications: - The method used to drop privileges leaves the access token in the TokenIsElevated state. Detecting this is likely to be fragile. - The unprivileged shell is started by CreateProcessAsUserA(). In older versions of Windows this has to be loaded dynamically. Adds about 900 bytes. (GitHub issue #240)
* win32: skip ACL check in stat(2) when running as rootFRP-4881-ga6c5fd4ebRon Yorston2023-02-131-1/+2
| | | | | | | | | | Commit 88965fe20 (win32: use ACL check to clarify write permission) added code to check if a file had write permission due to an ACL entry. When running with elevated privileges this check is unnecessary as "user" permissions will be sufficient. This also prevents write permission for "other" being set without respecting umask.
* ash,make: fix CRLF handlingRon Yorston2023-01-301-2/+3
| | | | | | | Fix remove_cr() so it only removes CRs which are part of a CRLF pair, not every CR. Add a test case for the shell.
* win32: another stat(2) + access time fixRon Yorston2023-01-261-1/+1
| | | | | | | | Use FILE_SHARE_READ when opening a file to check if it's an executable. Without that other processes running in parallel might be unable to access the file. (GitHub issue #284)
* win32: only count subdirectories if necessaryRon Yorston2023-01-231-3/+15
| | | | | | | | | | | | | | | | | Commit 7fb95a2a5 (win32: try to get link count for directories) allowed stat(2) to report accurate values of st_nlink for directories. There are only a couple of places in busybox-w32 where these values are required. Disable counting of subdirectories by default and only enable it when necessary. Microsoft kindly provide directories to test edge cases like this: C:/Windows/WinSxS (contains many subdirectories) C:/Windows/WinSxS/Manifests (contains many files) Adds 84-112 bytes.
* win32: limit setting of errno when lazy loading failsRon Yorston2023-01-221-3/+3
| | | | | | | | | | | | The function get_proc_addr() facilitates dynamic loading of functions from DLLs. In the event of failure it set errno to ENOSYS. This is sometimes useful, such as in the implementations of link(2), symlink(2) and realpath(3). However, many other uses of lazy loading can recover from failure or simply don't care. In these cases setting errno is unnecessary and may be counterproductive. (GitHub issue #283)
* win32: more minor improvements to stat(2)Ron Yorston2023-01-181-29/+26
| | | | | | | | | | | | | | | | The previous commit incorrectly stated that preventing the access time of a file from being updated only required it to be opened with GENERIC_READ access. In fact, even though we don't want to update the access time, SetFileTime() also requires the file to have been opened with FILE_WRITE_ATTRIBUTES access. There's no need to explicitly avoid device files when checking for execute mode: since device files are now 'character special' they are excluded by the test that the file is 'regular'. Device files should be excluded when trying to obtain extra file data using GetFileInformationByHandle(). It shouldn't be possible for CreateFile() to open then, so there's no point in trying.
* win32: minor improvements to stat(2)Ron Yorston2023-01-171-9/+9
| | | | | | | | | | | Commit b11352dcb (win32: prevent stat(2) from updating access times) requested GENERIC_ALL access when opening files. It appears that GENERIC_READ is sufficient and also faster. The code to find the actual size of compressed or sparse files only needs to be invoked for regular files. Avoiding unnecessary calls to GetCompressedFileSize() makes stat(2) slightly faster and gives a more accurate number of blocks for symbolic links.
* win32: use ACL check to clarify write permissionRon Yorston2023-01-161-27/+30
| | | | | | | | | | | | | | | | | On Microsoft Windows a user's home directory doesn't belong to them: it actually belongs to the 'system' user. stat(2) was only using ownership to determine write permissions, so it seemed that the user was unable to write to their own home directory. Use a call to AccessCheck() to determine if files can be accessed due to an entry in their ACL. User home directories and a few other files (e.g. C:/Users/Public) now have the correct write permission. This feature is enabled by FEATURE_EXTRA_FILE_DATA. Costs 220-256 bytes. (GitHub issue #280)
* win32: fix permissions of read-only directoryRon Yorston2023-01-111-1/+1
| | | | | | | | | | | | Commit 15fcbd19c8 (win32: special case for devices files in stat(2)) caused write permissions on directories to respect the read-only attribute. This is incorrect: the read-only attribute doesn't apply to directories in the same way as to normal files. Give directories write permission unconditionally, as before, though respecting umask. (GitHub issue #280)