ReactOS 0.4.16-dev-1176-g64fda67
shlexec.cpp File Reference
#include "precomp.h"
#include <undocshell.h>
Include dependency graph for shlexec.cpp:

Go to the source code of this file.

Macros

#define STARTF_SHELLPRIVATE   0x400
 
#define SEE_MASK_CLASSALL   (SEE_MASK_CLASSNAME | SEE_MASK_CLASSKEY)
 

Typedefs

typedef UINT_PTR(* SHELL_ExecuteW32) (const WCHAR *lpCmd, WCHAR *env, BOOL shWait, const SHELLEXECUTEINFOW *sei, LPSHELLEXECUTEINFOW sei_out)
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (exec)
 
EXTERN_C BOOL PathIsExeW (LPCWSTR lpszPath)
 
static BOOL SHELL_InRunDllProcess (VOID)
 
static void ParseNoTildeEffect (PWSTR &res, LPCWSTR &args, DWORD &len, DWORD &used, int argNum)
 
static void ParseTildeEffect (PWSTR &res, LPCWSTR &args, DWORD &len, DWORD &used, int argNum)
 
static BOOL SHELL_ArgifyW (WCHAR *out, DWORD len, const WCHAR *fmt, const WCHAR *lpFile, LPITEMIDLIST pidl, LPCWSTR args, DWORD *out_len, const WCHAR *lpDir)
 
static HRESULT SHELL_GetPathFromIDListForExecuteW (LPCITEMIDLIST pidl, LPWSTR pszPath, UINT uOutSize)
 
static UINT_PTR SHELL_ExecuteW (const WCHAR *lpCmd, WCHAR *env, BOOL shWait, const SHELLEXECUTEINFOW *psei, LPSHELLEXECUTEINFOW psei_out)
 
static LPWSTR SHELL_BuildEnvW (const WCHAR *path)
 
static BOOL SHELL_TryAppPathW (LPCWSTR szName, LPWSTR lpResult, WCHAR **env)
 
static UINT SHELL_FindExecutableByVerb (LPCWSTR lpVerb, LPWSTR key, LPWSTR classname, LPWSTR command, LONG commandlen)
 
static UINT SHELL_FindExecutable (LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpVerb, LPWSTR lpResult, DWORD resultLen, LPWSTR key, WCHAR **env, LPITEMIDLIST pidl, LPCWSTR args)
 
static HDDEDATA CALLBACK dde_cb (UINT uType, UINT uFmt, HCONV hConv, HSZ hsz1, HSZ hsz2, HDDEDATA hData, ULONG_PTR dwData1, ULONG_PTR dwData2)
 
static unsigned dde_connect (const WCHAR *key, const WCHAR *start, WCHAR *ddeexec, const WCHAR *lpFile, WCHAR *env, LPCWSTR szCommandline, LPITEMIDLIST pidl, SHELL_ExecuteW32 execfunc, const SHELLEXECUTEINFOW *psei, LPSHELLEXECUTEINFOW psei_out)
 
static UINT_PTR execute_from_key (LPCWSTR key, LPCWSTR lpFile, WCHAR *env, LPCWSTR szCommandline, LPCWSTR executable_name, SHELL_ExecuteW32 execfunc, LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out)
 
HINSTANCE WINAPI FindExecutableA (LPCSTR lpFile, LPCSTR lpDirectory, LPSTR lpResult)
 
HINSTANCE WINAPI FindExecutableW (LPCWSTR lpFile, LPCWSTR lpDirectory, LPWSTR lpResult)
 
static HKEY ShellExecute_GetClassKey (const SHELLEXECUTEINFOW *sei)
 
static HRESULT shellex_get_dataobj (LPSHELLEXECUTEINFOW sei, CComPtr< IDataObject > &dataObj)
 
static HRESULT shellex_run_context_menu_default (IShellExtInit *obj, LPSHELLEXECUTEINFOW sei)
 
static HRESULT shellex_load_object_and_run (HKEY hkey, LPCGUID guid, LPSHELLEXECUTEINFOW sei)
 
static HRESULT shellex_get_contextmenu (LPSHELLEXECUTEINFOW sei, CComPtr< IContextMenu > &cm)
 
static HRESULT ShellExecute_ContextMenuVerb (LPSHELLEXECUTEINFOW sei)
 
static LONG ShellExecute_FromContextMenuHandlers (LPSHELLEXECUTEINFOW sei)
 
static UINT_PTR SHELL_quote_and_execute (LPCWSTR wcmd, LPCWSTR wszParameters, LPCWSTR lpstrProtocol, LPCWSTR wszApplicationName, LPWSTR env, LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out, SHELL_ExecuteW32 execfunc)
 
static UINT_PTR SHELL_execute_class (LPCWSTR wszApplicationName, LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out, SHELL_ExecuteW32 execfunc)
 
static BOOL SHELL_translate_idlist (LPSHELLEXECUTEINFOW sei, LPWSTR wszParameters, DWORD parametersLen, LPWSTR wszApplicationName, DWORD dwApplicationNameLen)
 
static BOOL SHELL_InvokePidl (_In_ LPSHELLEXECUTEINFOW sei, _In_ LPCITEMIDLIST pidl)
 
static UINT_PTR SHELL_execute_url (LPCWSTR lpFile, LPCWSTR wcmd, LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out, SHELL_ExecuteW32 execfunc)
 
static void do_error_dialog (UINT_PTR retval, HWND hwnd, WCHAR *filename)
 
static WCHARexpand_environment (const WCHAR *str)
 
static BOOL SHELL_execute (LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
 
HINSTANCE WINAPI ShellExecuteA (HWND hWnd, LPCSTR lpVerb, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, INT iShowCmd)
 
static DWORD ShellExecute_Normal (_Inout_ LPSHELLEXECUTEINFOW sei)
 
static VOID ShellExecute_ShowError (_In_ const SHELLEXECUTEINFOW *ExecInfo, _In_opt_ LPCWSTR pszCaption, _In_ DWORD dwError)
 
BOOL WINAPI DECLSPEC_HOTPATCH ShellExecuteExA (LPSHELLEXECUTEINFOA sei)
 
BOOL WINAPI DECLSPEC_HOTPATCH ShellExecuteExW (LPSHELLEXECUTEINFOW sei)
 
HINSTANCE WINAPI ShellExecuteW (HWND hwnd, LPCWSTR lpVerb, LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd)
 
EXTERN_C HINSTANCE WINAPI WOWShellExecute (HWND hWnd, LPCSTR lpVerb, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, INT iShowCmd, void *callback)
 
EXTERN_C void WINAPI OpenAs_RunDLLW (HWND hwnd, HINSTANCE hinst, LPCWSTR cmdline, int cmdshow)
 
EXTERN_C void WINAPI OpenAs_RunDLLA (HWND hwnd, HINSTANCE hinst, LPCSTR cmdline, int cmdshow)
 
static LPCWSTR SplitParams (LPCWSTR psz, LPWSTR pszArg0, size_t cchArg0)
 
HRESULT WINAPI ShellExecCmdLine (HWND hwnd, LPCWSTR pwszCommand, LPCWSTR pwszStartDir, int nShow, LPVOID pUnused, DWORD dwSeclFlags)
 
EXTERN_C HINSTANCE WINAPI RealShellExecuteExA (_In_opt_ HWND hwnd, _In_opt_ LPCSTR lpOperation, _In_opt_ LPCSTR lpFile, _In_opt_ LPCSTR lpParameters, _In_opt_ LPCSTR lpDirectory, _In_opt_ LPSTR lpReturn, _In_opt_ LPCSTR lpTitle, _In_opt_ LPVOID lpReserved, _In_ INT nCmdShow, _Out_opt_ PHANDLE lphProcess, _In_ DWORD dwFlags)
 
EXTERN_C HINSTANCE WINAPI RealShellExecuteExW (_In_opt_ HWND hwnd, _In_opt_ LPCWSTR lpOperation, _In_opt_ LPCWSTR lpFile, _In_opt_ LPCWSTR lpParameters, _In_opt_ LPCWSTR lpDirectory, _In_opt_ LPWSTR lpReturn, _In_opt_ LPCWSTR lpTitle, _In_opt_ LPVOID lpReserved, _In_ INT nCmdShow, _Out_opt_ PHANDLE lphProcess, _In_ DWORD dwFlags)
 
EXTERN_C HINSTANCE WINAPI RealShellExecuteA (_In_opt_ HWND hwnd, _In_opt_ LPCSTR lpOperation, _In_opt_ LPCSTR lpFile, _In_opt_ LPCSTR lpParameters, _In_opt_ LPCSTR lpDirectory, _In_opt_ LPSTR lpReturn, _In_opt_ LPCSTR lpTitle, _In_opt_ LPVOID lpReserved, _In_ INT nCmdShow, _Out_opt_ PHANDLE lphProcess)
 
EXTERN_C HINSTANCE WINAPI RealShellExecuteW (_In_opt_ HWND hwnd, _In_opt_ LPCWSTR lpOperation, _In_opt_ LPCWSTR lpFile, _In_opt_ LPCWSTR lpParameters, _In_opt_ LPCWSTR lpDirectory, _In_opt_ LPWSTR lpReturn, _In_opt_ LPCWSTR lpTitle, _In_opt_ LPVOID lpReserved, _In_ INT nCmdShow, _Out_opt_ PHANDLE lphProcess)
 
EXTERN_C LONG PathProcessCommandW (_In_ PCWSTR pszSrc, _Out_writes_opt_(dwBuffSize) PWSTR pszDest, _In_ INT cchDest, _In_ DWORD dwFlags)
 
static VOID ShellExec_RunDLL_Helper (_In_opt_ HWND hwnd, _In_opt_ HINSTANCE hInstance, _In_ PCWSTR pszCmdLine, _In_ INT nCmdShow)
 
EXTERN_C VOID WINAPI ShellExec_RunDLLA (_In_opt_ HWND hwnd, _In_opt_ HINSTANCE hInstance, _In_ PCSTR pszCmdLine, _In_ INT nCmdShow)
 
EXTERN_C VOID WINAPI ShellExec_RunDLLW (_In_opt_ HWND hwnd, _In_opt_ HINSTANCE hInstance, _In_ PCWSTR pszCmdLine, _In_ INT nCmdShow)
 

Macro Definition Documentation

◆ SEE_MASK_CLASSALL

#define SEE_MASK_CLASSALL   (SEE_MASK_CLASSNAME | SEE_MASK_CLASSKEY)

Definition at line 33 of file shlexec.cpp.

◆ STARTF_SHELLPRIVATE

#define STARTF_SHELLPRIVATE   0x400

Definition at line 31 of file shlexec.cpp.

Typedef Documentation

◆ SHELL_ExecuteW32

typedef UINT_PTR(* SHELL_ExecuteW32) (const WCHAR *lpCmd, WCHAR *env, BOOL shWait, const SHELLEXECUTEINFOW *sei, LPSHELLEXECUTEINFOW sei_out)

Definition at line 35 of file shlexec.cpp.

Function Documentation

◆ dde_cb()

static HDDEDATA CALLBACK dde_cb ( UINT  uType,
UINT  uFmt,
HCONV  hConv,
HSZ  hsz1,
HSZ  hsz2,
HDDEDATA  hData,
ULONG_PTR  dwData1,
ULONG_PTR  dwData2 
)
static

Definition at line 983 of file shlexec.cpp.

986{
987 TRACE("dde_cb: %04x, %04x, %p, %p, %p, %p, %08lx, %08lx\n",
988 uType, uFmt, hConv, hsz1, hsz2, hData, dwData1, dwData2);
989 return NULL;
990}
#define NULL
Definition: types.h:112
#define TRACE(s)
Definition: solgame.cpp:4

Referenced by dde_connect().

◆ dde_connect()

static unsigned dde_connect ( const WCHAR key,
const WCHAR start,
WCHAR ddeexec,
const WCHAR lpFile,
WCHAR env,
LPCWSTR  szCommandline,
LPITEMIDLIST  pidl,
SHELL_ExecuteW32  execfunc,
const SHELLEXECUTEINFOW psei,
LPSHELLEXECUTEINFOW  psei_out 
)
static

Definition at line 1001 of file shlexec.cpp.

1005{
1006 WCHAR regkey[256];
1007 WCHAR * endkey = regkey + wcslen(key);
1008 WCHAR app[256], topic[256], ifexec[256], static_res[256];
1010 WCHAR * res;
1011 LONG applen, topiclen, ifexeclen;
1012 WCHAR * exec;
1013 DWORD ddeInst = 0;
1014 DWORD tid;
1015 DWORD resultLen, endkeyLen;
1016 HSZ hszApp, hszTopic;
1017 HCONV hConv;
1018 HDDEDATA hDdeData;
1019 unsigned ret = SE_ERR_NOASSOC;
1020 BOOL unicode = !(GetVersion() & 0x80000000);
1021
1022 if (strlenW(key) + 1 > ARRAY_SIZE(regkey))
1023 {
1024 FIXME("input parameter %s larger than buffer\n", debugstr_w(key));
1025 return 2;
1026 }
1027 wcscpy(regkey, key);
1028 endkeyLen = ARRAY_SIZE(regkey) - (endkey - regkey);
1029 if (strlenW(L"\\application") + 1 > endkeyLen)
1030 {
1031 FIXME("endkey %s overruns buffer\n", debugstr_w(L"\\application"));
1032 return 2;
1033 }
1034 wcscpy(endkey, L"\\application");
1035 applen = sizeof(app);
1036 if (RegQueryValueW(HKEY_CLASSES_ROOT, regkey, app, &applen) != ERROR_SUCCESS)
1037 {
1038 WCHAR command[1024], fullpath[MAX_PATH];
1039 LPWSTR ptr = NULL;
1040 DWORD ret = 0;
1041
1042 /* Get application command from start string and find filename of application */
1043 if (*start == '"')
1044 {
1045 if (strlenW(start + 1) + 1 > ARRAY_SIZE(command))
1046 {
1047 FIXME("size of input parameter %s larger than buffer\n",
1048 debugstr_w(start + 1));
1049 return 2;
1050 }
1051 wcscpy(command, start + 1);
1052 if ((ptr = wcschr(command, '"')))
1053 * ptr = 0;
1054 ret = SearchPathW(NULL, command, L".exe", ARRAY_SIZE(fullpath), fullpath, &ptr);
1055 }
1056 else
1057 {
1058 LPCWSTR p;
1059 LPWSTR space;
1060 for (p = start; (space = const_cast<LPWSTR>(strchrW(p, ' '))); p = space + 1)
1061 {
1062 int idx = space - start;
1063 memcpy(command, start, idx * sizeof(WCHAR));
1064 command[idx] = '\0';
1065 if ((ret = SearchPathW(NULL, command, L".exe", ARRAY_SIZE(fullpath), fullpath, &ptr)))
1066 break;
1067 }
1068 if (!ret)
1069 ret = SearchPathW(NULL, start, L".exe", ARRAY_SIZE(fullpath), fullpath, &ptr);
1070 }
1071
1072 if (!ret)
1073 {
1074 ERR("Unable to find application path for command %s\n", debugstr_w(start));
1075 return ERROR_ACCESS_DENIED;
1076 }
1077 if (strlenW(ptr) + 1 > ARRAY_SIZE(app))
1078 {
1079 FIXME("size of found path %s larger than buffer\n", debugstr_w(ptr));
1080 return 2;
1081 }
1082 wcscpy(app, ptr);
1083
1084 /* Remove extensions (including .so) */
1085 ptr = app + wcslen(app) - 3;
1086 if (ptr > app && !wcscmp(ptr, L".so"))
1087 *ptr = 0;
1088
1089 ptr = const_cast<LPWSTR>(strrchrW(app, '.'));
1090 assert(ptr);
1091 *ptr = 0;
1092 }
1093
1094 if (strlenW(L"\\topic") + 1 > endkeyLen)
1095 {
1096 FIXME("endkey %s overruns buffer\n", debugstr_w(L"\\topic"));
1097 return 2;
1098 }
1099 wcscpy(endkey, L"\\topic");
1100 topiclen = sizeof(topic);
1101 if (RegQueryValueW(HKEY_CLASSES_ROOT, regkey, topic, &topiclen) != ERROR_SUCCESS)
1102 {
1103 wcscpy(topic, L"System");
1104 }
1105
1106 if (unicode)
1107 {
1109 return 2;
1110 }
1111 else
1112 {
1114 return 2;
1115 }
1116
1119
1120 hConv = DdeConnect(ddeInst, hszApp, hszTopic, NULL);
1121 exec = ddeexec;
1122 if (!hConv)
1123 {
1124 TRACE("Launching %s\n", debugstr_w(start));
1125 ret = execfunc(start, env, TRUE, psei, psei_out);
1126 if (ret <= 32)
1127 {
1128 TRACE("Couldn't launch\n");
1129 goto error;
1130 }
1131 /* if ddeexec is NULL, then we just need to exit here */
1132 if (ddeexec == NULL)
1133 {
1134 TRACE("Exiting because ddeexec is NULL. ret=42.\n");
1135 /* See https://docs.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shellexecutew */
1136 /* for reason why we use 42 here and also "Shell32_apitest ShellExecuteW" regression test */
1137 return 42;
1138 }
1139 /* if ddeexec is 'empty string', then we just need to exit here */
1140 if (wcscmp(ddeexec, L"") == 0)
1141 {
1142 TRACE("Exiting because ddeexec is 'empty string'. ret=42.\n");
1143 /* See https://docs.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shellexecutew */
1144 /* for reason why we use 42 here and also "Shell32_apitest ShellExecuteW" regression test */
1145 return 42;
1146 }
1147 hConv = DdeConnect(ddeInst, hszApp, hszTopic, NULL);
1148 if (!hConv)
1149 {
1150 TRACE("Couldn't connect. ret=%d\n", ret);
1153 return 30; /* whatever */
1154 }
1155 if (strlenW(L"\\ifexec") + 1 > endkeyLen)
1156 {
1157 FIXME("endkey %s overruns buffer\n", debugstr_w(L"\\ifexec"));
1158 return 2;
1159 }
1160 strcpyW(endkey, L"\\ifexec");
1161 ifexeclen = sizeof(ifexec);
1162 if (RegQueryValueW(HKEY_CLASSES_ROOT, regkey, ifexec, &ifexeclen) == ERROR_SUCCESS)
1163 {
1164 exec = ifexec;
1165 }
1166 }
1167
1168 SHELL_ArgifyW(static_res, ARRAY_SIZE(static_res), exec, lpFile, pidl, szCommandline, &resultLen, NULL);
1169 if (resultLen > ARRAY_SIZE(static_res))
1170 {
1171 dynamic_res.Allocate(resultLen);
1172 res = dynamic_res;
1173 SHELL_ArgifyW(dynamic_res, resultLen, exec, lpFile, pidl, szCommandline, NULL, NULL);
1174 }
1175 else
1176 res = static_res;
1177 TRACE("%s %s => %s\n", debugstr_w(exec), debugstr_w(lpFile), debugstr_w(res));
1178
1179 /* It's documented in the KB 330337 that IE has a bug and returns
1180 * error DMLERR_NOTPROCESSED on XTYP_EXECUTE request.
1181 */
1182 if (unicode)
1183 hDdeData = DdeClientTransaction((LPBYTE)res, (strlenW(res) + 1) * sizeof(WCHAR), hConv, 0L, 0, XTYP_EXECUTE, 30000, &tid);
1184 else
1185 {
1186 DWORD lenA = WideCharToMultiByte(CP_ACP, 0, res, -1, NULL, 0, NULL, NULL);
1188 resA.Allocate(lenA);
1189 WideCharToMultiByte(CP_ACP, 0, res, -1, resA, lenA, NULL, NULL);
1190 hDdeData = DdeClientTransaction( (LPBYTE)(LPSTR)resA, lenA, hConv, 0L, 0,
1191 XTYP_EXECUTE, 10000, &tid );
1192 }
1193 if (hDdeData)
1194 DdeFreeDataHandle(hDdeData);
1195 else
1196 WARN("DdeClientTransaction failed with error %04x\n", DdeGetLastError(ddeInst));
1197 ret = 33;
1198
1199 DdeDisconnect(hConv);
1200
1201error:
1203
1204 return ret;
1205}
#define ARRAY_SIZE(A)
Definition: main.h:20
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
bool Allocate(_In_ size_t nElements=1)
Definition: atlalloc.h:143
wcscpy
static LPCWSTR LPCWSTR LPCWSTR env
Definition: db.cpp:170
HDDEDATA WINAPI DdeClientTransaction(LPBYTE, DWORD, HCONV, HSZ, UINT, UINT, DWORD, LPDWORD)
Definition: ddeclient.c:1122
#define DMLERR_NO_ERROR
Definition: ddeml.h:242
BOOL WINAPI DdeUninitialize(DWORD)
Definition: ddemisc.c:1112
UINT WINAPI DdeInitializeW(LPDWORD, PFNCALLBACK, DWORD, DWORD)
Definition: ddemisc.c:1095
HCONV WINAPI DdeConnect(DWORD, HSZ, HSZ, PCONVCONTEXT)
Definition: ddeclient.c:84
UINT WINAPI DdeGetLastError(DWORD)
Definition: ddemisc.c:253
HSZ WINAPI DdeCreateStringHandleW(DWORD, LPCWSTR, INT)
Definition: ddemisc.c:608
BOOL WINAPI DdeDisconnect(HCONV)
Definition: ddeclient.c:1363
#define XTYP_EXECUTE
Definition: ddeml.h:185
#define CP_WINUNICODE
Definition: ddeml.h:33
BOOL WINAPI DdeFreeDataHandle(HDDEDATA)
Definition: ddemisc.c:1461
#define APPCMD_CLIENTONLY
Definition: ddeml.h:122
UINT WINAPI DdeInitializeA(LPDWORD, PFNCALLBACK, DWORD, DWORD)
Definition: ddemisc.c:1075
#define ERROR_SUCCESS
Definition: deptool.c:10
#define TRUE
Definition: types.h:120
unsigned int idx
Definition: utils.c:41
LSTATUS WINAPI RegQueryValueW(HKEY hkey, LPCWSTR name, LPWSTR data, LPLONG count)
Definition: reg.c:4241
#define wcschr
Definition: compat.h:17
#define CP_ACP
Definition: compat.h:109
#define SetLastError(x)
Definition: compat.h:752
#define MAX_PATH
Definition: compat.h:34
#define WideCharToMultiByte
Definition: compat.h:111
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
DWORD WINAPI SearchPathW(IN LPCWSTR lpPath OPTIONAL, IN LPCWSTR lpFileName, IN LPCWSTR lpExtension OPTIONAL, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart OPTIONAL)
Definition: path.c:1298
#define assert(x)
Definition: debug.h:53
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint start
Definition: gl.h:1545
GLuint res
Definition: glext.h:9613
GLfloat GLfloat p
Definition: glext.h:8902
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define debugstr_w
Definition: kernel32.h:32
#define error(str)
Definition: mkdosfs.c:1605
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static PVOID ptr
Definition: dispmode.c:27
static TfClientId tid
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
static const char topic[]
Definition: propsys.c:45
#define strchrW(s, c)
Definition: unicode.h:40
#define strlenW(s)
Definition: unicode.h:34
#define strrchrW(s, c)
Definition: unicode.h:41
#define strcpyW(d, s)
Definition: unicode.h:35
DWORD WINAPI GetVersion()
Definition: redirtest.c:5
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define SE_ERR_NOASSOC
Definition: shellapi.h:136
static DWORD ddeInst
Definition: shlexec.c:147
static HSZ hszTopic
Definition: shlexec.c:148
static HDDEDATA CALLBACK dde_cb(UINT uType, UINT uFmt, HCONV hConv, HSZ hsz1, HSZ hsz2, HDDEDATA hData, ULONG_PTR dwData1, ULONG_PTR dwData2)
Definition: shlexec.cpp:983
static BOOL SHELL_ArgifyW(WCHAR *out, DWORD len, const WCHAR *fmt, const WCHAR *lpFile, LPITEMIDLIST pidl, LPCWSTR args, DWORD *out_len, const WCHAR *lpDir)
Definition: shlexec.cpp:201
Definition: copy.c:22
unsigned char * LPBYTE
Definition: typedefs.h:53
int ret
#define ERROR_DDE_FAIL
Definition: winerror.h:678
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185

Referenced by execute_from_key().

◆ do_error_dialog()

static void do_error_dialog ( UINT_PTR  retval,
HWND  hwnd,
WCHAR filename 
)
static

Definition at line 1924 of file shlexec.cpp.

1925{
1926 WCHAR msg[2048];
1927 DWORD_PTR msgArguments[3] = { (DWORD_PTR)filename, 0, 0 };
1929
1931 if (retval == SE_ERR_NOASSOC)
1933 else
1935 NULL,
1936 error_code,
1938 msg,
1939 ARRAY_SIZE(msg),
1940 (va_list*)msgArguments);
1941
1943}
#define shell32_hInstance
char * va_list
Definition: acmsvcex.h:78
#define msg(x)
Definition: auth_time.c:54
DWORD WINAPI FormatMessageW(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPWSTR lpBuffer, DWORD nSize, __ms_va_list *args)
Definition: format_msg.c:583
const char * filename
Definition: ioapi.h:137
#define IDS_SHLEXEC_NOASSOC
Definition: shresdef.h:187
#define LANG_USER_DEFAULT
Definition: tnerror.cpp:50
#define DWORD_PTR
Definition: treelist.c:76
uint32_t DWORD_PTR
Definition: typedefs.h:65
int retval
Definition: wcstombs.cpp:91
static int error_code[8]
Definition: odbccp32.c:61
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define FORMAT_MESSAGE_FROM_SYSTEM
Definition: winbase.h:450
#define FORMAT_MESSAGE_ARGUMENT_ARRAY
Definition: winbase.h:451
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
int WINAPI MessageBoxW(_In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType)
#define MB_ICONERROR
Definition: winuser.h:798

