diff options
Diffstat (limited to 'win32/process.c')
-rw-r--r-- | win32/process.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/win32/process.c b/win32/process.c index fd89707ca..33f45ee42 100644 --- a/win32/process.c +++ b/win32/process.c | |||
@@ -501,6 +501,38 @@ static NORETURN void wait_for_child(HANDLE child, const char *cmd) | |||
501 | exit((int)code); | 501 | exit((int)code); |
502 | } | 502 | } |
503 | 503 | ||
504 | static intptr_t | ||
505 | shell_execute(const char *path, char *const *argv) | ||
506 | { | ||
507 | SHELLEXECUTEINFO info; | ||
508 | char *args; | ||
509 | |||
510 | memset(&info, 0, sizeof(SHELLEXECUTEINFO)); | ||
511 | info.cbSize = sizeof(SHELLEXECUTEINFO); | ||
512 | info.fMask = SEE_MASK_NOCLOSEPROCESS; | ||
513 | /* info.hwnd = NULL; */ | ||
514 | info.lpVerb = "runas"; | ||
515 | info.lpFile = path; | ||
516 | |||
517 | args = NULL; | ||
518 | if (*argv++) { | ||
519 | while (*argv) { | ||
520 | char *q = quote_arg(*argv++); | ||
521 | args = xappendword(args, q); | ||
522 | free(q); | ||
523 | } | ||
524 | } | ||
525 | |||
526 | info.lpParameters = args; | ||
527 | /* info.lpDirectory = NULL; */ | ||
528 | info.nShow = SW_SHOWNORMAL; | ||
529 | |||
530 | mingw_shell_execute(&info); | ||
531 | |||
532 | free(args); | ||
533 | return info.hProcess ? (intptr_t)info.hProcess : -1; | ||
534 | } | ||
535 | |||
504 | int | 536 | int |
505 | mingw_execvp(const char *cmd, char *const *argv) | 537 | mingw_execvp(const char *cmd, char *const *argv) |
506 | { | 538 | { |
@@ -514,6 +546,16 @@ int | |||
514 | mingw_execve(const char *cmd, char *const *argv, char *const *envp) | 546 | mingw_execve(const char *cmd, char *const *argv, char *const *envp) |
515 | { | 547 | { |
516 | intptr_t ret = mingw_spawn_interpreter(P_NOWAIT, cmd, argv, envp, 0); | 548 | intptr_t ret = mingw_spawn_interpreter(P_NOWAIT, cmd, argv, envp, 0); |
549 | |||
550 | if (ret == -1 && GetLastError() == ERROR_ELEVATION_REQUIRED) { | ||
551 | // Command exists but failed because it wants elevated privileges. | ||
552 | // Try again using ShellExecuteEx(). | ||
553 | SetLastError(0); | ||
554 | ret = shell_execute(cmd, argv); | ||
555 | if (GetLastError()) | ||
556 | exit(1); | ||
557 | } | ||
558 | |||
517 | if (ret != -1) | 559 | if (ret != -1) |
518 | wait_for_child((HANDLE)ret, cmd); | 560 | wait_for_child((HANDLE)ret, cmd); |
519 | return ret; | 561 | return ret; |