| 13717 | |
| 13718 | |
| 13719 | ResultType Script::ActionExec(LPTSTR aAction, LPTSTR aParams, LPTSTR aWorkingDir, bool aDisplayErrors |
| 13720 | , LPTSTR aRunShowMode, HANDLE *aProcess, bool aUpdateLastError, bool aUseRunAs, Var *aOutputVar) |
| 13721 | // Caller should specify NULL for aParams if it wants us to attempt to parse out params from |
| 13722 | // within aAction. Caller may specify empty string ("") instead to specify no params at all. |
| 13723 | // Remember that aAction and aParams can both be NULL, so don't dereference without checking first. |
| 13724 | // Note: For the Run & RunWait commands, aParams should always be NULL. Params are parsed out of |
| 13725 | // the aActionString at runtime, here, rather than at load-time because Run & RunWait might contain |
| 13726 | // dereferenced variable(s), which can only be resolved at runtime. |
| 13727 | { |
| 13728 | HANDLE hprocess_local; |
| 13729 | HANDLE &hprocess = aProcess ? *aProcess : hprocess_local; // To simplify other things. |
| 13730 | hprocess = NULL; // Init output param if the caller gave us memory to store it. Even if caller didn't, other things below may rely on this being initialized. |
| 13731 | if (aOutputVar) // Same |
| 13732 | aOutputVar->Assign(); |
| 13733 | |
| 13734 | // Launching nothing is always a success: |
| 13735 | if (!aAction || !*aAction) return OK; |
| 13736 | |
| 13737 | // Make sure this is set to NULL because CreateProcess() won't work if it's the empty string: |
| 13738 | if (aWorkingDir && !*aWorkingDir) |
| 13739 | aWorkingDir = NULL; |
| 13740 | |
| 13741 | #define IS_VERB(str) ( !_tcsicmp(str, _T("find")) || !_tcsicmp(str, _T("explore")) || !_tcsicmp(str, _T("open"))\ |
| 13742 | || !_tcsicmp(str, _T("edit")) || !_tcsicmp(str, _T("print")) || !_tcsicmp(str, _T("properties")) ) |
| 13743 | |
| 13744 | // Set default items to be run by ShellExecute(). These are also used by the error |
| 13745 | // reporting at the end, which is why they're initialized even if CreateProcess() works |
| 13746 | // and there's no need to use ShellExecute(): |
| 13747 | LPTSTR shell_verb = NULL; |
| 13748 | LPTSTR shell_action = aAction; |
| 13749 | LPTSTR shell_params = NULL; |
| 13750 | |
| 13751 | /////////////////////////////////////////////////////////////////////////////////// |
| 13752 | // This next section is done prior to CreateProcess() because when aParams is NULL, |
| 13753 | // we need to find out whether aAction contains a system verb. |
| 13754 | /////////////////////////////////////////////////////////////////////////////////// |
| 13755 | if (aParams) // Caller specified the params (even an empty string counts, for this purpose). |
| 13756 | { |
| 13757 | if (IS_VERB(shell_action)) |
| 13758 | { |
| 13759 | shell_verb = shell_action; |
| 13760 | shell_action = aParams; |
| 13761 | } |
| 13762 | else |
| 13763 | shell_params = aParams; |
| 13764 | } |
| 13765 | else // Caller wants us to try to parse params out of aAction. |
| 13766 | { |
| 13767 | // Find out the "first phrase" in the string to support the special "find" and "explore" operations. |
| 13768 | LPTSTR phrase; |
| 13769 | size_t phrase_len; |
| 13770 | // Set phrase_end to be the location of the first whitespace char, if one exists: |
| 13771 | LPTSTR phrase_end = StrChrAny(shell_action, _T(" \t")); // Find space or tab. |
| 13772 | if (phrase_end) // i.e. there is a second phrase. |
| 13773 | { |
| 13774 | phrase_len = phrase_end - shell_action; |
| 13775 | // Create a null-terminated copy of the phrase for comparison. |
| 13776 | phrase = tmemcpy(talloca(phrase_len + 1), shell_action, phrase_len); |
no test coverage detected