Referenced by SHELL_execute().

◆ execute_from_key()

static UINT_PTR execute_from_key ( LPCWSTR  key,
LPCWSTR  lpFile,
WCHAR env,
LPCWSTR  szCommandline,
LPCWSTR  executable_name,
SHELL_ExecuteW32  execfunc,
LPSHELLEXECUTEINFOW  psei,
LPSHELLEXECUTEINFOW  psei_out 
)
static

Definition at line 1210 of file shlexec.cpp.

1214{
1215 WCHAR cmd[256], param[1024], ddeexec[256];
1216 DWORD cmdlen = sizeof(cmd), ddeexeclen = sizeof(ddeexec);
1218 DWORD resultLen;
1219 LPWSTR tmp;
1220
1221 TRACE("%s %s %s %s %s\n", debugstr_w(key), debugstr_w(lpFile), debugstr_w(env),
1222 debugstr_w(szCommandline), debugstr_w(executable_name));
1223
1224 cmd[0] = '\0';
1225 param[0] = '\0';
1226
1227 /* Get the application from the registry */
1229 {
1230 TRACE("got cmd: %s\n", debugstr_w(cmd));
1231
1232 /* Is there a replace() function anywhere? */
1233 cmdlen /= sizeof(WCHAR);
1234 if (cmdlen >= ARRAY_SIZE(cmd))
1235 cmdlen = ARRAY_SIZE(cmd) - 1;
1236 cmd[cmdlen] = '\0';
1237 SHELL_ArgifyW(param, ARRAY_SIZE(param), cmd, lpFile, (LPITEMIDLIST)psei->lpIDList, szCommandline, &resultLen,
1238 (psei->lpDirectory && *psei->lpDirectory) ? psei->lpDirectory : NULL);
1239 if (resultLen > ARRAY_SIZE(param))
1240 ERR("Argify buffer not large enough, truncating\n");
1241 }
1242
1243 /* Get the parameters needed by the application
1244 from the associated ddeexec key */
1245 tmp = const_cast<LPWSTR>(strstrW(key, L"command"));
1246 assert(tmp);
1247 wcscpy(tmp, L"ddeexec");
1248
1249 if (RegQueryValueW(HKEY_CLASSES_ROOT, key, ddeexec, (LONG *)&ddeexeclen) == ERROR_SUCCESS)
1250 {
1251 TRACE("Got ddeexec %s => %s\n", debugstr_w(key), debugstr_w(ddeexec));
1252 if (!param[0]) strcpyW(param, executable_name);
1253 retval = dde_connect(key, param, ddeexec, lpFile, env, szCommandline, (LPITEMIDLIST)psei->lpIDList, execfunc, psei, psei_out);
1254 }
1255 else if (param[0])
1256 {
1257 TRACE("executing: %s\n", debugstr_w(param));
1258 retval = execfunc(param, env, FALSE, psei, psei_out);
1259 }
1260 else
1261 WARN("Nothing appropriate found for %s\n", debugstr_w(key));
1262
1263 return retval;
1264}
#define FALSE
Definition: types.h:117
GLfloat param
Definition: glext.h:5796
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
#define strstrW(d, s)
Definition: unicode.h:38
static unsigned dde_connect(const WCHAR *key, const WCHAR *start, WCHAR *ddeexec, const WCHAR *lpFile, WCHAR *env, LPCWSTR szCommandline, LPITEMIDLIST pidl, SHELL_ExecuteW32 execfunc, const SHELLEXECUTEINFOW *psei, LPSHELLEXECUTEINFOW psei_out)
Definition: shlexec.cpp:1001
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
LPCWSTR lpDirectory
Definition: shellapi.h:341
Definition: ftp_var.h:139

Referenced by SHELL_execute_url(), and SHELL_quote_and_execute().

◆ expand_environment()

static WCHAR * expand_environment ( const WCHAR str)
static

Definition at line 1945 of file shlexec.cpp.

1946{
1948 DWORD len;
1949
1951 if (!len) return NULL;
1952
1953 if (!buf.Allocate(len))
1954 return NULL;
1955
1957 if (!len)
1958 return NULL;
1959
1960 return buf.Detach();
1961}
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:519
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLsizei len
Definition: glext.h:6722
const WCHAR * str

Referenced by SHELL_execute().

◆ FindExecutableA()

HINSTANCE WINAPI FindExecutableA ( LPCSTR  lpFile,
LPCSTR  lpDirectory,
LPSTR  lpResult 
)

Definition at line 1269 of file shlexec.cpp.

1270{
1272 WCHAR *wFile = NULL, *wDirectory = NULL;
1273 WCHAR wResult[MAX_PATH];
1274
1275 if (lpFile) __SHCloneStrAtoW(&wFile, lpFile);
1276 if (lpDirectory) __SHCloneStrAtoW(&wDirectory, lpDirectory);
1277
1278 retval = FindExecutableW(wFile, wDirectory, wResult);
1279 WideCharToMultiByte(CP_ACP, 0, wResult, -1, lpResult, MAX_PATH, NULL, NULL);
1280 SHFree(wFile);
1281 SHFree(wDirectory);
1282
1283 TRACE("returning %s\n", lpResult);
1284 return retval;
1285}
void WINAPI SHFree(LPVOID pv)
Definition: shellole.c:326
static __inline LPWSTR __SHCloneStrAtoW(WCHAR **target, const char *source)
Definition: shell32_main.h:185
_In_opt_ LPCSTR lpDirectory
Definition: shellapi.h:497
HINSTANCE WINAPI FindExecutableW(LPCWSTR lpFile, LPCWSTR lpDirectory, LPWSTR lpResult)
Definition: shlexec.cpp:1312

Referenced by DoTestEntry(), test_fileurls(), and test_find_executable().

◆ FindExecutableW()

HINSTANCE WINAPI FindExecutableW ( LPCWSTR  lpFile,
LPCWSTR  lpDirectory,
LPWSTR  lpResult 
)

Definition at line 1312 of file shlexec.cpp.

