1 #include "rktio.h"
2 #include "rktio_private.h"
3
4 #define rktio_SHOW_CONVERT(v) case RKTIO_ ## v: show_mode = v; break
5
rktio_shell_execute(rktio_t * rktio,const char * verb,const char * target,const char * arg,const char * dir,int show_mode)6 rktio_ok_t rktio_shell_execute(rktio_t *rktio,
7 const char *verb,
8 const char *target,
9 const char *arg,
10 const char *dir,
11 int show_mode)
12 /* dir needs to have normalized path separators */
13 {
14 #ifdef RKTIO_SYSTEM_WINDOWS
15 SHELLEXECUTEINFOW se;
16 int ok, r;
17
18 switch(show_mode) {
19 rktio_SHOW_CONVERT(SW_HIDE);
20 rktio_SHOW_CONVERT(SW_MAXIMIZE);
21 rktio_SHOW_CONVERT(SW_MINIMIZE);
22 rktio_SHOW_CONVERT(SW_RESTORE);
23 rktio_SHOW_CONVERT(SW_SHOW);
24 rktio_SHOW_CONVERT(SW_SHOWDEFAULT);
25 rktio_SHOW_CONVERT(SW_SHOWMAXIMIZED);
26 rktio_SHOW_CONVERT(SW_SHOWMINIMIZED);
27 rktio_SHOW_CONVERT(SW_SHOWMINNOACTIVE);
28 rktio_SHOW_CONVERT(SW_SHOWNA);
29 rktio_SHOW_CONVERT(SW_SHOWNOACTIVATE);
30 rktio_SHOW_CONVERT(SW_SHOWNORMAL);
31 }
32
33 memset(&se, 0, sizeof(se));
34 se.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_DDEWAIT;
35 se.cbSize = sizeof(se);
36 if (!verb)
37 se.lpVerb = NULL;
38 else
39 se.lpVerb = WIDE_PATH_copy(verb);
40 se.lpFile = WIDE_PATH_copy(target);
41 se.lpParameters = WIDE_PATH_copy(arg);
42 se.lpDirectory = WIDE_PATH_copy(dir);
43 se.nShow = show_mode;
44 se.hwnd = NULL;
45
46 r = (int)(intptr_t)ShellExecuteW(se.hwnd, se.lpVerb, se.lpFile, se.lpParameters,
47 se.lpDirectory, se.nShow);
48
49 ok = (r > 32);
50
51 if (!ok) {
52 switch(r) {
53 case ERROR_FILE_NOT_FOUND:
54 case ERROR_PATH_NOT_FOUND:
55 case ERROR_BAD_FORMAT:
56 set_windows_error(r);
57 break;
58 default:
59 /* Other results are not Windows error codes,
60 so just collapse them to a Racket error */
61 set_racket_error(RKTIO_ERROR_SHELL_EXECUTE_FAILED);
62 break;
63 }
64 }
65
66 if (se.lpVerb) free((char *)se.lpVerb);
67 free((char *)se.lpFile);
68 free((char *)se.lpParameters);
69 free((char *)se.lpDirectory);
70
71 return ok;
72 #else
73 set_racket_error(RKTIO_ERROR_UNSUPPORTED);
74 return 0;
75 #endif
76 }
77