1313{
1315 WCHAR old_dir[MAX_PATH], res[MAX_PATH];
1316 DWORD cch = _countof(res);
1317 LPCWSTR dirs[2];
1318
1319 TRACE("File %s, Dir %s\n", debugstr_w(lpFile), debugstr_w(lpDirectory));
1320
1321 *lpResult = UNICODE_NULL;
1322
1323 GetCurrentDirectoryW(_countof(old_dir), old_dir);
1324
1325 if (lpDirectory && *lpDirectory)
1326 {
1328 dirs[0] = lpDirectory;
1329 }
1330 else
1331 {
1332 dirs[0] = old_dir;
1333 }
1334 dirs[1] = NULL;
1335
1336 if (!GetShortPathNameW(lpFile, res, _countof(res)))
1337 StringCchCopyW(res, _countof(res), lpFile);
1338
1340 {
1341 // NOTE: The last parameter of this AssocQueryStringW call is "strange" in Windows.
1342 if (PathIsExeW(res) ||
1344 {
1345 StringCchCopyW(lpResult, MAX_PATH, res);
1346 retval = 42;
1347 }
1348 else
1349 {
1351 }
1352 }
1353 else
1354 {
1356 }
1357
1358 TRACE("returning %s\n", debugstr_w(lpResult));
1359 SetCurrentDirectoryW(old_dir);
1360 return (HINSTANCE)retval;
1361}
#define PRF_TRYPROGRAMEXTENSIONS
Definition: PathResolve.cpp:40
#define PRF_FIRSTDIRDEF
Definition: PathResolve.cpp:41
#define GetCurrentDirectoryW(x, y)
Definition: compat.h:756
BOOL WINAPI SetCurrentDirectoryW(IN LPCWSTR lpPathName)
Definition: path.c:2249
DWORD WINAPI GetShortPathNameW(IN LPCWSTR lpszLongPath, OUT LPWSTR lpszShortPath, IN DWORD cchBuffer)
Definition: path.c:1833
BOOL WINAPI PathResolveW(_Inout_ LPWSTR path, _Inout_opt_ LPCWSTR *dirs, _In_ DWORD flags)
Definition: shellpath.c:1032
HRESULT WINAPI AssocQueryStringW(ASSOCF cfFlags, ASSOCSTR str, LPCWSTR pszAssoc, LPCWSTR pszExtra, LPWSTR pszOut, DWORD *pcchOut)
Definition: assoc.c:436
#define SUCCEEDED(hr)
Definition: intsafe.h:50
static DWORD DWORD void LPSTR DWORD cch
Definition: str.c:202
#define UNICODE_NULL
#define SE_ERR_FNF
Definition: shellapi.h:126
EXTERN_C BOOL PathIsExeW(LPCWSTR lpszPath)
Definition: shellpath.c:539
@ ASSOCSTR_EXECUTABLE
Definition: shlwapi.h:613
@ ASSOCF_NONE
Definition: shlwapi.h:590
#define _countof(array)
Definition: sndvol32.h:70
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149

Referenced by ExtractAssociatedIconW(), FindExecutableA(), CShellLink::OnCommand(), and TEST_Start().

◆ OpenAs_RunDLLA()

EXTERN_C void WINAPI OpenAs_RunDLLA ( HWND  hwnd,
HINSTANCE  hinst,
LPCSTR  cmdline,
int  cmdshow 
)

Definition at line 2612 of file shlexec.cpp.

2613{
2614 LPWSTR pszCmdLineW = NULL;
2615 TRACE("%p, %p, %s, %d\n", hwnd, hinst, debugstr_a(cmdline), cmdshow);
2616
2617 if (cmdline)
2618 __SHCloneStrAtoW(&pszCmdLineW, cmdline);
2619 OpenAs_RunDLLW(hwnd, hinst, pszCmdLineW, cmdshow);
2620 SHFree(pszCmdLineW);
2621}
#define debugstr_a
Definition: kernel32.h:31
static HINSTANCE hinst
Definition: edit.c:551
EXTERN_C void WINAPI OpenAs_RunDLLW(HWND hwnd, HINSTANCE hinst, LPCWSTR cmdline, int cmdshow)
Definition: shlexec.cpp:2595
TCHAR * cmdline
Definition: stretchblt.cpp:32

◆ OpenAs_RunDLLW()

EXTERN_C void WINAPI OpenAs_RunDLLW ( HWND  hwnd,
HINSTANCE  hinst,
LPCWSTR  cmdline,
int  cmdshow 
)

Definition at line 2595 of file shlexec.cpp.

2596{
2598 TRACE("%p, %p, %s, %d\n", hwnd, hinst, debugstr_w(cmdline), cmdshow);
2599
2600 ZeroMemory(&info, sizeof(info));
2601 info.pcszFile = cmdline;
2602 info.pcszClass = NULL;
2604
2606}
HRESULT WINAPI SHOpenWithDialog(HWND hwndParent, const OPENASINFO *poainfo)
@ OAIF_EXEC
Definition: shlobj.h:2690
@ OAIF_REGISTER_EXT
Definition: shlobj.h:2689
@ OAIF_ALLOW_REGISTRATION
Definition: shlobj.h:2688
#define ZeroMemory
Definition: winbase.h:1744

Referenced by OpenAs_RunDLLA().

◆ ParseNoTildeEffect()

static void ParseNoTildeEffect ( PWSTR res,
LPCWSTR args,
DWORD len,
DWORD used,
int  argNum 
)
static

Definition at line 52 of file shlexec.cpp.

53{
54 bool firstCharQuote = false;
55 bool quotes_opened = false;
56 bool backslash_encountered = false;
57
58 for (int curArg = 0; curArg <= argNum && *args; ++curArg)
59 {
60 firstCharQuote = false;
61 if (*args == '"')
62 {
63 quotes_opened = true;
64 firstCharQuote = true;
65 args++;
66 }
67
68 while(*args)
69 {
70 if (*args == '\\')
71 {
72 // if we found a backslash then flip the variable
73 backslash_encountered = !backslash_encountered;
74 }
75 else if (*args == '"')
76 {
77 if (quotes_opened)
78 {
79 if (*(args + 1) != '"')
80 {
81 quotes_opened = false;
82 args++;
83 break;
84 }
85 else
86 {
87 args++;
88 }
89 }
90 else
91 {
92 quotes_opened = true;
93 }
94
95 backslash_encountered = false;
96 }
97 else
98 {
99 backslash_encountered = false;
100 if (*args == ' ' && !firstCharQuote)
101 break;
102 }
103
104 if (curArg == argNum)
105 {
106 used++;
107 if (used < len)
108 *res++ = *args;
109 }
110
111 args++;
112 }
113
114 while(*args == ' ')
115 ++args;
116 }
117}
static int used
Definition: adh-main.c:39
Definition: match.c:390

Referenced by SHELL_ArgifyW().

◆ ParseTildeEffect()

static void ParseTildeEffect ( PWSTR res,
LPCWSTR args,
DWORD len,
DWORD used,
int  argNum 
)
static

Definition at line 119 of file shlexec.cpp.

120{
121 bool quotes_opened = false;
122 bool backslash_encountered = false;
123
124 for (int curArg = 0; curArg <= argNum && *args; ++curArg)
125 {
126 while(*args)
127 {
128 if (*args == '\\')
129 {
130 // if we found a backslash then flip the variable
131 backslash_encountered = !backslash_encountered;
132 }
133 else if (*args == '"')
134 {
135 if (quotes_opened)
136 {
137 if (*(args + 1) != '"')
138 {
139 quotes_opened = false;
140 }
141 else
142 {
143 args++;
144 }
145 }
146 else
147 {
148 quotes_opened = true;
149 }
150
151 backslash_encountered = false;
152 }
153 else
154 {
155 backslash_encountered = false;
156 if (*args == ' ' && !quotes_opened && curArg != argNum)
157 break;
158 }
159
160 if (curArg == argNum)
161 {
162 used++;
163 if (used < len)
164 *res++ = *args;
165 }
166
167 args++;
168 }
169 }
170}

Referenced by SHELL_ArgifyW().

◆ PathIsExeW()

EXTERN_C BOOL PathIsExeW ( LPCWSTR  lpszPath)

Definition at line 539 of file shellpath.c.

540{
541 LPCWSTR lpszExtension = PathGetExtensionW(lpszPath);
542 int i;
543 static const WCHAR lpszExtensions[][4] =
544 {L"exe", L"com", L"pif", L"cmd", L"bat", L"scf", L"scr", L"" };
545
546 TRACE("path=%s\n",debugstr_w(lpszPath));
547
548 for(i=0; lpszExtensions[i][0]; i++)
549 if (!wcsicmp(lpszExtension,lpszExtensions[i])) return TRUE;
550
551 return FALSE;
552}
#define wcsicmp
Definition: compat.h:15
static LPWSTR PathGetExtensionW(LPCWSTR lpszPath)
Definition: shellpath.c:434
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248

Referenced by FindExecutableW(), PathIsExeAW(), and SHELL_execute().

◆ PathProcessCommandW()

EXTERN_C LONG PathProcessCommandW ( _In_ PCWSTR  pszSrc,
_Out_writes_opt_(dwBuffSize) PWSTR  pszDest,
_In_ INT  cchDest,
_In_ DWORD  dwFlags 
)

Definition at line 2996 of file shlexec.cpp.

3001{
3002 TRACE("%s, %p, %d, 0x%X\n", wine_dbgstr_w(pszSrc), pszDest, cchDest, dwFlags);
3003
3004 if (!pszSrc)
3005 return -1;
3006
3008 PCWSTR pchArg = NULL;
3009
3010 if (*pszSrc == L'"') // Quoted?
3011 {
3012 ++pszSrc;
3013
3014 PCWSTR pch = wcschr(pszSrc, L'"');
3015 if (pch)
3016 {
3017 szPath.SetString(pszSrc, pch - pszSrc);
3018 pchArg = pch + 1;
3019 }
3020 else
3021 {
3022 szPath = pszSrc;
3023 }
3024
3026 {
3028 szPath.ReleaseBuffer();
3029 if (!ret)
3030 return -1;
3031 }
3032 }
3033 else // Not quoted?
3034 {
3035 BOOL resolved = FALSE;
3036 BOOL resolveRelative = PathIsRelativeW(pszSrc) || (dwFlags & PPCF_FORCEQUALIFY);
3037 INT cchPath = 0;
3038
3039 for (INT ich = 0; ; ++ich)
3040 {
3041 szPath += pszSrc[ich];
3042
3043 if (pszSrc[ich] && pszSrc[ich] != L' ')
3044 continue;
3045
3046 szPath = szPath.Left(ich);
3047
3048 if (resolveRelative &&
3050 {
3051 szPath.ReleaseBuffer();
3052 szPath += pszSrc[ich];
3053 }
3054 else
3055 {
3056 szPath.ReleaseBuffer();
3057
3059 if (attrs != INVALID_FILE_ATTRIBUTES &&
3061 {
3062 resolved = TRUE;
3063 pchArg = pszSrc + ich;
3064
3066 break;
3067
3068 cchPath = ich;
3069 break;
3070 }
3071 else if (!resolveRelative)
3072 {
3073 szPath += pszSrc[ich];
3074 }
3075 }
3076
3077 if (!szPath[ich])
3078 {
3079 szPath.ReleaseBuffer(); // Remove excessive '\0'
3080 break;
3081 }
3082 }
3083
3084 if (!resolved)
3085 return -1;
3086
3087 if (cchPath && (dwFlags & PPCF_LONGESTPOSSIBLE))
3088 {
3089 szPath = szPath.Left(cchPath);
3090 pchArg = pszSrc + cchPath;
3091 }
3092 }
3093
3094 BOOL needsQuoting = (dwFlags & PPCF_ADDQUOTES) && wcschr(szPath, L' ');
3095 CStringW result = needsQuoting ? (L"\"" + szPath + L"\"") : szPath;
3096
3097 if (pchArg && (dwFlags & PPCF_ADDARGUMENTS))
3098 result += pchArg;
3099
3100 LONG requiredSize = result.GetLength() + 1;
3101 if (!pszDest)
3102 return requiredSize;
3103
3104 if (requiredSize > cchDest || StringCchCopyW(pszDest, cchDest, result) != S_OK)
3105 return -1;
3106
3107 return requiredSize;
3108}
static _In_ LPCWSTR _In_ DWORD _In_ int _In_ int cchDest
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:652
BOOL WINAPI PathIsRelativeW(LPCWSTR lpszPath)
Definition: path.c:1585
GLuint64EXT * result
Definition: glext.h:11304
#define S_OK
Definition: intsafe.h:52
#define wine_dbgstr_w
Definition: kernel32.h:34
#define pch(ap)
Definition: match.c:418
LPCWSTR szPath
Definition: env.c:37
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define PPCF_FORCEQUALIFY
Definition: shlobj.h:2429
#define PPCF_LONGESTPOSSIBLE
Definition: shlobj.h:2430
#define PPCF_ADDQUOTES
Definition: shlobj.h:2424
#define PPCF_ADDARGUMENTS
Definition: shlobj.h:2426
#define PPCF_NODIRECTORIES
Definition: shlobj.h:2427
const uint16_t * PCWSTR
Definition: typedefs.h:57
int32_t INT
Definition: typedefs.h:58
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176

Referenced by ShellExec_RunDLL_Helper().

◆ RealShellExecuteA()

EXTERN_C HINSTANCE WINAPI RealShellExecuteA ( _In_opt_ HWND  hwnd,
_In_opt_ LPCSTR  lpOperation,
_In_opt_ LPCSTR  lpFile,
_In_opt_ LPCSTR  lpParameters,
_In_opt_ LPCSTR  lpDirectory,
_In_opt_ LPSTR  lpReturn,
_In_opt_ LPCSTR  lpTitle,
_In_opt_ LPVOID  lpReserved,
_In_ INT  nCmdShow,
_Out_opt_ PHANDLE  lphProcess 
)

Definition at line 2934 of file shlexec.cpp.

2945{
2947 lpOperation,
2948 lpFile,
2949 lpParameters,
2951 lpReturn,
2952 lpTitle,
2953 lpReserved,
2954 nCmdShow,
2955 lphProcess,
2956 0);
2957}
static DWORD const LPVOID const lpReserved
TCHAR lpTitle[80]
Definition: ctm.c:69
EXTERN_C HINSTANCE WINAPI RealShellExecuteExA(_In_opt_ HWND hwnd, _In_opt_ LPCSTR lpOperation, _In_opt_ LPCSTR lpFile, _In_opt_ LPCSTR lpParameters, _In_opt_ LPCSTR lpDirectory, _In_opt_ LPSTR lpReturn, _In_opt_ LPCSTR lpTitle, _In_opt_ LPVOID lpReserved, _In_ INT nCmdShow, _Out_opt_ PHANDLE lphProcess, _In_ DWORD dwFlags)
Definition: shlexec.cpp:2800

◆ RealShellExecuteExA()

EXTERN_C HINSTANCE WINAPI RealShellExecuteExA ( _In_opt_ HWND  hwnd,
_In_opt_ LPCSTR  lpOperation,
_In_opt_ LPCSTR  lpFile,
_In_opt_ LPCSTR  lpParameters,
_In_opt_ LPCSTR  lpDirectory,
_In_opt_ LPSTR  lpReturn,
_In_opt_ LPCSTR  lpTitle,
_In_opt_ LPVOID  lpReserved,
_In_ INT  nCmdShow,
_Out_opt_ PHANDLE  lphProcess,
_In_ DWORD  dwFlags 
)

Definition at line 2800 of file shlexec.cpp.

2812{
2813 SHELLEXECUTEINFOA ExecInfo;
2814
2815 TRACE("(%p, %s, %s, %s, %s, %p, %s, %p, %u, %p, %lu)\n",
2816 hwnd, debugstr_a(lpOperation), debugstr_a(lpFile), debugstr_a(lpParameters),
2818 lpReserved, nCmdShow, lphProcess, dwFlags);
2819
2820 ZeroMemory(&ExecInfo, sizeof(ExecInfo));
2821 ExecInfo.cbSize = sizeof(ExecInfo);
2823 ExecInfo.hwnd = hwnd;
2824 ExecInfo.lpVerb = lpOperation;
2825 ExecInfo.lpFile = lpFile;
2826 ExecInfo.lpParameters = lpParameters;
2827 ExecInfo.lpDirectory = lpDirectory;
2828 ExecInfo.nShow = (WORD)nCmdShow;
2829
2830 if (lpReserved)
2831 {
2832 ExecInfo.fMask |= SEE_MASK_USE_RESERVED;
2833 ExecInfo.hInstApp = (HINSTANCE)lpReserved;
2834 }
2835
2836 if (lpTitle)
2837 {
2838 ExecInfo.fMask |= SEE_MASK_HASTITLE;
2839 ExecInfo.lpClass = lpTitle;
2840 }
2841
2842 if (dwFlags & 1)
2843 ExecInfo.fMask |= SEE_MASK_FLAG_SEPVDM;
2844
2845 if (dwFlags & 2)
2846 ExecInfo.fMask |= SEE_MASK_NO_CONSOLE;
2847
2848 if (lphProcess == NULL)
2849 {
2850 ShellExecuteExA(&ExecInfo);
2851 }
2852 else
2853 {
2854 ExecInfo.fMask |= SEE_MASK_NOCLOSEPROCESS;
2855 ShellExecuteExA(&ExecInfo);
2856 *lphProcess = ExecInfo.hProcess;
2857 }
2858
2859 return ExecInfo.hInstApp;
2860}
unsigned short WORD
Definition: ntddk_ex.h:93
#define SEE_MASK_USE_RESERVED
Definition: shellapi.h:51
#define SEE_MASK_FLAG_SEPVDM
Definition: shellapi.h:50
#define SEE_MASK_NOCLOSEPROCESS
Definition: shellapi.h:31
#define SEE_MASK_HASTITLE
Definition: shellapi.h:52
#define SEE_MASK_UNKNOWN_0x1000
Definition: shellapi.h:48
#define SEE_MASK_FLAG_NO_UI
Definition: shellapi.h:36
#define SEE_MASK_NO_CONSOLE
Definition: shellapi.h:38
BOOL WINAPI DECLSPEC_HOTPATCH ShellExecuteExA(LPSHELLEXECUTEINFOA sei)
Definition: shlexec.cpp:2416
LPCSTR lpParameters
Definition: shellapi.h:317
HINSTANCE hInstApp
Definition: shellapi.h:320
LPCSTR lpDirectory
Definition: shellapi.h:318
HANDLE HINSTANCE
Definition: typedefs.h:77

Referenced by RealShellExecuteA().

◆ RealShellExecuteExW()

EXTERN_C HINSTANCE WINAPI RealShellExecuteExW ( _In_opt_ HWND  hwnd,
_In_opt_ LPCWSTR  lpOperation,
_In_opt_ LPCWSTR  lpFile,
_In_opt_ LPCWSTR  lpParameters,
_In_opt_ LPCWSTR  lpDirectory,
_In_opt_ LPWSTR  lpReturn,
_In_opt_ LPCWSTR  lpTitle,
_In_opt_ LPVOID  lpReserved,
_In_ INT  nCmdShow,
_Out_opt_ PHANDLE  lphProcess,
_In_ DWORD  dwFlags 
)

Definition at line 2867 of file shlexec.cpp.

2879{
2880 SHELLEXECUTEINFOW ExecInfo;
2881
2882 TRACE("(%p, %s, %s, %s, %s, %p, %s, %p, %u, %p, %lu)\n",
2883 hwnd, debugstr_w(lpOperation), debugstr_w(lpFile), debugstr_w(lpParameters),
2885 lpReserved, nCmdShow, lphProcess, dwFlags);
2886
2887 ZeroMemory(&ExecInfo, sizeof(ExecInfo));
2888 ExecInfo.cbSize = sizeof(ExecInfo);
2890 ExecInfo.hwnd = hwnd;
2891 ExecInfo.lpVerb = lpOperation;
2892 ExecInfo.lpFile = lpFile;
2893 ExecInfo.lpParameters = lpParameters;
2894 ExecInfo.lpDirectory = lpDirectory;
2895 ExecInfo.nShow = (WORD)nCmdShow;
2896
2897 if (lpReserved)
2898 {
2899 ExecInfo.fMask |= SEE_MASK_USE_RESERVED;
2900 ExecInfo.hInstApp = (HINSTANCE)lpReserved;
2901 }
2902
2903 if (lpTitle)
2904 {
2905 ExecInfo.fMask |= SEE_MASK_HASTITLE;
2906 ExecInfo.lpClass = lpTitle;
2907 }
2908
2909 if (dwFlags & 1)
2910 ExecInfo.fMask |= SEE_MASK_FLAG_SEPVDM;
2911
2912 if (dwFlags & 2)
2913 ExecInfo.fMask |= SEE_MASK_NO_CONSOLE;
2914
2915 if (lphProcess == NULL)
2916 {
2917 ShellExecuteExW(&ExecInfo);
2918 }
2919 else
2920 {
2921 ExecInfo.fMask |= SEE_MASK_NOCLOSEPROCESS;
2922 ShellExecuteExW(&ExecInfo);
2923 *lphProcess = ExecInfo.hProcess;
2924 }
2925
2926 return ExecInfo.hInstApp;
2927}
BOOL WINAPI DECLSPEC_HOTPATCH ShellExecuteExW(LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:2474
HINSTANCE hInstApp
Definition: shellapi.h:343
LPCWSTR lpParameters
Definition: shellapi.h:340

Referenced by RealShellExecuteW().

◆ RealShellExecuteW()

EXTERN_C HINSTANCE WINAPI RealShellExecuteW ( _In_opt_ HWND  hwnd,
_In_opt_ LPCWSTR  lpOperation,
_In_opt_ LPCWSTR  lpFile,
_In_opt_ LPCWSTR  lpParameters,
_In_opt_ LPCWSTR  lpDirectory,
_In_opt_ LPWSTR  lpReturn,
_In_opt_ LPCWSTR  lpTitle,
_In_opt_ LPVOID  lpReserved,
_In_ INT  nCmdShow,
_Out_opt_ PHANDLE  lphProcess 
)

Definition at line 2964 of file shlexec.cpp.

2975{
2977 lpOperation,
2978 lpFile,
2979 lpParameters,
2981 lpReturn,
2982 lpTitle,
2983 lpReserved,
2984 nCmdShow,
2985 lphProcess,
2986 0);
2987}
EXTERN_C HINSTANCE WINAPI RealShellExecuteExW(_In_opt_ HWND hwnd, _In_opt_ LPCWSTR lpOperation, _In_opt_ LPCWSTR lpFile, _In_opt_ LPCWSTR lpParameters, _In_opt_ LPCWSTR lpDirectory, _In_opt_ LPWSTR lpReturn, _In_opt_ LPCWSTR lpTitle, _In_opt_ LPVOID lpReserved, _In_ INT nCmdShow, _Out_opt_ PHANDLE lphProcess, _In_ DWORD dwFlags)
Definition: shlexec.cpp:2867

◆ SHELL_ArgifyW()

static BOOL SHELL_ArgifyW ( WCHAR out,
DWORD  len,
const WCHAR fmt,
const WCHAR lpFile,
LPITEMIDLIST  pidl,
LPCWSTR  args,
DWORD out_len,
const WCHAR lpDir 
)
static

Definition at line 201 of file shlexec.cpp.

202{
203 BOOL done = FALSE;
204 BOOL found_p1 = FALSE;
205 PWSTR res = out;
206 DWORD used = 0;
207 bool tildeEffect = false;
208
209 TRACE("Before parsing: %p, %d, %s, %s, %p, %p\n", out, len, debugstr_w(fmt),
210 debugstr_w(lpFile), pidl, args);
211
212 while (*fmt)
213 {
214 if (*fmt == '%')
215 {
216 switch (*++fmt)
217 {
218 case '\0':
219 case '%':
220 {
221 used++;
222 if (used < len)
223 *res++ = '%';
224 };
225 break;
226
227 case '*':
228 {
229 if (args)
230 {
231 if (*fmt == '*')
232 {
233 used++;
234 while(*args)
235 {
236 used++;
237 if (used < len)
238 *res++ = *args++;
239 else
240 args++;
241 }
242 used++;
243 break;
244 }
245 }
246 };
247 break;
248
249 case '~':
250
251 case '2':
252 case '3':
253 case '4':
254 case '5':
255 case '6':
256 case '7':
257 case '8':
258 case '9':
259 //case '0':
260 {
261 if (*fmt == '~')
262 {
263 fmt++;
264 tildeEffect = true;
265 }
266
267 if (args)
268 {
269 if (tildeEffect)
270 {
271 ParseTildeEffect(res, args, len, used, *fmt - '2');
272 tildeEffect = false;
273 }
274 else
275 {
277 }
278 }
279 };
280 break;
281
282 case '1':
283 if ((!done || (*fmt == '1')) && lpFile)
284 {
285 SIZE_T filelen = wcslen(lpFile);
286 used += filelen;
287 if (used < len)
288 {
289 wcscpy(res, lpFile);
290 res += filelen;
291 }
292 }
293 found_p1 = TRUE;
294 break;
295
296 /*
297 * IE uses this a lot for activating things such as windows media
298 * player. This is not verified to be fully correct but it appears
299 * to work just fine.
300 */
301 case 'l':
302 case 'L':
303 if (lpFile)
304 {
305 used += wcslen(lpFile);
306 if (used < len)
307 {
308 wcscpy(res, lpFile);
309 res += wcslen(lpFile);
310 }
311 }
312 found_p1 = TRUE;
313 break;
314
315 case 'w':
316 case 'W':
317 if (lpDir)
318 {
319 used += wcslen(lpDir);
320 if (used < len)
321 {
322 wcscpy(res, lpDir);
323 res += wcslen(lpDir);
324 }
325 }
326 break;
327
328 case 'v':
329 case 'V':
330 if (lpFile)
331 {
332 used += wcslen(lpFile);
333 if (used < len)
334 {
335 wcscpy(res, lpFile);
336 res += wcslen(lpFile);
337 }
338 found_p1 = TRUE;
339 }
340 else if (lpDir)
341 {
342 used += wcslen(lpDir);
343 if (used < len)
344 {
345 wcscpy(res, lpDir);
346 res += wcslen(lpDir);
347 }
348 }
349 break;
350
351 case 'i':
352 case 'I':
353 if (pidl)
354 {
355 DWORD chars = 0;
356 /* %p should not exceed 8, maybe 16 when looking forward to 64bit.
357 * allowing a buffer of 100 should more than exceed all needs */
358 WCHAR buf[100];
359 LPVOID pv;
360 HGLOBAL hmem = SHAllocShared(pidl, ILGetSize(pidl), 0);
361 pv = SHLockShared(hmem, 0);
362 chars = swprintf(buf, L":%p", pv);
363
364 if (chars >= ARRAY_SIZE(buf))
365 ERR("pidl format buffer too small!\n");
366
367 used += chars;
368
369 if (used < len)
370 {
371 wcscpy(res, buf);
372 res += chars;
373 }
374 SHUnlockShared(pv);
375 }
376 found_p1 = TRUE;
377 break;
378
379 default:
380 /*
381 * Check if this is an env-variable here...
382 */
383
384 /* Make sure that we have at least one more %.*/
385 if (strchrW(fmt, '%'))
386 {
387 WCHAR tmpBuffer[1024];
388 PWSTR tmpB = tmpBuffer;
389 WCHAR tmpEnvBuff[MAX_PATH];
390 DWORD envRet;
391
392 while (*fmt != '%')
393 *tmpB++ = *fmt++;
394 *tmpB++ = 0;
395
396 TRACE("Checking %s to be an env-var\n", debugstr_w(tmpBuffer));
397
398 envRet = GetEnvironmentVariableW(tmpBuffer, tmpEnvBuff, MAX_PATH);
399 if (envRet == 0 || envRet > MAX_PATH)
400 {
401 used += wcslen(tmpBuffer);
402 if (used < len)
403 {
404 wcscpy( res, tmpBuffer );
405 res += wcslen(tmpBuffer);
406 }
407 }
408 else
409 {
410 used += wcslen(tmpEnvBuff);
411 if (used < len)
412 {
413 wcscpy( res, tmpEnvBuff );
414 res += wcslen(tmpEnvBuff);
415 }
416 }
417 }
418 done = TRUE;
419 break;
420 }
421 /* Don't skip past terminator (catch a single '%' at the end) */
422 if (*fmt != '\0')
423 {
424 fmt++;
425 }
426 }
427 else
428 {
429 used ++;
430 if (used < len)
431 *res++ = *fmt++;
432 else
433 fmt++;
434 }
435 }
436
437 used++;
438 if (res - out < static_cast<int>(len))
439 *res = '\0';
440 else
441 out[len-1] = '\0';
442
443 TRACE("used %i of %i space\n", used, len);
444 if (out_len)
445 *out_len = used;
446
447 TRACE("After parsing: %p, %d, %s, %s, %p, %p\n", out, len, debugstr_w(fmt),
448 debugstr_w(lpFile), pidl, args);
449
450 return found_p1;
451}
#define GetEnvironmentVariableW(x, y, z)
Definition: compat.h:755
HANDLE WINAPI SHAllocShared(LPCVOID lpvData, DWORD dwSize, DWORD dwProcId)
Definition: ordinal.c:169
PVOID WINAPI SHLockShared(HANDLE hShared, DWORD dwProcId)
Definition: ordinal.c:259
BOOL WINAPI SHUnlockShared(LPVOID lpView)
Definition: ordinal.c:295
#define swprintf
Definition: precomp.h:40
#define ILGetSize
Definition: shellclasses.h:638
static void ParseNoTildeEffect(PWSTR &res, LPCWSTR &args, DWORD &len, DWORD &used, int argNum)
Definition: shlexec.cpp:52
static void ParseTildeEffect(PWSTR &res, LPCWSTR &args, DWORD &len, DWORD &used, int argNum)
Definition: shlexec.cpp:119
Definition: dsound.c:943
uint16_t * PWSTR
Definition: typedefs.h:56
ULONG_PTR SIZE_T
Definition: typedefs.h:80
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383

Referenced by dde_connect(), execute_from_key(), SHELL_execute_class(), SHELL_FindExecutable(), and SHELL_translate_idlist().

◆ SHELL_BuildEnvW()

static LPWSTR SHELL_BuildEnvW ( const WCHAR path)
static

Definition at line 579 of file shlexec.cpp.

580{
582 WCHAR *strings, *p, *p2;
583 int total = wcslen(path) + 1;
584 BOOL got_path = FALSE;
585
586 if (!(strings = GetEnvironmentStringsW())) return NULL;
587 p = strings;
588 while (*p)
589 {
590 int len = wcslen(p) + 1;
591 if (!_wcsnicmp( p, L"PATH=", 5 )) got_path = TRUE;
592 total += len;
593 p += len;
594 }
595 if (!got_path) total += 5; /* we need to create PATH */
596 total++; /* terminating null */
597
598 if (!new_env.Allocate(total))
599 {
601 return NULL;
602 }
603 p = strings;
604 p2 = new_env;
605 while (*p)
606 {
607 int len = wcslen(p) + 1;
608 memcpy(p2, p, len * sizeof(WCHAR));
609 if (!_wcsnicmp( p, L"PATH=", 5 ))
610 {
611 p2[len - 1] = ';';
612 wcscpy( p2 + len, path );
613 p2 += wcslen(path) + 1;
614 }
615 p += len;
616 p2 += len;
617 }
618 if (!got_path)
619 {
620 wcscpy(p2, L"PATH=");
621 wcscat(p2, path);
622 p2 += wcslen(p2) + 1;
623 }
624 *p2 = 0;
626 return new_env.Detach();
627}
T * Detach()
Definition: atlalloc.h:168
wcscat
BOOL WINAPI FreeEnvironmentStringsW(IN LPWSTR EnvironmentStrings)
Definition: environ.c:389
size_t total
GLsizei const GLchar *const * strings
Definition: glext.h:7622
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
LPWSTR WINAPI GetEnvironmentStringsW(void)
Definition: environ.c:344

Referenced by SHELL_TryAppPathW().

◆ SHELL_execute()

static BOOL SHELL_execute ( LPSHELLEXECUTEINFOW  sei,
SHELL_ExecuteW32  execfunc 
)
static

Definition at line 1966 of file shlexec.cpp.

1967{
1968 static const DWORD unsupportedFlags =
1970
1971 DWORD len;
1973 BOOL appKnownSingular = FALSE;
1974
1975 /* make a local copy of the LPSHELLEXECUTEINFO structure and work with this from now on */
1976 SHELLEXECUTEINFOW sei_tmp = *sei;
1977
1978 TRACE("mask=0x%08x hwnd=%p verb=%s file=%s parm=%s dir=%s show=0x%08x class=%s\n",
1979 sei_tmp.fMask, sei_tmp.hwnd, debugstr_w(sei_tmp.lpVerb),
1980 debugstr_w(sei_tmp.lpFile), debugstr_w(sei_tmp.lpParameters),
1981 debugstr_w(sei_tmp.lpDirectory), sei_tmp.nShow,
1982 ((sei_tmp.fMask & SEE_MASK_CLASSALL) == SEE_MASK_CLASSNAME) ?
1983 debugstr_w(sei_tmp.lpClass) : "not used");
1984
1985 sei->hProcess = NULL;
1986
1987 /* make copies of all path/command strings */
1988 CHeapPtr<WCHAR, CLocalAllocator> wszApplicationName;
1989 DWORD dwApplicationNameLen = MAX_PATH + 2;
1990 if (!sei_tmp.lpFile)
1991 {
1992 wszApplicationName.Allocate(dwApplicationNameLen);
1993 *wszApplicationName = '\0';
1994 }
1995 else if (*sei_tmp.lpFile == '\"' && sei_tmp.lpFile[(len = strlenW(sei_tmp.lpFile))-1] == '\"')
1996 {
1997 if(len-1 >= dwApplicationNameLen)
1998 dwApplicationNameLen = len;
1999
2000 wszApplicationName.Allocate(dwApplicationNameLen);
2001 memcpy(wszApplicationName, sei_tmp.lpFile + 1, len * sizeof(WCHAR));
2002
2003 if(len > 2)
2004 wszApplicationName[len-2] = '\0';
2005 appKnownSingular = TRUE;
2006
2007 TRACE("wszApplicationName=%s\n", debugstr_w(wszApplicationName));
2008 }
2009 else
2010 {
2011 DWORD l = strlenW(sei_tmp.lpFile) + 1;
2012 if(l > dwApplicationNameLen) dwApplicationNameLen = l + 1;
2013 wszApplicationName.Allocate(dwApplicationNameLen);
2014 memcpy(wszApplicationName, sei_tmp.lpFile, l * sizeof(WCHAR));
2015
2016 if (wszApplicationName[2] == 0 && wszApplicationName[1] == L':' &&
2017 ((L'A' <= wszApplicationName[0] && wszApplicationName[0] <= L'Z') ||
2018 (L'a' <= wszApplicationName[0] && wszApplicationName[0] <= L'z')))
2019 {
2020 // 'C:' --> 'C:\'
2021 PathAddBackslashW(wszApplicationName);
2022 }
2023 }
2024
2025 WCHAR parametersBuffer[1024];
2026 LPWSTR wszParameters = parametersBuffer;
2028 DWORD parametersLen = _countof(parametersBuffer);
2029
2030 if (sei_tmp.lpParameters)
2031 {
2032 len = lstrlenW(sei_tmp.lpParameters) + 1;
2033 if (len > parametersLen)
2034 {
2035 wszParamAlloc.Allocate(len);
2036 wszParameters = wszParamAlloc;
2037 parametersLen = len;
2038 }
2039 strcpyW(wszParameters, sei_tmp.lpParameters);
2040 }
2041 else
2042 *wszParameters = L'\0';
2043
2044 // Get the working directory
2045 WCHAR dirBuffer[MAX_PATH];
2046 LPWSTR wszDir = dirBuffer;
2047 wszDir[0] = UNICODE_NULL;
2049 if (sei_tmp.lpDirectory && *sei_tmp.lpDirectory)
2050 {
2051 if (sei_tmp.fMask & SEE_MASK_DOENVSUBST)
2052 {
2053 LPWSTR tmp = expand_environment(sei_tmp.lpDirectory);
2054 if (tmp)
2055 {
2056 wszDirAlloc.Attach(tmp);
2057 wszDir = wszDirAlloc;
2058 }
2059 }
2060 else
2061 {
2062 __SHCloneStrW(&wszDirAlloc, sei_tmp.lpDirectory);
2063 if (wszDirAlloc)
2064 wszDir = wszDirAlloc;
2065 }
2066 }
2067 if (!wszDir[0])
2068 {
2069 ::GetCurrentDirectoryW(_countof(dirBuffer), dirBuffer);
2070 wszDir = dirBuffer;
2071 }
2072 // NOTE: ShellExecute should accept the invalid working directory for historical reason.
2073 if (!PathIsDirectoryW(wszDir))
2074 {
2075 INT iDrive = PathGetDriveNumberW(wszDir);
2076 if (iDrive >= 0)
2077 {
2078 PathStripToRootW(wszDir);
2079 if (!PathIsDirectoryW(wszDir))
2080 {
2081 ::GetWindowsDirectoryW(dirBuffer, _countof(dirBuffer));
2082 wszDir = dirBuffer;
2083 }
2084 }
2085 }
2086
2087 /* adjust string pointers to point to the new buffers */
2088 sei_tmp.lpFile = wszApplicationName;
2089 sei_tmp.lpParameters = wszParameters;
2090 sei_tmp.lpDirectory = wszDir;
2091
2092 if (sei_tmp.fMask & unsupportedFlags)
2093 {
2094 FIXME("flags ignored: 0x%08x\n", sei_tmp.fMask & unsupportedFlags);
2095 }
2096
2097 /* process the IDList */
2098 if (sei_tmp.fMask & SEE_MASK_IDLIST &&
2100 {
2101 LPCITEMIDLIST pidl = (LPCITEMIDLIST)sei_tmp.lpIDList;
2102
2105 if (SUCCEEDED(hr))
2106 {
2107 hr = pSEH->Execute(&sei_tmp);
2108 if (hr == S_OK)
2109 return TRUE;
2110 }
2111
2112 hr = SHGetNameAndFlagsW(pidl, SHGDN_FORPARSING, wszApplicationName, dwApplicationNameLen, NULL);
2113 if (FAILED(hr))
2114 {
2115 if (dwApplicationNameLen)
2116 *wszApplicationName = UNICODE_NULL;
2117 if (!_ILIsDesktop(pidl))
2118 TRACE("Unable to get PIDL parsing path\n");
2119 }
2120 appKnownSingular = TRUE;
2121 TRACE("-- idlist=%p (%s)\n", sei_tmp.lpIDList, debugstr_w(wszApplicationName));
2122 }
2123
2124 if ((sei_tmp.fMask & SEE_MASK_DOENVSUBST) && !StrIsNullOrEmpty(sei_tmp.lpFile))
2125 {
2126 WCHAR *tmp = expand_environment(sei_tmp.lpFile);
2127 if (tmp)
2128 {
2129 wszApplicationName.Attach(tmp);
2130 sei_tmp.lpFile = wszApplicationName;
2131 }
2132 }
2133
2135 {
2137 if (SUCCEEDED(hr))
2138 {
2139 sei->hInstApp = (HINSTANCE)42;
2140 return TRUE;
2141 }
2142 }
2143
2145 {
2146 sei->hInstApp = (HINSTANCE) 33;
2147 return TRUE;
2148 }
2149
2150 if (sei_tmp.fMask & SEE_MASK_CLASSALL)
2151 {
2152 retval = SHELL_execute_class(wszApplicationName, &sei_tmp, sei, execfunc);
2153 if (retval <= 32 && !(sei_tmp.fMask & SEE_MASK_FLAG_NO_UI))
2154 {
2156
2157 //FIXME
2158 // need full path
2159
2160 Info.pcszFile = wszApplicationName;
2161 Info.pcszClass = NULL;
2162 Info.oaifInFlags = OAIF_ALLOW_REGISTRATION | OAIF_EXEC;
2163
2164 //if (SHOpenWithDialog(sei_tmp.hwnd, &Info) != S_OK)
2166 do_error_dialog(retval, sei_tmp.hwnd, wszApplicationName);
2167 }
2168 return retval > 32;
2169 }
2170
2171 if (!(sei_tmp.fMask & SEE_MASK_IDLIST) && // Not an ID List
2172 (StrCmpNIW(sei_tmp.lpFile, L"shell:", 6) == 0 ||
2173 StrCmpNW(sei_tmp.lpFile, L"::{", 3) == 0))
2174 {
2175 CComHeapPtr<ITEMIDLIST> pidlParsed;
2176 HRESULT hr = SHParseDisplayName(sei_tmp.lpFile, NULL, &pidlParsed, 0, NULL);
2177 if (SUCCEEDED(hr) && SHELL_InvokePidl(&sei_tmp, pidlParsed))
2178 {
2179 sei_tmp.hInstApp = (HINSTANCE)UlongToHandle(42);
2180 return TRUE;
2181 }
2182 }
2183
2184 /* Has the IDList not yet been translated? */
2185 if (sei_tmp.fMask & SEE_MASK_IDLIST)
2186 {
2187 appKnownSingular = SHELL_translate_idlist( &sei_tmp, wszParameters,
2188 parametersLen,
2189 wszApplicationName,
2190 dwApplicationNameLen );
2191 }
2192
2193 /* convert file URLs */
2194 if (UrlIsFileUrlW(sei_tmp.lpFile))
2195 {
2198 if (!buf.Allocate(size) || FAILED(PathCreateFromUrlW(sei_tmp.lpFile, buf, &size, 0)))
2199 return SE_ERR_OOM;
2200
2201 wszApplicationName.Attach(buf.Detach());
2202 sei_tmp.lpFile = wszApplicationName;
2203 }
2204
2205 /* Else, try to execute the filename */
2206 TRACE("execute: %s,%s,%s\n", debugstr_w(wszApplicationName), debugstr_w(wszParameters), debugstr_w(wszDir));
2207
2208 /* separate out command line arguments from executable file name */
2209 LPCWSTR lpFile = sei_tmp.lpFile;
2210 if (!*sei_tmp.lpParameters && !appKnownSingular)
2211 {
2212 /* If the executable path is quoted, handle the rest of the command line as parameters. */
2213 if (sei_tmp.lpFile[0] == L'"')
2214 {
2215 LPWSTR pszArgs = PathGetArgsW(wszApplicationName);
2216 PathRemoveArgsW(wszApplicationName);
2217 PathUnquoteSpacesW(wszApplicationName);
2218 parametersLen = lstrlenW(pszArgs);
2219 if (parametersLen < _countof(parametersBuffer))
2220 {
2221 StringCchCopyW(parametersBuffer, _countof(parametersBuffer), pszArgs);
2222 wszParameters = parametersBuffer;
2223 }
2224 else
2225 {
2226 wszParamAlloc.Attach(StrDupW(pszArgs));
2227 wszParameters = wszParamAlloc;
2228 }
2229 }
2230 /* We have to test sei instead of sei_tmp because sei_tmp had its
2231 * input fMask modified above in SHELL_translate_idlist.
2232 * This code is needed to handle the case where we only have an
2233 * lpIDList with multiple CLSID/PIDL's (not 'My Computer' only) */
2234 else if ((sei->fMask & SEE_MASK_IDLIST) == SEE_MASK_IDLIST)
2235 {
2236 WCHAR buffer[MAX_PATH], xlpFile[MAX_PATH];
2237 LPWSTR space, s;
2238
2239 LPWSTR beg = wszApplicationName;
2240 for(s = beg; (space = const_cast<LPWSTR>(strchrW(s, L' '))); s = space + 1)
2241 {
2242 int idx = space - sei_tmp.lpFile;
2243 memcpy(buffer, sei_tmp.lpFile, idx * sizeof(WCHAR));
2244 buffer[idx] = '\0';
2245
2246 if (SearchPathW(*sei_tmp.lpDirectory ? sei_tmp.lpDirectory : NULL,
2247 buffer, L".exe", _countof(xlpFile), xlpFile, NULL))
2248 {
2249 /* separate out command from parameter string */
2250 LPCWSTR p = space + 1;
2251
2252 while(isspaceW(*p))
2253 ++p;
2254
2255 strcpyW(wszParameters, p);
2256 *space = L'\0';
2257
2258 break;
2259 }
2260 }
2261 }
2262 }
2263
2264 WCHAR wcmdBuffer[1024];
2265 LPWSTR wcmd = wcmdBuffer;
2266 DWORD wcmdLen = _countof(wcmdBuffer);
2268
2269 /* Only execute if it has an executable extension */
2270 if (PathIsExeW(lpFile))
2271 {
2272 len = lstrlenW(wszApplicationName) + 3;
2273 if (sei_tmp.lpParameters[0])
2274 len += 1 + lstrlenW(wszParameters);
2275 if (len > wcmdLen)
2276 {
2277 wcmdAlloc.Allocate(len);
2278 wcmd = wcmdAlloc;
2279 wcmdLen = len;
2280 }
2281 swprintf(wcmd, L"\"%s\"", (LPWSTR)wszApplicationName);
2282 if (sei_tmp.lpParameters[0])
2283 {
2284 strcatW(wcmd, L" ");
2285 strcatW(wcmd, wszParameters);
2286 }
2287
2288 retval = execfunc(wcmd, NULL, FALSE, &sei_tmp, sei);
2289 if (retval > 32)
2290 return TRUE;
2291 }
2292
2293 /* Else, try to find the executable */
2294 WCHAR wszKeyname[256];
2296 wcmd[0] = UNICODE_NULL;
2297 retval = SHELL_FindExecutable(sei_tmp.lpDirectory, lpFile, sei_tmp.lpVerb, wcmd, wcmdLen, wszKeyname, &env, (LPITEMIDLIST)sei_tmp.lpIDList, sei_tmp.lpParameters);
2298 if (retval > 32) /* Found */
2299 {
2300 retval = SHELL_quote_and_execute(wcmd, wszParameters, wszKeyname,
2301 wszApplicationName, env, &sei_tmp,
2302 sei, execfunc);
2303 }
2304 else if (PathIsDirectoryW(lpFile))
2305 {
2306 WCHAR wExec[MAX_PATH];
2308 if (lpQuotedFile.Allocate(strlenW(lpFile) + 3))
2309 {
2310 retval = SHELL_FindExecutable(sei_tmp.lpDirectory, L"explorer",
2311 L"open", wExec, MAX_PATH,
2312 NULL, &env, NULL, NULL);
2313 if (retval > 32)
2314 {
2315 swprintf(lpQuotedFile, L"\"%s\"", lpFile);
2316 retval = SHELL_quote_and_execute(wExec, lpQuotedFile,
2317 wszKeyname,
2318 wszApplicationName, env,
2319 &sei_tmp, sei, execfunc);
2320 }
2321 }
2322 else
2323 retval = 0; /* Out of memory */
2324 }
2325 else if (PathIsURLW(lpFile)) /* File not found, check for URL */
2326 {
2327 retval = SHELL_execute_url(lpFile, wcmd, &sei_tmp, sei, execfunc );
2328 }
2329 /* Check if file specified is in the form www.??????.*** */
2330 else if (!strncmpiW(lpFile, L"www", 3))
2331 {
2332 /* if so, prefix lpFile with http:// and call ShellExecute */
2333 WCHAR lpstrTmpFile[256];
2334 strcpyW(lpstrTmpFile, L"http://");
2335 strcatW(lpstrTmpFile, lpFile);
2336 retval = (UINT_PTR)ShellExecuteW(sei_tmp.hwnd, sei_tmp.lpVerb, lpstrTmpFile, NULL, NULL, 0);
2337 }
2338
2339 TRACE("retval %lu\n", retval);
2340
2341 if (retval <= 32 && !(sei_tmp.fMask & SEE_MASK_FLAG_NO_UI))
2342 {
2344
2345 //FIXME
2346 // need full path
2347
2348 Info.pcszFile = wszApplicationName;
2349 Info.pcszClass = NULL;
2350 Info.oaifInFlags = OAIF_ALLOW_REGISTRATION | OAIF_EXEC;
2351
2352 //if (SHOpenWithDialog(sei_tmp.hwnd, &Info) != S_OK)
2354 do_error_dialog(retval, sei_tmp.hwnd, wszApplicationName);
2355 }
2356
2357 sei->hInstApp = (HINSTANCE)(retval > 32 ? 33 : retval);
2358
2359 return retval > 32;
2360}
BOOL _ILIsDesktop(LPCITEMIDLIST pidl)
Definition: CBandSite.h:24
#define UlongToHandle(ul)
Definition: basetsd.h:97
r l[0]
Definition: byte_order.h:168
void Attach(T *lp)
Definition: atlalloc.h:162
INT WINAPI StrCmpNIW(LPCWSTR lpszStr, LPCWSTR lpszComp, INT iLen)
Definition: string.c:307
INT WINAPI StrCmpNW(LPCWSTR lpszStr, LPCWSTR lpszComp, INT iLen)
Definition: string.c:500
#define lstrlenW
Definition: compat.h:750
UINT WINAPI GetWindowsDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2352
HRESULT SHGetNameAndFlagsW(_In_ LPCITEMIDLIST pidl, _In_ DWORD dwFlags, _Out_opt_ LPWSTR pszText, _In_ UINT cchBuf, _Inout_opt_ DWORD *pdwAttributes)
Definition: utils.cpp:480
void WINAPI PathRemoveArgsW(LPWSTR lpszPath)
Definition: path.c:779
int WINAPI PathGetDriveNumberW(const WCHAR *path)
Definition: path.c:553
HRESULT WINAPI PathCreateFromUrlW(LPCWSTR pszUrl, LPWSTR pszPath, LPDWORD pcchPath, DWORD dwReserved)
Definition: path.c:3361
BOOL WINAPI PathStripToRootW(LPWSTR lpszPath)
Definition: path.c:733
VOID WINAPI PathUnquoteSpacesW(LPWSTR lpszPath)
Definition: path.c:1040
BOOL WINAPI PathIsDirectoryW(LPCWSTR lpszPath)
Definition: path.c:1729
LPWSTR WINAPI PathGetArgsW(LPCWSTR lpszPath)
Definition: path.c:506
LPWSTR WINAPI StrDupW(LPCWSTR lpszStr)
Definition: string.c:1093
BOOL WINAPI PathIsURLW(LPCWSTR lpstrPath)
Definition: url.c:2432
GLdouble s
Definition: gl.h:2039
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
#define FAILED(hr)
Definition: intsafe.h:51
#define DBG_UNREFERENCED_LOCAL_VARIABLE(L)
Definition: ntbasedef.h:331
#define PathAddBackslashW
Definition: pathcch.h:301
HRESULT WINAPI SHParseDisplayName(LPCWSTR pszName, IBindCtx *pbc, LPITEMIDLIST *ppidl, SFGAOF sfgaoIn, SFGAOF *psfgaoOut)
Definition: pidl.c:1541
HRESULT WINAPI SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCITEMIDLIST *ppidlLast)
Definition: pidl.c:1497
#define strncmpiW(s1, s2, n)
Definition: unicode.h:46
#define strcatW(d, s)
Definition: unicode.h:36
#define isspaceW(n)
Definition: unicode.h:58
static __inline void __SHCloneStrW(WCHAR **target, const WCHAR *source)
Definition: shell32_main.h:179
#define SEE_MASK_DOENVSUBST
Definition: shellapi.h:35
#define SEE_MASK_CLASSNAME
Definition: shellapi.h:25
#define SEE_MASK_ASYNCOK
Definition: shellapi.h:54
#define SEE_MASK_IDLIST
Definition: shellapi.h:27
#define SEE_MASK_FLAG_DDEWAIT
Definition: shellapi.h:34
#define SEE_MASK_CONNECTNETDRV
Definition: shellapi.h:32
#define SE_ERR_OOM
Definition: shellapi.h:129
#define SEE_MASK_INVOKEIDLIST
Definition: shellapi.h:28
static UINT_PTR SHELL_execute_class(LPCWSTR wszApplicationName, LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out, SHELL_ExecuteW32 execfunc)
Definition: shlexec.cpp:1687
static HRESULT ShellExecute_ContextMenuVerb(LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:1577
static UINT_PTR SHELL_quote_and_execute(LPCWSTR wcmd, LPCWSTR wszParameters, LPCWSTR lpstrProtocol, LPCWSTR wszApplicationName, LPWSTR env, LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out, SHELL_ExecuteW32 execfunc)
Definition: shlexec.cpp:1854
static BOOL SHELL_InvokePidl(_In_ LPSHELLEXECUTEINFOW sei, _In_ LPCITEMIDLIST pidl)
Definition: shlexec.cpp:1802
static LONG ShellExecute_FromContextMenuHandlers(LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:1643
static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpVerb, LPWSTR lpResult, DWORD resultLen, LPWSTR key, WCHAR **env, LPITEMIDLIST pidl, LPCWSTR args)
Definition: shlexec.cpp:765
#define SEE_MASK_CLASSALL
Definition: shlexec.cpp:33
static WCHAR * expand_environment(const WCHAR *str)
Definition: shlexec.cpp:1945
static UINT_PTR SHELL_execute_url(LPCWSTR lpFile, LPCWSTR wcmd, LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out, SHELL_ExecuteW32 execfunc)
Definition: shlexec.cpp:1890
static void do_error_dialog(UINT_PTR retval, HWND hwnd, WCHAR *filename)
Definition: shlexec.cpp:1924
HINSTANCE WINAPI ShellExecuteW(HWND hwnd, LPCWSTR lpVerb, LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd)
Definition: shlexec.cpp:2529
static BOOL SHELL_translate_idlist(LPSHELLEXECUTEINFOW sei, LPWSTR wszParameters, DWORD parametersLen, LPWSTR wszApplicationName, DWORD dwApplicationNameLen)
Definition: shlexec.cpp:1746
HRESULT hr
Definition: shlfolder.c:183
#define UrlIsFileUrlW(x)
Definition: shlwapi.h:1412
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
#define IID_PPV_ARG(Itype, ppType)

Referenced by ShellExecute_Normal(), and WOWShellExecute().

◆ SHELL_execute_class()

static UINT_PTR SHELL_execute_class ( LPCWSTR  wszApplicationName,
LPSHELLEXECUTEINFOW  psei,
LPSHELLEXECUTEINFOW  psei_out,
SHELL_ExecuteW32  execfunc 
)
static

Definition at line 1687 of file shlexec.cpp.

1688{
1689 WCHAR execCmd[1024], classname[1024];
1690 /* launch a document by fileclass like 'WordPad.Document.1' */
1691 /* the Commandline contains 'c:\Path\wordpad.exe "%1"' */
1692 /* FIXME: wcmd should not be of a fixed size. Fixed to 1024, MAX_PATH is way too short! */
1693 ULONG cmask = (psei->fMask & SEE_MASK_CLASSALL);
1694 DWORD resultLen;
1695 BOOL done;
1696 UINT_PTR rslt;
1697
1698 /* FIXME: remove following block when SHELL_quote_and_execute supports hkeyClass parameter */
1699 if (cmask != SEE_MASK_CLASSNAME)
1700 {
1701 WCHAR wcmd[1024];
1703 (cmask == SEE_MASK_CLASSNAME) ? psei->lpClass : NULL,
1704 psei->lpVerb,
1705 execCmd, sizeof(execCmd));
1706
1707 /* FIXME: get the extension of lpFile, check if it fits to the lpClass */
1708 TRACE("SEE_MASK_CLASSNAME->%s, doc->%s\n", debugstr_w(execCmd), debugstr_w(wszApplicationName));
1709
1710 wcmd[0] = '\0';
1711 done = SHELL_ArgifyW(wcmd, ARRAY_SIZE(wcmd), execCmd, wszApplicationName, (LPITEMIDLIST)psei->lpIDList, psei->lpParameters,
1712 &resultLen, (psei->lpDirectory && *psei->lpDirectory) ? psei->lpDirectory : NULL);
1713 if (!done && wszApplicationName[0])
1714 {
1715#if 0 // Given HKCR\.test=SZ:"test" and HKCR\test\shell\open\command=SZ:"cmd.exe /K echo.Hello", no filename is
1716 // appended on Windows when there is no %1 nor %L when executed with: shlextdbg.exe /shellexec=c:\file.test /INVOKE
1717 strcatW(wcmd, L" ");
1718 if (*wszApplicationName != '"')
1719 {
1720 strcatW(wcmd, L"\"");
1721 strcatW(wcmd, wszApplicationName);
1722 strcatW(wcmd, L"\"");
1723 }
1724 else
1725 strcatW(wcmd, wszApplicationName);
1726#endif
1727 }
1728 if (resultLen > ARRAY_SIZE(wcmd))
1729 ERR("Argify buffer not large enough... truncating\n");
1730 return execfunc(wcmd, NULL, FALSE, psei, psei_out);
1731 }
1732
1733 strcpyW(classname, psei->lpClass);
1734 rslt = SHELL_FindExecutableByVerb(psei->lpVerb, NULL, classname, execCmd, sizeof(execCmd));
1735
1736 TRACE("SHELL_FindExecutableByVerb returned %u (%s, %s)\n", (unsigned int)rslt, debugstr_w(classname), debugstr_w(execCmd));
1737 if (33 > rslt)
1738 return rslt;
1739 rslt = SHELL_quote_and_execute( execCmd, L"", classname,
1740 wszApplicationName, NULL, psei,
1741 psei_out, execfunc );
1742 return rslt;
1743
1744}
WCHAR classname[128]
Definition: startup.c:15
BOOL HCR_GetExecuteCommandW(HKEY hkeyClass, LPCWSTR szClass, LPCWSTR szVerb, LPWSTR szDest, DWORD len)
Definition: classes.c:220
#define SEE_MASK_CLASSKEY
Definition: shellapi.h:26
static UINT SHELL_FindExecutableByVerb(LPCWSTR lpVerb, LPWSTR key, LPWSTR classname, LPWSTR command, LONG commandlen)
Definition: shlexec.cpp:697
uint32_t ULONG
Definition: typedefs.h:59

Referenced by SHELL_execute().

◆ SHELL_execute_url()

static UINT_PTR SHELL_execute_url ( LPCWSTR  lpFile,
LPCWSTR  wcmd,
LPSHELLEXECUTEINFOW  psei,
LPSHELLEXECUTEINFOW  psei_out,
SHELL_ExecuteW32  execfunc 
)
static

Definition at line 1890 of file shlexec.cpp.

1891{
1894 LPCWSTR lpstrRes;
1895 INT iSize;
1896 DWORD len;
1897
1898 lpstrRes = strchrW(lpFile, ':');
1899 if (lpstrRes)
1900 iSize = lpstrRes - lpFile;
1901 else
1902 iSize = strlenW(lpFile);
1903
1904 TRACE("Got URL: %s\n", debugstr_w(lpFile));
1905 /* Looking for ...<protocol>\shell<lpVerb>\command */
1906 len = iSize + lstrlenW(L"\\shell\\") + lstrlenW(L"\\command") + 1;
1907 if (psei->lpVerb && *psei->lpVerb)
1908 len += lstrlenW(psei->lpVerb);
1909 else
1910 len += lstrlenW(L"open");
1911 lpstrProtocol.Allocate(len);
1912 memcpy(lpstrProtocol, lpFile, iSize * sizeof(WCHAR));
1913 lpstrProtocol[iSize] = '\0';
1914 strcatW(lpstrProtocol, L"\\shell\\");
1915 strcatW(lpstrProtocol, psei->lpVerb && *psei->lpVerb ? psei->lpVerb : L"open");
1916 strcatW(lpstrProtocol, L"\\command");
1917
1918 retval = execute_from_key(lpstrProtocol, lpFile, NULL, psei->lpParameters,
1919 wcmd, execfunc, psei, psei_out);
1920
1921 return retval;
1922}
static UINT_PTR execute_from_key(LPCWSTR key, LPCWSTR lpFile, WCHAR *env, LPCWSTR szCommandline, LPCWSTR executable_name, SHELL_ExecuteW32 execfunc, LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out)
Definition: shlexec.cpp:1210

Referenced by SHELL_execute().

◆ SHELL_ExecuteW()

static UINT_PTR SHELL_ExecuteW ( const WCHAR lpCmd,
WCHAR env,
BOOL  shWait,
const SHELLEXECUTEINFOW psei,
LPSHELLEXECUTEINFOW  psei_out 
)
static

Definition at line 475 of file shlexec.cpp.

477{
481 UINT gcdret = 0;
482 WCHAR curdir[MAX_PATH];
483 DWORD dwCreationFlags;
484 const WCHAR *lpDirectory = NULL;
485
486 TRACE("Execute %s from directory %s\n", debugstr_w(lpCmd), debugstr_w(psei->lpDirectory));
487
488 /* make sure we don't fail the CreateProcess if the calling app passes in
489 * a bad working directory */
490 if (!StrIsNullOrEmpty(psei->lpDirectory))
491 {
494 lpDirectory = psei->lpDirectory;
495 }
496
497 /* ShellExecute specifies the command from psei->lpDirectory
498 * if present. Not from the current dir as CreateProcess does */
499 if (lpDirectory)
500 if ((gcdret = GetCurrentDirectoryW( MAX_PATH, curdir)))
502 ERR("cannot set directory %s\n", debugstr_w(lpDirectory));
503
505 startup.cb = sizeof(STARTUPINFOW);
507 startup.wShowWindow = psei->nShow;
508 dwCreationFlags = CREATE_UNICODE_ENVIRONMENT;
509 if (!(psei->fMask & SEE_MASK_NO_CONSOLE))
510 dwCreationFlags |= CREATE_NEW_CONSOLE;
511 if (psei->fMask & SEE_MASK_FLAG_SEPVDM)
512 dwCreationFlags |= CREATE_SEPARATE_WOW_VDM;
513 startup.lpTitle = (LPWSTR)(psei->fMask & (SEE_MASK_HASLINKNAME | SEE_MASK_HASTITLE) ? psei->lpClass : NULL);
514
515 if (psei->fMask & SEE_MASK_HASLINKNAME)
516 startup.dwFlags |= STARTF_TITLEISLINKNAME;
517
518 if (psei->fMask & SEE_MASK_HOTKEY)
519 {
520 startup.hStdInput = UlongToHandle(psei->dwHotKey);
521 startup.dwFlags |= STARTF_USEHOTKEY;
522 }
523
524 if (psei->fMask & SEE_MASK_ICON) // hIcon has higher precedence than hMonitor
525 {
526 startup.hStdOutput = psei->hIcon;
527 startup.dwFlags |= STARTF_SHELLPRIVATE;
528 }
529 else if ((psei->fMask & SEE_MASK_HMONITOR) || psei->hwnd)
530 {
531 if (psei->fMask & SEE_MASK_HMONITOR)
532 startup.hStdOutput = psei->hMonitor;
533 else if (psei->hwnd)
534 startup.hStdOutput = MonitorFromWindow(psei->hwnd, MONITOR_DEFAULTTONEAREST);
535 if (startup.hStdOutput)
536 startup.dwFlags |= STARTF_SHELLPRIVATE;
537 }
538
539 if (CreateProcessW(NULL, (LPWSTR)lpCmd, NULL, NULL, FALSE, dwCreationFlags, env,
541 {
542 /* Give 30 seconds to the app to come up, if desired. Probably only needed
543 when starting app immediately before making a DDE connection. */
544 if (shWait)
545 if (WaitForInputIdle(info.hProcess, 30000) == WAIT_FAILED)
546 WARN("WaitForInputIdle failed: Error %d\n", GetLastError() );
547 retval = 33;
548
549 if (psei->fMask & SEE_MASK_NOCLOSEPROCESS)
550 psei_out->hProcess = info.hProcess;
551 else
552 CloseHandle( info.hProcess );
553 CloseHandle( info.hThread );
554 }
555 else if ((retval = GetLastError()) >= 32)
556 {
557 WARN("CreateProcess returned error %ld\n", retval);
559 }
560
561 TRACE("returning %lu\n", retval);
562
563 psei_out->hInstApp = (HINSTANCE)retval;
564
565 if (gcdret)
566 if (!SetCurrentDirectoryW(curdir))
567 ERR("cannot return to directory %s\n", debugstr_w(curdir));
568
569 return retval;
570}
static void startup(void)
#define CloseHandle
Definition: compat.h:739
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessW(LPCWSTR lpApplicationName, LPWSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4598
HMONITOR WINAPI MonitorFromWindow(HWND, DWORD)
unsigned int UINT
Definition: ndis.h:50
#define SEE_MASK_ICON
Definition: shellapi.h:29
#define SEE_MASK_HOTKEY
Definition: shellapi.h:30
#define SEE_MASK_HMONITOR
Definition: shellapi.h:55
#define SEE_MASK_HASLINKNAME
Definition: shellapi.h:49
#define STARTF_SHELLPRIVATE
Definition: shlexec.cpp:31
Definition: cookie.c:202
#define STARTF_USEHOTKEY
Definition: main.c:17
#define STARTF_USESHOWWINDOW
Definition: winbase.h:518
#define CREATE_UNICODE_ENVIRONMENT
Definition: winbase.h:190
#define CREATE_SEPARATE_WOW_VDM
Definition: winbase.h:191
#define WAIT_FAILED
Definition: winbase.h:440
#define CREATE_NEW_CONSOLE
Definition: winbase.h:184
struct _STARTUPINFOW STARTUPINFOW
#define ERROR_BAD_FORMAT
Definition: winerror.h:114
DWORD WINAPI WaitForInputIdle(_In_ HANDLE, _In_ DWORD)

Referenced by ShellExecute_Normal().

◆ SHELL_FindExecutable()

static UINT SHELL_FindExecutable ( LPCWSTR  lpPath,
LPCWSTR  lpFile,
LPCWSTR  lpVerb,
LPWSTR  lpResult,
DWORD  resultLen,
LPWSTR  key,
WCHAR **  env,
LPITEMIDLIST  pidl,
LPCWSTR  args 
)
static

Definition at line 765 of file shlexec.cpp.

767{
768 WCHAR *extension = NULL; /* pointer to file extension */
769 WCHAR classname[256]; /* registry name for this file type */
770 LONG classnamelen = sizeof(classname); /* length of above */
771 WCHAR command[1024]; /* command from registry */
772 WCHAR wBuffer[256]; /* Used to GetProfileString */
774 WCHAR *tok; /* token pointer */
775 WCHAR xlpFile[MAX_PATH]; /* result of PathResolve */
776 DWORD attribs; /* file attributes */
777 WCHAR curdir[MAX_PATH];
778 const WCHAR *search_paths[3] = {0};
779
780 TRACE("%s\n", debugstr_w(lpFile));
781
782 if (!lpResult)
784
785 xlpFile[0] = '\0';
786 lpResult[0] = '\0'; /* Start off with an empty return string */
787 if (key) *key = '\0';
788
789 /* trap NULL parameters on entry */
790 if (!lpFile)
791 {
792 WARN("(lpFile=%s,lpResult=%s): NULL parameter\n",
793 debugstr_w(lpFile), debugstr_w(lpResult));
794 return ERROR_FILE_NOT_FOUND; /* File not found. Close enough, I guess. */
795 }
796
797 if (SHELL_TryAppPathW( lpFile, lpResult, env ))
798 {
799 TRACE("found %s via App Paths\n", debugstr_w(lpResult));
800 return 33;
801 }
802
803 GetCurrentDirectoryW(ARRAY_SIZE(curdir), curdir);
804 if (lpPath && *lpPath)
805 {
806 search_paths[0] = lpPath;
807 search_paths[1] = curdir;
808 }
809 else
810 {
811 search_paths[0] = curdir;
812 }
813
814 lstrcpyW(xlpFile, lpFile);
815 if (PathResolveW(xlpFile, search_paths, PRF_TRYPROGRAMEXTENSIONS | PRF_VERIFYEXISTS) ||
816 PathFindOnPathW(xlpFile, search_paths))
817 {
818 TRACE("PathResolveW returned non-zero\n");
819 lpFile = xlpFile;
820 PathRemoveBlanksW(xlpFile);
821
822 /* Clear any trailing periods */
823 SIZE_T i = wcslen(xlpFile);
824 while (i > 0 && xlpFile[i - 1] == '.')
825 {
826 xlpFile[--i] = '\0';
827 }
828
829 lstrcpyW(lpResult, xlpFile);
830 /* The file was found in lpPath or one of the directories in the system-wide search path */
831 }
832 else
833 {
834 xlpFile[0] = '\0';
835 }
836
837 attribs = GetFileAttributesW(lpFile);
839 {
840 wcscpy(classname, L"Folder");
841 }
842 else
843 {
844 /* Did we get something? Anything? */
845 if (xlpFile[0] == 0)
846 {
847 TRACE("Returning SE_ERR_FNF\n");
848 return SE_ERR_FNF;
849 }
850 /* First thing we need is the file's extension */
851 extension = wcsrchr(xlpFile, '.'); /* Assume last "." is the one; */
852 /* File->Run in progman uses */
853 /* .\FILE.EXE :( */
854 TRACE("xlpFile=%s,extension=%s\n", debugstr_w(xlpFile), debugstr_w(extension));
855
856 if (extension == NULL || extension[1] == 0)
857 {
858 WARN("Returning SE_ERR_NOASSOC\n");
859 return SE_ERR_NOASSOC;
860 }
861
862 /* Three places to check: */
863 /* 1. win.ini, [windows], programs (NB no leading '.') */
864 /* 2. Registry, HKEY_CLASS_ROOT<classname>\shell\open\command */
865 /* 3. win.ini, [extensions], extension (NB no leading '.' */
866 /* All I know of the order is that registry is checked before */
867 /* extensions; however, it'd make sense to check the programs */
868 /* section first, so that's what happens here. */
869
870 /* See if it's a program - if GetProfileString fails, we skip this
871 * section. Actually, if GetProfileString fails, we've probably
872 * got a lot more to worry about than running a program... */
873 if (GetProfileStringW(L"windows", L"programs", L"exe pif bat cmd com", wBuffer, ARRAY_SIZE(wBuffer)) > 0)
874 {
875 CharLowerW(wBuffer);
876 tok = wBuffer;
877 while (*tok)
878 {
879 WCHAR *p = tok;
880 while (*p && *p != ' ' && *p != '\t') p++;
881 if (*p)
882 {
883 *p++ = 0;
884 while (*p == ' ' || *p == '\t') p++;
885 }
886
887 if (_wcsicmp(tok, &extension[1]) == 0) /* have to skip the leading "." */
888 {
889 wcscpy(lpResult, xlpFile);
890 /* Need to perhaps check that the file has a path
891 * attached */
892 TRACE("found %s\n", debugstr_w(lpResult));
893 return 33;
894 /* Greater than 32 to indicate success */
895 }
896 tok = p;
897 }
898 }
899
900 /* Check registry */
902 &classnamelen) == ERROR_SUCCESS)
903 {
904 classnamelen /= sizeof(WCHAR);
905 if (classnamelen == ARRAY_SIZE(classname))
906 classnamelen--;
907
908 classname[classnamelen] = '\0';
909 TRACE("File type: %s\n", debugstr_w(classname));
910 }
911 else
912 {
913 *classname = '\0';
914 }
915 }
916
917 if (*classname)
918 {
919 /* pass the verb string to SHELL_FindExecutableByVerb() */
921
922 if (retval > 32)
923 {
924 DWORD finishedLen;
925 SHELL_ArgifyW(lpResult, resultLen, command, xlpFile, pidl, args, &finishedLen, lpPath);
926 if (finishedLen > resultLen)
927 ERR("Argify buffer not large enough.. truncated\n");
928 /* Remove double quotation marks and command line arguments */
929 if (*lpResult == '"')
930 {
931 WCHAR *p = lpResult;
932 while (*(p + 1) != '"')
933 {
934 *p = *(p + 1);
935 p++;
936 }
937 *p = '\0';
938 }
939 else
940 {
941 /* Truncate on first space */
942 WCHAR *p = lpResult;
943 while (*p != ' ' && *p != '\0')
944 p++;
945 *p = '\0';
946 }
947 }
948 }
949 else /* Check win.ini */
950 {
951 /* Toss the leading dot */
952 extension++;
953 if (GetProfileStringW(L"extensions", extension, L"", command, ARRAY_SIZE(command)) > 0)
954 {
955 if (wcslen(command) != 0)
956 {
957 wcscpy(lpResult, command);
958 tok = wcschr(lpResult, '^'); /* should be ^.extension? */
959 if (tok != NULL)
960 {
961 tok[0] = '\0';
962 wcscat(lpResult, xlpFile); /* what if no dir in xlpFile? */
963 tok = wcschr(command, '^'); /* see above */
964 if ((tok != NULL) && (wcslen(tok) > 5))
965 {
966 wcscat(lpResult, &tok[5]);
967 }
968 }
969 retval = 33; /* FIXME - see above */
970 }
971 }
972 }
973
974 TRACE("returning path %s, retval %d\n", debugstr_w(lpResult), retval);
975 return retval;
976}
#define PRF_VERIFYEXISTS
Definition: PathResolve.cpp:38
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define wcsrchr
Definition: compat.h:16
#define lstrcpyW
Definition: compat.h:749
INT WINAPI GetProfileStringW(LPCWSTR section, LPCWSTR entry, LPCWSTR def_val, LPWSTR buffer, UINT len)
Definition: profile.c:1267
BOOL WINAPI PathFindOnPathW(LPWSTR lpszFile, LPCWSTR *lppszOtherDirs)
Definition: path.c:1409
void WINAPI PathRemoveBlanksW(LPWSTR pszPath)
Definition: path.c:923
const GLint * attribs
Definition: glext.h:10538
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
static BOOL SHELL_TryAppPathW(LPCWSTR szName, LPWSTR lpResult, WCHAR **env)
Definition: shlexec.cpp:637
LPWSTR WINAPI CharLowerW(_Inout_ LPWSTR)

Referenced by SHELL_execute(), and shellex_get_contextmenu().

◆ SHELL_FindExecutableByVerb()

static UINT SHELL_FindExecutableByVerb ( LPCWSTR  lpVerb,
LPWSTR  key,
LPWSTR  classname,
LPWSTR  command,
LONG  commandlen 
)
static

Definition at line 697 of file shlexec.cpp.

698{
699 HKEY hkeyClass;
700 WCHAR verb[MAX_PATH];
701
702 if (RegOpenKeyExW(HKEY_CLASSES_ROOT, classname, 0, 0x02000000, &hkeyClass))
703 return SE_ERR_NOASSOC;
704 if (!HCR_GetDefaultVerbW(hkeyClass, lpVerb, verb, ARRAY_SIZE(verb)))
705 return SE_ERR_NOASSOC;
706 RegCloseKey(hkeyClass);
707
708 /* Looking for ...buffer\shell<verb>\command */
709 wcscat(classname, L"\\shell\\");
710 wcscat(classname, verb);
711 wcscat(classname, L"\\command");
712
714 &commandlen) == ERROR_SUCCESS)
715 {
716 commandlen /= sizeof(WCHAR);
717 if (key) wcscpy(key, classname);
718#if 0
719 LPWSTR tmp;
720 WCHAR param[256];
721 LONG paramlen = sizeof(param);
722
723 /* FIXME: it seems all Windows version don't behave the same here.
724 * the doc states that this ddeexec information can be found after
725 * the exec names.
726 * on Win98, it doesn't appear, but I think it does on Win2k
727 */
728 /* Get the parameters needed by the application
729 from the associated ddeexec key */
730 tmp = strstrW(classname, L"\\command");
731 tmp[0] = '\0';
732 wcscat(classname, wDdeexec);
734 &paramlen) == ERROR_SUCCESS)
735 {
736 paramlen /= sizeof(WCHAR);
737 wcscat(command, L" ");
739 commandlen += paramlen;
740 }
741#endif
742
743 command[commandlen] = '\0';
744
745 return 33; /* FIXME see SHELL_FindExecutable() */
746 }
747
748 return SE_ERR_NOASSOC;
749}
#define RegCloseKey(hKey)
Definition: registry.h:49
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
BOOL HCR_GetDefaultVerbW(HKEY hkeyClass, LPCWSTR szVerb, LPWSTR szDest, DWORD len)
Definition: classes.c:152

Referenced by SHELL_execute_class(), and SHELL_FindExecutable().

◆ SHELL_GetPathFromIDListForExecuteW()

static HRESULT SHELL_GetPathFromIDListForExecuteW ( LPCITEMIDLIST  pidl,
LPWSTR  pszPath,
UINT  uOutSize 
)
static

Definition at line 453 of file shlexec.cpp.

454{
455 STRRET strret;
456 CComPtr<IShellFolder> desktop;
457
458 HRESULT hr = SHGetDesktopFolder(&desktop);
459
460 if (SUCCEEDED(hr))
461 {
462 hr = desktop->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &strret);
463
464 if (SUCCEEDED(hr))
465 StrRetToStrNW(pszPath, uOutSize, &strret, pidl);
466 }
467
468 return hr;
469}
HRESULT WINAPI SHGetDesktopFolder(IShellFolder **psf)
BOOL WINAPI StrRetToStrNW(LPWSTR dest, DWORD len, LPSTRRET src, const ITEMIDLIST *pidl)
Definition: shellstring.c:85

Referenced by SHELL_translate_idlist().

◆ SHELL_InRunDllProcess()

static BOOL SHELL_InRunDllProcess ( VOID  )
static

Definition at line 39 of file shlexec.cpp.

40{
41 WCHAR szModule[MAX_PATH];
42 static INT s_bInDllProcess = -1;
43
44 if (s_bInDllProcess != -1)
45 return s_bInDllProcess;
46
47 s_bInDllProcess = GetModuleFileNameW(NULL, szModule, _countof(szModule)) &&
48 (StrStrIW(PathFindFileNameW(szModule), L"rundll") != NULL);
49 return s_bInDllProcess;
50}
LPWSTR WINAPI StrStrIW(LPCWSTR lpszStr, LPCWSTR lpszSearch)
Definition: string.c:380
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:600
LPWSTR WINAPI PathFindFileNameW(LPCWSTR lpszPath)
Definition: path.c:394

Referenced by ShellExec_RunDLL_Helper(), and ShellExecuteExW().

◆ SHELL_InvokePidl()

static BOOL SHELL_InvokePidl ( _In_ LPSHELLEXECUTEINFOW  sei,
_In_ LPCITEMIDLIST  pidl 
)
static

Definition at line 1802 of file shlexec.cpp.

1805{
1806 // Bind pidl
1807 CComPtr<IShellFolder> psfFolder;
1808 LPCITEMIDLIST pidlLast;
1809 HRESULT hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &psfFolder), &pidlLast);
1811 return FALSE;
1812
1813 // Get the context menu to invoke a command
1815 hr = psfFolder->GetUIObjectOf(NULL, 1, &pidlLast, IID_NULL_PPV_ARG(IContextMenu, &pCM));
1817 return FALSE;
1818
1819 // Invoke a command
1820 CMINVOKECOMMANDINFO ici = { sizeof(ici) };
1821 ici.fMask = (sei->fMask & SEE_CMIC_COMMON_BASICFLAGS) & ~CMIC_MASK_UNICODE; // FIXME: Unicode?
1822 ici.nShow = sei->nShow;
1823 ici.hwnd = sei->hwnd;
1824 char szVerb[VERBKEY_CCHMAX];
1825 if (sei->lpVerb && sei->lpVerb[0])
1826 {
1827 WideCharToMultiByte(CP_ACP, 0, sei->lpVerb, -1, szVerb, _countof(szVerb), NULL, NULL);
1828 szVerb[_countof(szVerb) - 1] = ANSI_NULL; // Avoid buffer overrun
1829 ici.lpVerb = szVerb;
1830 }
1831 else // The default verb?
1832 {
1833 HMENU hMenu = CreatePopupMenu();
1834 const INT idCmdFirst = 1, idCmdLast = 0x7FFF;
1835 hr = pCM->QueryContextMenu(hMenu, 0, idCmdFirst, idCmdLast, CMF_DEFAULTONLY);
1837 {
1838 DestroyMenu(hMenu);
1839 return FALSE;
1840 }
1841
1842 INT nDefaultID = GetMenuDefaultItem(hMenu, FALSE, 0);
1843 DestroyMenu(hMenu);
1844 if (nDefaultID == -1)
1845 nDefaultID = idCmdFirst;
1846
1847 ici.lpVerb = MAKEINTRESOURCEA(nDefaultID - idCmdFirst);
1848 }
1849 hr = pCM->InvokeCommand(&ici);
1850
1851 return !FAILED_UNEXPECTEDLY(hr);
1852}
#define VERBKEY_CCHMAX
Definition: precomp.h:130
#define FAILED_UNEXPECTEDLY
Definition: utils.cpp:30
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:63
#define ANSI_NULL
#define SEE_CMIC_COMMON_BASICFLAGS
Definition: shellutils.h:665
HMENU WINAPI CreatePopupMenu(void)
Definition: menu.c:838
UINT WINAPI GetMenuDefaultItem(_In_ HMENU hMenu, _In_ UINT fByPos, _In_ UINT gmdiFlags)
#define MAKEINTRESOURCEA(i)
Definition: winuser.h:581
BOOL WINAPI DestroyMenu(_In_ HMENU)
#define IID_NULL_PPV_ARG(Itype, ppType)

Referenced by SHELL_execute().

◆ SHELL_quote_and_execute()

static UINT_PTR SHELL_quote_and_execute ( LPCWSTR  wcmd,
LPCWSTR  wszParameters,
LPCWSTR  lpstrProtocol,
LPCWSTR  wszApplicationName,
LPWSTR  env,
LPSHELLEXECUTEINFOW  psei,
LPSHELLEXECUTEINFOW  psei_out,
SHELL_ExecuteW32  execfunc 
)
static

Definition at line 1854 of file shlexec.cpp.

1855{
1857 DWORD len;
1859
1860 /* Length of quotes plus length of command plus NULL terminator */
1861 len = 2 + lstrlenW(wcmd) + 1;
1862 if (wszParameters[0])
1863 {
1864 /* Length of space plus length of parameters */
1865 len += 1 + lstrlenW(wszParameters);
1866 }
1867 wszQuotedCmd.Allocate(len);
1868 /* Must quote to handle case where cmd contains spaces,
1869 * else security hole if malicious user creates executable file "C:\\Program"
1870 */
1871 strcpyW(wszQuotedCmd, L"\"");
1872 strcatW(wszQuotedCmd, wcmd);
1873 strcatW(wszQuotedCmd, L"\"");
1874 if (wszParameters[0])
1875 {
1876 strcatW(wszQuotedCmd, L" ");
1877 strcatW(wszQuotedCmd, wszParameters);
1878 }
1879
1880 TRACE("%s/%s => %s/%s\n", debugstr_w(wszApplicationName), debugstr_w(psei->lpVerb), debugstr_w(wszQuotedCmd), debugstr_w(wszKeyname));
1881
1882 if (*wszKeyname)
1883 retval = execute_from_key(wszKeyname, wszApplicationName, env, psei->lpParameters, wcmd, execfunc, psei, psei_out);
1884 else
1885 retval = execfunc(wszQuotedCmd, env, FALSE, psei, psei_out);
1886
1887 return retval;
1888}

Referenced by SHELL_execute(), and SHELL_execute_class().

◆ SHELL_translate_idlist()

static BOOL SHELL_translate_idlist ( LPSHELLEXECUTEINFOW  sei,
LPWSTR  wszParameters,
DWORD  parametersLen,
LPWSTR  wszApplicationName,
DWORD  dwApplicationNameLen 
)
static

Definition at line 1746 of file shlexec.cpp.

1747{
1749 BOOL appKnownSingular = FALSE;
1750
1751 /* last chance to translate IDList: now also allow CLSID paths */
1753 if (buffer[0] == ':' && buffer[1] == ':') {
1754 /* open shell folder for the specified class GUID */
1755 if (strlenW(buffer) + 1 > parametersLen)
1756 ERR("parameters len exceeds buffer size (%i > %i), truncating\n",
1757 lstrlenW(buffer) + 1, parametersLen);
1758 lstrcpynW(wszParameters, buffer, parametersLen);
1759 if (strlenW(L"explorer.exe") > dwApplicationNameLen)
1760 ERR("application len exceeds buffer size (%i), truncating\n",
1761 dwApplicationNameLen);
1762 lstrcpynW(wszApplicationName, L"explorer.exe", dwApplicationNameLen);
1763 appKnownSingular = TRUE;
1764
1765 sei->fMask &= ~SEE_MASK_INVOKEIDLIST;
1766 } else {
1768 DWORD attribs;
1769 DWORD resultLen;
1770 /* Check if we're executing a directory and if so use the
1771 handler for the Folder class */
1776 HCR_GetExecuteCommandW(0, L"Folder",
1777 sei->lpVerb,
1778 buffer, sizeof(buffer))) {
1779 SHELL_ArgifyW(wszApplicationName, dwApplicationNameLen,
1780 buffer, target, (LPITEMIDLIST)sei->lpIDList, NULL, &resultLen,
1781 !StrIsNullOrEmpty(sei->lpDirectory) ? sei->lpDirectory : NULL);
1782 if (resultLen > dwApplicationNameLen)
1783 ERR("Argify buffer not large enough... truncating\n"); // FIXME: Report this to the caller?
1784 appKnownSingular = FALSE;
1785 // HACKFIX: We really want the !appKnownSingular code in SHELL_execute to split the
1786 // parameters for us but we cannot guarantee that the exe in the registry is quoted.
1787 // We have now turned 'explorer.exe "%1" into 'explorer.exe "c:\path\from\pidl"' and
1788 // need to split to application and parameters.
1789 LPCWSTR params = PathGetArgsW(wszApplicationName);
1790 lstrcpynW(wszParameters, params, parametersLen);
1791 PathRemoveArgsW(wszApplicationName);
1792 PathUnquoteSpacesW(wszApplicationName);
1793 appKnownSingular = TRUE;
1794 }
1795 sei->fMask &= ~SEE_MASK_INVOKEIDLIST;
1796 }
1797 }
1798 return appKnownSingular;
1799}
#define lstrcpynW
Definition: compat.h:738
GLenum const GLfloat * params
Definition: glext.h:5645
GLenum target
Definition: glext.h:7315
static HRESULT SHELL_GetPathFromIDListForExecuteW(LPCITEMIDLIST pidl, LPWSTR pszPath, UINT uOutSize)
Definition: shlexec.cpp:453
#define max(a, b)
Definition: svc.c:63

Referenced by SHELL_execute().

◆ SHELL_TryAppPathW()

static BOOL SHELL_TryAppPathW ( LPCWSTR  szName,
LPWSTR  lpResult,
WCHAR **  env 
)
static

Definition at line 637 of file shlexec.cpp.

638{
639 HKEY hkApp = NULL;
640 WCHAR buffer[1024];
641 DWORD len, dwType;
642 LONG res;
643 BOOL found = FALSE;
644
645 if (env) *env = NULL;
646 wcscpy(buffer, L"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\");
649 if (res)
650 {
651 // Add ".exe" extension, if extension does not exists
652 if (PathAddExtensionW(buffer, L".exe"))
653 {
655 }
656 if (res) goto end;
657 }
658
659 len = MAX_PATH * sizeof(WCHAR);
660 res = SHRegQueryValueExW(hkApp, NULL, NULL, &dwType, (LPBYTE)lpResult, &len);
661 if (res != ERROR_SUCCESS || dwType != REG_SZ)
662 goto end;
663
664 found = TRUE;
665
666 if (env)
667 {
668 len = sizeof(buffer);
669 res = SHRegQueryValueExW(hkApp, L"Path", NULL, &dwType, (LPBYTE)buffer, &len);
670 if (res == ERROR_SUCCESS && dwType == REG_SZ && buffer[0])
672 }
673
674end:
675 if (hkApp) RegCloseKey(hkApp);
676 return found;
677}
GLuint GLuint end
Definition: gl.h:1545
#define REG_SZ
Definition: layer.c:22
#define KEY_READ
Definition: nt_native.h:1023
#define PathAddExtensionW
Definition: pathcch.h:305
static const WCHAR szName[]
Definition: powrprof.c:45
LONG WINAPI SHRegQueryValueExW(HKEY hkey, LPCWSTR pszValue, LPDWORD pdwReserved, LPDWORD pdwType, LPVOID pvData, LPDWORD pcbData)
Definition: shellreg.c:108
static LPWSTR SHELL_BuildEnvW(const WCHAR *path)
Definition: shlexec.cpp:579
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12

Referenced by SHELL_FindExecutable().

◆ shellex_get_contextmenu()

static HRESULT shellex_get_contextmenu ( LPSHELLEXECUTEINFOW  sei,
CComPtr< IContextMenu > &  cm 
)
static

Definition at line 1538 of file shlexec.cpp.

1539{
1540 CComHeapPtr<ITEMIDLIST> allocatedPidl;
1541 LPITEMIDLIST pidl = NULL;
1542
1543 if (sei->lpIDList)
1544 {
1545 pidl = (LPITEMIDLIST)sei->lpIDList;
1546 }
1547 else
1548 {
1549 SFGAOF sfga = 0;
1550 HRESULT hr = SHParseDisplayName(sei->lpFile, NULL, &allocatedPidl, SFGAO_STORAGECAPMASK, &sfga);
1551 if (FAILED(hr))
1552 {
1553 WCHAR Buffer[MAX_PATH] = {};
1554 // FIXME: MAX_PATH.....
1556 if (retval <= 32)
1557 return HRESULT_FROM_WIN32(retval);
1558
1559 hr = SHParseDisplayName(Buffer, NULL, &allocatedPidl, SFGAO_STORAGECAPMASK, &sfga);
1560 // This should not happen, we found it...
1562 return hr;
1563 }
1564
1565 pidl = allocatedPidl;
1566 }
1567
1569 LPCITEMIDLIST pidllast = NULL;
1570 HRESULT hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &shf), &pidllast);
1571 if (FAILED(hr))
1572 return hr;
1573
1574 return shf->GetUIObjectOf(NULL, 1, &pidllast, IID_NULL_PPV_ARG(IContextMenu, &cm));
1575}
Definition: bufpool.h:45
static IShellFolder IShellItem **static IBindCtx LPITEMIDLIST SFGAOF
Definition: ebrowser.c:83
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92

Referenced by ShellExecute_ContextMenuVerb().

◆ shellex_get_dataobj()

static HRESULT shellex_get_dataobj ( LPSHELLEXECUTEINFOW  sei,
CComPtr< IDataObject > &  dataObj 
)
static

Definition at line 1410 of file shlexec.cpp.

1411{
1412 CComHeapPtr<ITEMIDLIST> allocatedPidl;
1413 LPITEMIDLIST pidl = NULL;
1414
1415 if (sei->fMask & SEE_MASK_CLASSALL)
1416 {
1417 pidl = (LPITEMIDLIST)sei->lpIDList;
1418 }
1419 else
1420 {
1421 WCHAR fullpath[MAX_PATH];
1422 BOOL ret;
1423
1424 fullpath[0] = 0;
1425 ret = GetFullPathNameW(sei->lpFile, MAX_PATH, fullpath, NULL);
1426 if (!ret)
1428
1429 pidl = ILCreateFromPathW(fullpath);
1430 allocatedPidl.Attach(pidl);
1431 }
1433}
DWORD WINAPI GetFullPathNameW(IN LPCWSTR lpFileName, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart)
Definition: path.c:1106
EXTERN_C HRESULT SHELL_GetUIObjectOfAbsoluteItem(_In_opt_ HWND hWnd, _In_ PCIDLIST_ABSOLUTE pidl, _In_ REFIID riid, _Out_ void **ppvObj)
Definition: utils.cpp:380
LPITEMIDLIST WINAPI ILCreateFromPathW(LPCWSTR path)
Definition: pidl.c:1101

Referenced by shellex_load_object_and_run().

◆ shellex_load_object_and_run()

static HRESULT shellex_load_object_and_run ( HKEY  hkey,
LPCGUID  guid,
LPSHELLEXECUTEINFOW  sei 
)
static

Definition at line 1504 of file shlexec.cpp.

1505{
1506 TRACE("%p %s %p\n", hkey, debugstr_guid(guid), sei);
1507
1508 CCoInit coInit;
1509
1510 if (FAILED_UNEXPECTEDLY(coInit.hr))
1511 return coInit.hr;
1512
1514 HRESULT hr = CoCreateInstance(*guid, NULL, CLSCTX_INPROC_SERVER,
1517 return hr;
1518
1519 CComPtr<IDataObject> dataobj;
1520 hr = shellex_get_dataobj(sei, dataobj);
1522 return hr;
1523
1524 hr = obj->Initialize(NULL, dataobj, hkey);
1526 return hr;
1527
1529 hr = obj->QueryInterface(IID_PPV_ARG(IObjectWithSite, &ows));
1531 return hr;
1532
1533 ows->SetSite(NULL);
1534
1536}
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
#define debugstr_guid
Definition: kernel32.h:35
const GUID * guid
static HRESULT shellex_run_context_menu_default(IShellExtInit *obj, LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:1435
static HRESULT shellex_get_dataobj(LPSHELLEXECUTEINFOW sei, CComPtr< IDataObject > &dataObj)
Definition: shlexec.cpp:1410

Referenced by ShellExecute_FromContextMenuHandlers().

◆ shellex_run_context_menu_default()

static HRESULT shellex_run_context_menu_default ( IShellExtInit obj,
LPSHELLEXECUTEINFOW  sei 
)
static

Definition at line 1435 of file shlexec.cpp.

1437{
1439 CMINVOKECOMMANDINFOEX ici;
1441 WCHAR string[0x80];
1442 INT i, n, def = -1;
1443 HMENU hmenu = 0;
1444 HRESULT r;
1445
1446 TRACE("%p %p\n", obj, sei);
1447
1448 r = obj->QueryInterface(IID_PPV_ARG(IContextMenu, &cm));
1449 if (FAILED(r))
1450 return r;
1451
1452 hmenu = CreateMenu();
1453 if (!hmenu)
1454 goto end;
1455
1456 /* the number of the last menu added is returned in r */
1457 r = cm->QueryContextMenu(hmenu, 0, 0x20, 0x7fff, CMF_DEFAULTONLY);
1458 if (FAILED(r))
1459 goto end;
1460
1462 for (i = 0; i < n; i++)
1463 {
1464 memset(&info, 0, sizeof(info));
1465 info.cbSize = sizeof info;
1467 info.dwTypeData = string;
1468 info.cch = sizeof string;
1469 string[0] = 0;
1471
1472 TRACE("menu %d %s %08x %08lx %08x %08x\n", i, debugstr_w(string),
1473 info.fState, info.dwItemData, info.fType, info.wID);
1474 if ((!sei->lpVerb && (info.fState & MFS_DEFAULT)) ||
1475 (sei->lpVerb && !lstrcmpiW(sei->lpVerb, string)))
1476 {
1477 def = i;
1478 break;
1479 }
1480 }
1481
1482 r = E_FAIL;
1483 if (def == -1)
1484 goto end;
1485
1486 memset(&ici, 0, sizeof ici);
1487 ici.cbSize = sizeof ici;
1488 ici.fMask = (sei->fMask & SEE_CMIC_COMMON_BASICFLAGS) | CMIC_MASK_UNICODE;
1489 ici.nShow = sei->nShow;
1490 ici.lpVerb = MAKEINTRESOURCEA(def);
1491 ici.hwnd = sei->hwnd;
1492 ici.lpParametersW = sei->lpParameters;
1493
1494 r = cm->InvokeCommand((LPCMINVOKECOMMANDINFO)&ici);
1495
1496 TRACE("invoke command returned %08x\n", r);
1497
1498end:
1499 if (hmenu)
1500 DestroyMenu( hmenu );
1501 return r;
1502}
#define E_FAIL
Definition: ddrawi.h:102
int WINAPI lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4262
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLdouble n
Definition: glext.h:7729
static HMENU hmenu
Definition: win.c:66
#define memset(x, y, z)
Definition: compat.h:39
#define MIIM_STRING
Definition: winuser.h:738
#define MIIM_ID
Definition: winuser.h:733
int WINAPI GetMenuItemCount(_In_opt_ HMENU)
HMENU WINAPI CreateMenu(void)
Definition: menu.c:829
#define MIIM_FTYPE
Definition: winuser.h:740
#define MIIM_STATE
Definition: winuser.h:732
#define MFS_DEFAULT
Definition: winuser.h:759
BOOL WINAPI GetMenuItemInfoW(_In_ HMENU, _In_ UINT, _In_ BOOL, _Inout_ LPMENUITEMINFOW)
#define MIIM_DATA
Definition: winuser.h:737

Referenced by shellex_load_object_and_run().

◆ ShellExec_RunDLL_Helper()

static VOID ShellExec_RunDLL_Helper ( _In_opt_ HWND  hwnd,
_In_opt_ HINSTANCE  hInstance,
_In_ PCWSTR  pszCmdLine,
_In_ INT  nCmdShow 
)
static

Definition at line 3112 of file shlexec.cpp.

3117{
3118 TRACE("(%p, %p, %s, 0x%X)\n", hwnd, hInstance, wine_dbgstr_w(pszCmdLine), nCmdShow);
3119
3120 if (!pszCmdLine || !*pszCmdLine)
3121 return;
3122
3123 // '?' enables us to specify the additional mask value
3124 ULONG fNewMask = SEE_MASK_NOASYNC;
3125 if (*pszCmdLine == L'?') // 1st question
3126 {
3127 INT MaskValue;
3128 if (StrToIntExW(pszCmdLine + 1, STIF_SUPPORT_HEX, &MaskValue))
3129 fNewMask |= MaskValue;
3130
3131 PCWSTR pch2ndQuestion = StrChrW(pszCmdLine + 1, L'?'); // 2nd question
3132 if (pch2ndQuestion)
3133 pszCmdLine = pch2ndQuestion + 1;
3134 }
3135
3136 WCHAR szPath[2 * MAX_PATH];
3138 if (PathProcessCommandW(pszCmdLine, szPath, _countof(szPath), dwFlags) == -1)
3139 StrCpyNW(szPath, pszCmdLine, _countof(szPath));
3140
3141 // Split arguments from the path
3143 if (*Args)
3144 *(Args - 1) = UNICODE_NULL;
3145
3147
3148 // Execute
3149 SHELLEXECUTEINFOW execInfo = { sizeof(execInfo) };
3150 execInfo.fMask = fNewMask;
3151 execInfo.hwnd = hwnd;
3152 execInfo.lpFile = szPath;
3153 execInfo.lpParameters = Args;
3154 execInfo.nShow = nCmdShow;
3155 if (!ShellExecuteExW(&execInfo))
3156 {
3157 DWORD dwError = GetLastError();
3158 if (SHELL_InRunDllProcess()) // Is it a RUNDLL process?
3159 ExitProcess(dwError); // Terminate it now
3160 }
3161}
char ** Args
Definition: acdebug.h:353
HINSTANCE hInstance
Definition: charmap.c:19
LPWSTR WINAPI StrChrW(LPCWSTR lpszStr, WCHAR ch)
Definition: string.c:464
VOID WINAPI ExitProcess(IN UINT uExitCode)
Definition: proc.c:1487
BOOL WINAPI StrToIntExW(LPCWSTR lpszStr, DWORD dwFlags, int *lpiRet)
Definition: string.c:970
LPWSTR WINAPI StrCpyNW(LPWSTR dst, LPCWSTR src, int count)
Definition: string.c:536
#define SEE_MASK_NOASYNC
Definition: shellapi.h:33
EXTERN_C LONG PathProcessCommandW(_In_ PCWSTR pszSrc, _Out_writes_opt_(dwBuffSize) PWSTR pszDest, _In_ INT cchDest, _In_ DWORD dwFlags)
Definition: shlexec.cpp:2996
static BOOL SHELL_InRunDllProcess(VOID)
Definition: shlexec.cpp:39
#define PPCF_INCLUDEARGS
Definition: shlobj.h:2425
#define STIF_SUPPORT_HEX
Definition: shlwapi.h:1487

Referenced by ShellExec_RunDLLA(), and ShellExec_RunDLLW().

◆ ShellExec_RunDLLA()

EXTERN_C VOID WINAPI ShellExec_RunDLLA ( _In_opt_ HWND  hwnd,
_In_opt_ HINSTANCE  hInstance,
_In_ PCSTR  pszCmdLine,
_In_ INT  nCmdShow 
)

Definition at line 3170 of file shlexec.cpp.

3175{
3176 CStringW strCmdLine = pszCmdLine; // Keep
3177 ShellExec_RunDLL_Helper(hwnd, hInstance, strCmdLine, nCmdShow);
3178}
static VOID ShellExec_RunDLL_Helper(_In_opt_ HWND hwnd, _In_opt_ HINSTANCE hInstance, _In_ PCWSTR pszCmdLine, _In_ INT nCmdShow)
Definition: shlexec.cpp:3112

Referenced by TEST_ShellExec_RunDLLA().

◆ ShellExec_RunDLLW()

EXTERN_C VOID WINAPI ShellExec_RunDLLW ( _In_opt_ HWND  hwnd,
_In_opt_ HINSTANCE  hInstance,
_In_ PCWSTR  pszCmdLine,
_In_ INT  nCmdShow 
)

Definition at line 3187 of file shlexec.cpp.

3192{
3193 ShellExec_RunDLL_Helper(hwnd, hInstance, pszCmdLine, nCmdShow);
3194}

Referenced by CTaskSwitchWnd::InvokeRegistryAppKeyCommand(), and TEST_ShellExec_RunDLLW().

◆ ShellExecCmdLine()

HRESULT WINAPI ShellExecCmdLine ( HWND  hwnd,
LPCWSTR  pwszCommand,
LPCWSTR  pwszStartDir,
int  nShow,
LPVOID  pUnused,
DWORD  dwSeclFlags 
)

Definition at line 2672 of file shlexec.cpp.

2679{
2682 LPCWSTR pszVerb = NULL;
2683 WCHAR szFile[MAX_PATH], szFile2[MAX_PATH];
2684 HRESULT hr;
2685 LPCWSTR pchParams;
2686 LPWSTR lpCommand = NULL;
2687
2688 if (pwszCommand == NULL)
2690 1, (ULONG_PTR*)pwszCommand);
2691
2692 __SHCloneStrW(&lpCommand, pwszCommand);
2693 StrTrimW(lpCommand, L" \t");
2694
2695 if (dwSeclFlags & SECL_NO_UI)
2697 if (dwSeclFlags & SECL_LOG_USAGE)
2699 if (dwSeclFlags & SECL_USE_IDLIST)
2701
2702 if (dwSeclFlags & SECL_RUNAS)
2703 {
2704 dwSize = 0;
2705 hr = AssocQueryStringW(ASSOCF_NONE, ASSOCSTR_COMMAND, lpCommand, L"RunAs", NULL, &dwSize);
2706 if (SUCCEEDED(hr) && dwSize != 0)
2707 {
2708 pszVerb = L"runas";
2709 }
2710 }
2711
2712 if (PathIsURLW(lpCommand) || UrlIsW(lpCommand, URLIS_APPLIABLE))
2713 {
2714 StringCchCopyW(szFile, _countof(szFile), lpCommand);
2715 pchParams = NULL;
2716 }
2717 else
2718 {
2719 PCWSTR apPathList[2];
2720
2721 pchParams = SplitParams(lpCommand, szFile, _countof(szFile));
2722 if (szFile[0] != UNICODE_NULL && szFile[1] == L':' &&
2723 szFile[2] == UNICODE_NULL)
2724 {
2725 PathAddBackslashW(szFile);
2726 }
2727
2728 WCHAR szCurDir[MAX_PATH];
2729 GetCurrentDirectoryW(_countof(szCurDir), szCurDir);
2730 if (pwszStartDir)
2731 {
2732 SetCurrentDirectoryW(pwszStartDir);
2733 }
2734
2735 if ((PathIsRelativeW(szFile) &&
2736 GetFullPathNameW(szFile, _countof(szFile2), szFile2, NULL) &&
2737 PathFileExistsW(szFile2)) ||
2738 SearchPathW(NULL, szFile, NULL, _countof(szFile2), szFile2, NULL))
2739 {
2740 StringCchCopyW(szFile, _countof(szFile), szFile2);
2741 }
2742
2743 apPathList[0] = pwszStartDir;
2744 apPathList[1] = NULL;
2745 PathFindOnPathExW(szFile, apPathList, WHICH_DEFAULT);
2746
2747 if (!(dwSeclFlags & SECL_ALLOW_NONEXE))
2748 {
2749 if (!GetBinaryTypeW(szFile, &dwType))
2750 {
2751 SHFree(lpCommand);
2752
2753 if (!(dwSeclFlags & SECL_NO_UI))
2754 {
2755 WCHAR szText[128 + MAX_PATH], szFormat[128];
2757 StringCchPrintfW(szText, _countof(szText), szFormat, szFile);
2758 MessageBoxW(hwnd, szText, NULL, MB_ICONERROR);
2759 }
2760 return CO_E_APPNOTFOUND;
2761 }
2762 }
2763 else
2764 {
2766 {
2767 SHFree(lpCommand);
2768
2769 if (!(dwSeclFlags & SECL_NO_UI))
2770 {
2771 WCHAR szText[128 + MAX_PATH], szFormat[128];
2773 StringCchPrintfW(szText, _countof(szText), szFormat, szFile);
2774 MessageBoxW(hwnd, szText, NULL, MB_ICONERROR);
2775 }
2777 }
2778 }
2779 }
2780
2781 ZeroMemory(&info, sizeof(info));
2782 info.cbSize = sizeof(info);
2783 info.fMask = dwFlags;
2784 info.hwnd = hwnd;
2785 info.lpVerb = pszVerb;
2786 info.lpFile = szFile;
2787 info.lpParameters = (pchParams && *pchParams) ? pchParams : NULL;
2788 info.lpDirectory = pwszStartDir;
2789 info.nShow = nShow;
2791 SHFree(lpCommand);
2792 return HRESULT_FROM_WIN32(error);
2793}
#define SECL_USE_IDLIST
#define SECL_LOG_USAGE
#define SECL_ALLOW_NONEXE
#define SECL_RUNAS
#define SECL_NO_UI
VOID WINAPI RaiseException(_In_ DWORD dwExceptionCode, _In_ DWORD dwExceptionFlags, _In_ DWORD nNumberOfArguments, _In_opt_ const ULONG_PTR *lpArguments)
Definition: except.c:700
BOOL WINAPI GetBinaryTypeW(LPCWSTR lpApplicationName, LPDWORD lpBinaryType)
Definition: vdm.c:1243
BOOL WINAPI PathFileExistsW(LPCWSTR lpszPath)
Definition: path.c:1783
BOOL WINAPI PathFindOnPathExW(LPWSTR lpszFile, LPCWSTR *lppszOtherDirs, DWORD dwWhich)
Definition: path.c:1357
BOOL WINAPI StrTrimW(LPWSTR lpszStr, LPCWSTR lpszTrim)
Definition: string.c:1883
BOOL WINAPI UrlIsW(LPCWSTR pszUrl, URLIS Urlis)
Definition: url.c:1933
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
#define SEE_MASK_FLAG_LOG_USAGE
Definition: shellapi.h:59
static LPCWSTR SplitParams(LPCWSTR psz, LPWSTR pszArg0, size_t cchArg0)
Definition: shlexec.cpp:2626
@ ASSOCSTR_COMMAND
Definition: shlwapi.h:612
@ URLIS_APPLIABLE
Definition: shlwapi.h:1230
#define WHICH_DEFAULT
#define IDS_FILE_NOT_FOUND
Definition: shresdef.h:365
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
#define EXCEPTION_NONCONTINUABLE
Definition: stubs.h:23
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define EXCEPTION_ACCESS_VIOLATION
Definition: winbase.h:338
#define CO_E_APPNOTFOUND
Definition: winerror.h:2808

◆ ShellExecute_ContextMenuVerb()

static HRESULT ShellExecute_ContextMenuVerb ( LPSHELLEXECUTEINFOW  sei)
static

Definition at line 1577 of file shlexec.cpp.

1578{
1579 TRACE("%p\n", sei);
1580
1581 CCoInit coInit;
1582
1583 if (FAILED_UNEXPECTEDLY(coInit.hr))
1584 return coInit.hr;
1585
1589 return hr;
1590
1591 CComHeapPtr<char> verb, parameters, dir;
1592 __SHCloneStrWtoA(&verb, sei->lpVerb);
1593 __SHCloneStrWtoA(&parameters, sei->lpParameters);
1595
1596 BOOL fDefault = StrIsNullOrEmpty(sei->lpVerb);
1597 CMINVOKECOMMANDINFOEX ici = { sizeof(ici) };
1598 ici.fMask = SeeFlagsToCmicFlags(sei->fMask) | CMIC_MASK_UNICODE;
1599 ici.nShow = sei->nShow;
1600 if (!fDefault)
1601 {
1602 ici.lpVerb = verb;
1603 ici.lpVerbW = sei->lpVerb;
1604 }
1605 ici.hwnd = sei->hwnd;
1606 ici.lpParameters = parameters;
1607 ici.lpParametersW = sei->lpParameters;
1608 ici.lpDirectory = dir;
1609 ici.lpDirectoryW = sei->lpDirectory;
1610 ici.dwHotKey = sei->dwHotKey;
1611 ici.hIcon = sei->hIcon;
1612 if (ici.fMask & (CMIC_MASK_HASLINKNAME | CMIC_MASK_HASTITLE))
1613 ici.lpTitleW = sei->lpClass;
1614
1615 enum { idFirst = 1, idLast = 0x7fff };
1616 HMENU hMenu = CreatePopupMenu();
1617 // Note: Windows does not pass CMF_EXTENDEDVERBS so "hidden" verbs cannot be executed
1618 hr = cm->QueryContextMenu(hMenu, 0, idFirst, idLast, fDefault ? CMF_DEFAULTONLY : 0);
1619 if (!FAILED_UNEXPECTEDLY(hr))
1620 {
1621 if (fDefault)
1622 {
1623 INT uDefault = GetMenuDefaultItem(hMenu, FALSE, 0);
1624 uDefault = (uDefault != -1) ? uDefault - idFirst : 0;
1625 ici.lpVerb = MAKEINTRESOURCEA(uDefault);
1626 ici.lpVerbW = MAKEINTRESOURCEW(uDefault);
1627 }
1628
1629 hr = cm->InvokeCommand((LPCMINVOKECOMMANDINFO)&ici);
1630 if (!FAILED_UNEXPECTEDLY(hr))
1631 hr = S_OK;
1632 }
1633
1634 DestroyMenu(hMenu);
1635
1636 return hr;
1637}
unsigned int dir
Definition: maze.c:112
static UINT SeeFlagsToCmicFlags(UINT flags)
Definition: precomp.h:191
static __inline void __SHCloneStrWtoA(char **target, const WCHAR *source)
Definition: shell32_main.h:172
static HRESULT shellex_get_contextmenu(LPSHELLEXECUTEINFOW sei, CComPtr< IContextMenu > &cm)
Definition: shlexec.cpp:1538
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582

Referenced by SHELL_execute().

◆ ShellExecute_FromContextMenuHandlers()

static LONG ShellExecute_FromContextMenuHandlers ( LPSHELLEXECUTEINFOW  sei)
static

Definition at line 1643 of file shlexec.cpp.

1644{
1645 HKEY hkey, hkeycm = 0;
1646 WCHAR szguid[39];
1647 HRESULT hr;
1648 GUID guid;
1649 DWORD i;
1650 LONG r;
1651
1652 TRACE("%s\n", debugstr_w(sei->lpFile));
1653
1654 hkey = ShellExecute_GetClassKey(sei);
1655 if (!hkey)
1656 return ERROR_FUNCTION_FAILED;
1657
1658 r = RegOpenKeyW(hkey, L"shellex\\ContextMenuHandlers", &hkeycm);
1659 if (r == ERROR_SUCCESS)
1660 {
1661 i = 0;
1662 while (1)
1663 {
1664 r = RegEnumKeyW(hkeycm, i++, szguid, ARRAY_SIZE(szguid));
1665 if (r != ERROR_SUCCESS)
1666 break;
1667
1668 hr = CLSIDFromString(szguid, &guid);
1669 if (SUCCEEDED(hr))
1670 {
1671 /* stop at the first one that succeeds in running */
1672 hr = shellex_load_object_and_run(hkey, &guid, sei);
1673 if (SUCCEEDED(hr))
1674 break;
1675 }
1676 }
1677 RegCloseKey(hkeycm);
1678 }
1679
1680 if (hkey != sei->hkeyClass)
1681 RegCloseKey(hkey);
1682 return r;
1683}
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3268
LONG WINAPI RegEnumKeyW(HKEY hKey, DWORD dwIndex, LPWSTR lpName, DWORD cbName)
Definition: reg.c:2393
HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id)
Definition: compobj.c:2338
static HRESULT shellex_load_object_and_run(HKEY hkey, LPCGUID guid, LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:1504
static HKEY ShellExecute_GetClassKey(const SHELLEXECUTEINFOW *sei)
Definition: shlexec.cpp:1364
#define ERROR_FUNCTION_FAILED
Definition: winerror.h:985

Referenced by SHELL_execute().

◆ ShellExecute_GetClassKey()

static HKEY ShellExecute_GetClassKey ( const SHELLEXECUTEINFOW sei)
static

Definition at line 1364 of file shlexec.cpp.

1365{
1366 LPCWSTR ext = NULL, lpClass = NULL;
1368 DWORD type = 0, sz = 0;
1369 HKEY hkey = 0;
1370 LONG r;
1371
1372 if (sei->fMask & SEE_MASK_CLASSALL)
1373 return sei->hkeyClass;
1374
1375 if (sei->fMask & SEE_MASK_CLASSNAME)
1376 lpClass = sei->lpClass;
1377 else
1378 {
1380 TRACE("ext = %s\n", debugstr_w(ext));
1381 if (!ext)
1382 return hkey;
1383
1385 if (r != ERROR_SUCCESS)
1386 return hkey;
1387
1388 r = RegQueryValueExW(hkey, NULL, 0, &type, NULL, &sz);
1389 if (r == ERROR_SUCCESS && type == REG_SZ)
1390 {
1391 sz += sizeof (WCHAR);
1392 cls.Allocate(sz / sizeof(WCHAR));
1393 cls[0] = 0;
1394 RegQueryValueExW(hkey, NULL, 0, &type, (LPBYTE)(LPWSTR)cls, &sz);
1395 }
1396
1397 RegCloseKey( hkey );
1398 lpClass = cls;
1399 }
1400
1401 TRACE("class = %s\n", debugstr_w(lpClass));
1402
1403 hkey = 0;
1404 if (lpClass)
1405 RegOpenKeyW( HKEY_CLASSES_ROOT, lpClass, &hkey);
1406
1407 return hkey;
1408}
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
static const WCHAR *const ext[]
Definition: module.c:53
LPWSTR WINAPI PathFindExtensionW(LPCWSTR lpszPath)
Definition: path.c:447
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545

Referenced by ShellExecute_FromContextMenuHandlers().

◆ ShellExecute_Normal()

static DWORD ShellExecute_Normal ( _Inout_ LPSHELLEXECUTEINFOW  sei)
static

Definition at line 2395 of file shlexec.cpp.

2396{
2397 // FIXME
2399}
static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
Definition: shlexec.cpp:1966
static UINT_PTR SHELL_ExecuteW(const WCHAR *lpCmd, WCHAR *env, BOOL shWait, const SHELLEXECUTEINFOW *psei, LPSHELLEXECUTEINFOW psei_out)
Definition: shlexec.cpp:475

Referenced by ShellExecuteExW().

◆ ShellExecute_ShowError()

static VOID ShellExecute_ShowError ( _In_ const SHELLEXECUTEINFOW ExecInfo,
_In_opt_ LPCWSTR  pszCaption,
_In_ DWORD  dwError 
)
static

Definition at line 2402 of file shlexec.cpp.

2406{
2407 // FIXME: Show error message
2408}

Referenced by ShellExecuteExW().

◆ ShellExecuteA()

HINSTANCE WINAPI ShellExecuteA ( HWND  hWnd,
LPCSTR  lpVerb,
LPCSTR  lpFile,
LPCSTR  lpParameters,
LPCSTR  lpDirectory,
INT  iShowCmd 
)

Definition at line 2365 of file shlexec.cpp.

2367{
2369
2370 TRACE("%p,%s,%s,%s,%s,%d\n",
2371 hWnd, debugstr_a(lpVerb), debugstr_a(lpFile),
2372 debugstr_a(lpParameters), debugstr_a(lpDirectory), iShowCmd);
2373
2374 sei.cbSize = sizeof(sei);
2376 sei.hwnd = hWnd;
2377 sei.lpVerb = lpVerb;
2378 sei.lpFile = lpFile;
2379 sei.lpParameters = lpParameters;
2381 sei.nShow = iShowCmd;
2382 sei.lpIDList = 0;
2383 sei.lpClass = 0;
2384 sei.hkeyClass = 0;
2385 sei.dwHotKey = 0;
2386 sei.hProcess = 0;
2387
2389 sei.fMask |= SEE_MASK_NOASYNC;
2390 ShellExecuteExA(&sei);
2391 return sei.hInstApp;
2392}
HWND hWnd
Definition: settings.c:17
DWORD WINAPI SHGetAppCompatFlags(DWORD dwUnknown)
Definition: ordinal.c:4565
#define SHACF_WIN95SHLEXEC

Referenced by FileProtocolHandlerA(), MACRO_ExecFile(), OpenURLA(), and shell_execute_().

◆ ShellExecuteExA()

Definition at line 2416 of file shlexec.cpp.

2417{
2418 SHELLEXECUTEINFOW seiW;
2419 BOOL ret;
2420 WCHAR *wVerb = NULL, *wFile = NULL, *wParameters = NULL, *wDirectory = NULL, *wClass = NULL;
2421
2422 TRACE("%p\n", sei);
2423
2424 if (sei->cbSize != sizeof(SHELLEXECUTEINFOA))
2425 {
2428 return FALSE;
2429 }
2430
2431 memcpy(&seiW, sei, sizeof(SHELLEXECUTEINFOW));
2432
2433 seiW.cbSize = sizeof(SHELLEXECUTEINFOW);
2434
2435 if (sei->lpVerb)
2436 seiW.lpVerb = __SHCloneStrAtoW(&wVerb, sei->lpVerb);
2437
2438 if (sei->lpFile)
2439 seiW.lpFile = __SHCloneStrAtoW(&wFile, sei->lpFile);
2440
2441 if (sei->lpParameters)
2442 seiW.lpParameters = __SHCloneStrAtoW(&wParameters, sei->lpParameters);
2443
2444 if (sei->lpDirectory)
2445 seiW.lpDirectory = __SHCloneStrAtoW(&wDirectory, sei->lpDirectory);
2446
2447 if ((sei->fMask & SEE_MASK_CLASSALL) == SEE_MASK_CLASSNAME && sei->lpClass)
2448 seiW.lpClass = __SHCloneStrAtoW(&wClass, sei->lpClass);
2449 else
2450 seiW.lpClass = NULL;
2451
2452 ret = ShellExecuteExW(&seiW);
2453
2454 sei->hInstApp = seiW.hInstApp;
2455
2456 if (sei->fMask & SEE_MASK_NOCLOSEPROCESS)
2457 sei->hProcess = seiW.hProcess;
2458
2459 SHFree(wVerb);
2460 SHFree(wFile);
2461 SHFree(wParameters);
2462 SHFree(wDirectory);
2463 SHFree(wClass);
2464
2465 return ret;
2466}
struct _SHELLEXECUTEINFOW SHELLEXECUTEINFOW

Referenced by RealShellExecuteExA(), shell_execute_ex_(), SHELL_ShowItemIDListProperties(), and ShellExecuteA().

◆ ShellExecuteExW()

Definition at line 2474 of file shlexec.cpp.

2475{
2476 HRESULT hrCoInit;
2477 DWORD dwError;
2478 ULONG fOldMask;
2479
2480 if (sei->cbSize != sizeof(SHELLEXECUTEINFOW))
2481 {
2484 return FALSE;
2485 }
2486
2487 hrCoInit = SHCoInitializeAnyApartment();
2488
2489 if (SHRegGetBoolUSValueW(L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer",
2490 L"MaximizeApps", FALSE, FALSE))
2491 {
2492 switch (sei->nShow)
2493 {
2494 case SW_SHOW:
2495 case SW_SHOWDEFAULT:
2496 case SW_SHOWNORMAL:
2497 case SW_RESTORE:
2498 sei->nShow = SW_SHOWMAXIMIZED;
2499 break;
2500 default:
2501 break;
2502 }
2503 }
2504
2505 fOldMask = sei->fMask;
2506
2507 if (!(fOldMask & SEE_MASK_NOASYNC) && SHELL_InRunDllProcess())
2509
2510 dwError = ShellExecute_Normal(sei);
2511
2512 if (dwError && dwError != ERROR_DLL_NOT_FOUND && dwError != ERROR_CANCELLED)
2513 ShellExecute_ShowError(sei, NULL, dwError);
2514
2515 sei->fMask = fOldMask;
2516
2517 if (SUCCEEDED(hrCoInit))
2519
2520 if (dwError)
2521 SetLastError(dwError);
2522
2523 return dwError == ERROR_SUCCESS;
2524}
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
HRESULT SHCoInitializeAnyApartment(VOID)
Definition: utils.cpp:471
BOOL WINAPI SHRegGetBoolUSValueW(LPCWSTR pszSubKey, LPCWSTR pszValue, BOOL fIgnoreHKCU, BOOL fDefault)
Definition: reg.c:770
#define SE_ERR_ACCESSDENIED
Definition: shellapi.h:128
#define SEE_MASK_WAITFORINPUTIDLE
Definition: shellapi.h:58
static DWORD ShellExecute_Normal(_Inout_ LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:2395
static VOID ShellExecute_ShowError(_In_ const SHELLEXECUTEINFOW *ExecInfo, _In_opt_ LPCWSTR pszCaption, _In_ DWORD dwError)
Definition: shlexec.cpp:2402
#define ERROR_DLL_NOT_FOUND
Definition: winerror.h:679
#define ERROR_CANCELLED
Definition: winerror.h:726
#define SW_SHOWNORMAL
Definition: winuser.h:781
#define SW_SHOWMAXIMIZED
Definition: winuser.h:784
#define SW_SHOWDEFAULT
Definition: winuser.h:791
#define SW_RESTORE
Definition: winuser.h:790
#define SW_SHOW
Definition: winuser.h:786

Referenced by AutoStartupApplications(), BtrfsVolPropSheet::DeviceDlgProc(), CShellLink::DoOpen(), RunOnceExEntry::Exec(), COpenWithList::Execute(), CAddressEditBox::ExecuteCommandLine(), ExtractAndInstallThread(), HlinkSimpleNavigateToString(), BtrfsContextMenu::InvokeCommand(), CISFBand::InvokeCommand(), CDefaultContextMenu::InvokePidl(), LanguagesPageProc(), COpenControlPanel::Open(), BtrfsPropSheet::open_as_admin(), BtrfsBalance::PauseBalance(), CDownloadManager::PerformDownloadAndInstall(), ProcessPage_OnProperties(), RealShellExecuteExW(), BtrfsVolPropSheet::ResetStats(), RunDlgProc(), RunFontViewer(), SHELL_OpenFolder(), ShellExec_RunDLL_Helper(), ShellExecCmdLine(), ShellExecuteCommand(), ShellExecuteExA(), ShellExecuteExWrapW(), ShellExecuteVerb(), ShellExecuteW(), SHObjectProperties(), SHOpenFolderAndSelectItems(), BtrfsVolPropSheet::ShowChangeDriveLetter(), CRecycleBinCleaner::ShowProperties(), BtrfsVolPropSheet::ShowScrub(), BtrfsBalance::StartBalance(), BtrfsBalance::StopBalance(), test_DoInvalidDir(), TEST_DoTestEntryStruct(), test_properties(), test_sei_lpIDList(), try_application_url(), UniformResourceLocatorW_InvokeCommand(), wmain(), and WshShell3_Run().

◆ ShellExecuteW()

HINSTANCE WINAPI ShellExecuteW ( HWND  hwnd,
LPCWSTR  lpVerb,
LPCWSTR  lpFile,
LPCWSTR  lpParameters,
LPCWSTR  lpDirectory,
INT  nShowCmd 
)

Definition at line 2529 of file shlexec.cpp.

2531{
2533
2534 TRACE("\n");
2535 sei.cbSize = sizeof(sei);
2537 sei.hwnd = hwnd;
2538 sei.lpVerb = lpVerb;
2539 sei.lpFile = lpFile;
2540 sei.lpParameters = lpParameters;
2542 sei.nShow = nShowCmd;
2543 sei.lpIDList = 0;
2544 sei.lpClass = 0;
2545 sei.hkeyClass = 0;
2546 sei.dwHotKey = 0;
2547 sei.hProcess = 0;
2548
2550 sei.fMask |= SEE_MASK_NOASYNC;
2551 ShellExecuteExW(&sei);
2552 return sei.hInstApp;
2553}

Referenced by _RunVolume(), Control_StartApplet(), CPlApplet(), DIALOG_EXECUTE_DlgProc(), dialog_hyperlink_handler(), DisplayApplet(), CShellLink::DoOpenFileLocation(), CExeDropHandler::Drop(), CTrayWindow::ExecContextMenuCmd(), CTrayWindow::ExecResourceCmd(), CDrvDefExt::ExtraPageProc(), GeneralPageProc(), CDrvDefExt::GeneralPageProc(), CTrayWindow::HandleCommand(), CTrayWindow::HandleHotKey(), IHlink_fnNavigate(), CCPLItemMenu::InvokeCommand(), LanguagesPageProc(), LANStatusDlg(), LaunchDeviceManager(), LaunchSoundControl(), MainWnd_OnOpenRegKey(), OnAddStartMenuItems(), OnAdvancedStartMenuItems(), CAppInfoDisplay::OnCommand(), CShellMenuCallback::OnExec(), CTrayClockWnd::OnLButtonDblClick(), OnLink(), OnNotify(), OnRemoveStartmenuItems(), CZipExtract::CCompleteSettingsPage::OnWizardFinish(), OpenShellFolder(), ProcessPage_OnOpenFileLocation(), PROGRAM_ExecuteProgram(), RouteTheCallW(), RunCommand(), CSysTray::RunDll(), SHELL_execute(), CShellDispatch::ShellExecute(), SHFindFiles(), SHRunControlPanel(), START_TEST(), StartRecDlgProc(), and TEST_Init().

◆ SplitParams()

static LPCWSTR SplitParams ( LPCWSTR  psz,
LPWSTR  pszArg0,
size_t  cchArg0 
)
static

Definition at line 2626 of file shlexec.cpp.

2627{
2628 LPCWSTR pch;
2629 size_t ich = 0;
2630 if (*psz == L'"')
2631 {
2632 // 1st argument is quoted. the string in quotes is quoted 1st argument.
2633 // [pch] --> [pszArg0+ich]
2634 for (pch = psz + 1; *pch && ich + 1 < cchArg0; ++ich, ++pch)
2635 {
2636 if (*pch == L'"' && pch[1] == L'"')
2637 {
2638 // doubled double quotations found!
2639 pszArg0[ich] = L'"';
2640 }
2641 else if (*pch == L'"')
2642 {
2643 // single double quotation found!
2644 ++pch;
2645 break;
2646 }
2647 else
2648 {
2649 // otherwise
2650 pszArg0[ich] = *pch;
2651 }
2652 }
2653 }
2654 else
2655 {
2656 // 1st argument is unquoted. non-space sequence is 1st argument.
2657 // [pch] --> [pszArg0+ich]
2658 for (pch = psz; *pch && !iswspace(*pch) && ich + 1 < cchArg0; ++ich, ++pch)
2659 {
2660 pszArg0[ich] = *pch;
2661 }
2662 }
2663 pszArg0[ich] = 0;
2664
2665 // skip space
2666 while (iswspace(*pch))
2667 ++pch;
2668
2669 return pch;
2670}
#define iswspace(_c)
Definition: ctype.h:669

Referenced by ShellExecCmdLine().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( exec  )

◆ WOWShellExecute()

EXTERN_C HINSTANCE WINAPI WOWShellExecute ( HWND  hWnd,
LPCSTR  lpVerb,
LPCSTR  lpFile,
LPCSTR  lpParameters,
LPCSTR  lpDirectory,
INT  iShowCmd,
void callback 
)

Definition at line 2560 of file shlexec.cpp.

2562{
2563 SHELLEXECUTEINFOW seiW;
2564 WCHAR *wVerb = NULL, *wFile = NULL, *wParameters = NULL, *wDirectory = NULL;
2565 HANDLE hProcess = 0;
2566
2567 seiW.lpVerb = lpVerb ? __SHCloneStrAtoW(&wVerb, lpVerb) : NULL;
2568 seiW.lpFile = lpFile ? __SHCloneStrAtoW(&wFile, lpFile) : NULL;
2569 seiW.lpParameters = lpParameters ? __SHCloneStrAtoW(&wParameters, lpParameters) : NULL;
2570 seiW.lpDirectory = lpDirectory ? __SHCloneStrAtoW(&wDirectory, lpDirectory) : NULL;
2571
2572 seiW.cbSize = sizeof(seiW);
2573 seiW.fMask = 0;
2574 seiW.hwnd = hWnd;
2575 seiW.nShow = iShowCmd;
2576 seiW.lpIDList = 0;
2577 seiW.lpClass = 0;
2578 seiW.hkeyClass = 0;
2579 seiW.dwHotKey = 0;
2580 seiW.hProcess = hProcess;
2581
2583
2584 SHFree(wVerb);
2585 SHFree(wFile);
2586 SHFree(wParameters);
2587 SHFree(wDirectory);
2588 return seiW.hInstApp;
2589}
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:71
static IPrintDialogCallback callback
Definition: printdlg.c:326
UINT_PTR(* SHELL_ExecuteW32)(const WCHAR *lpCmd, WCHAR *env, BOOL shWait, const SHELLEXECUTEINFOW *sei, LPSHELLEXECUTEINFOW sei_out)
Definition: shlexec.cpp:35