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

Go to the source code of this file.

Macros

#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 int Win32ErrFromHInst (HINSTANCE hInst)
 
static BOOL SHELL_InRunDllProcess (VOID)
 
static UINT_PTR InvokeOpenWith (HWND hWndOwner, SHELLEXECUTEINFOW &sei)
 
static HRESULT InvokeShellExecuteHook (PCWSTR pszClsid, LPSHELLEXECUTEINFOW pSEI)
 
static HRESULT TryShellExecuteHooks (LPSHELLEXECUTEINFOW pSEI)
 
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 wszKeyname, 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, PCWSTR 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 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 33 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 1081 of file shlexec.cpp.

1084{
1085 TRACE("dde_cb: %04x, %04x, %p, %p, %p, %p, %08lx, %08lx\n",
1086 uType, uFmt, hConv, hsz1, hsz2, hData, dwData1, dwData2);
1087 return NULL;
1088}
#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 1099 of file shlexec.cpp.

1103{
1104 WCHAR regkey[256];
1105 WCHAR * endkey = regkey + wcslen(key);
1106 WCHAR app[256], topic[256], ifexec[256], static_res[256];
1108 WCHAR * res;
1109 LONG applen, topiclen, ifexeclen;
1110 WCHAR * exec;
1111 DWORD ddeInst = 0;
1112 DWORD tid;
1113 DWORD resultLen, endkeyLen;
1114 HSZ hszApp, hszTopic;
1115 HCONV hConv;
1116 HDDEDATA hDdeData;
1117 unsigned ret = SE_ERR_NOASSOC;
1118 BOOL unicode = !(GetVersion() & 0x80000000);
1119
1120 if (strlenW(key) + 1 > ARRAY_SIZE(regkey))
1121 {
1122 FIXME("input parameter %s larger than buffer\n", debugstr_w(key));
1123 return 2;
1124 }
1125 wcscpy(regkey, key);
1126 endkeyLen = ARRAY_SIZE(regkey) - (endkey - regkey);
1127 if (strlenW(L"\\application") + 1 > endkeyLen)
1128 {
1129 FIXME("endkey %s overruns buffer\n", debugstr_w(L"\\application"));
1130 return 2;
1131 }
1132 wcscpy(endkey, L"\\application");
1133 applen = sizeof(app);
1134 if (RegQueryValueW(HKEY_CLASSES_ROOT, regkey, app, &applen) != ERROR_SUCCESS)
1135 {
1136 WCHAR command[1024], fullpath[MAX_PATH];
1137 LPWSTR ptr = NULL;
1138 DWORD ret = 0;
1139
1140 /* Get application command from start string and find filename of application */
1141 if (*start == '"')
1142 {
1143 if (strlenW(start + 1) + 1 > ARRAY_SIZE(command))
1144 {
1145 FIXME("size of input parameter %s larger than buffer\n",
1146 debugstr_w(start + 1));
1147 return 2;
1148 }
1149 wcscpy(command, start + 1);
1150 if ((ptr = wcschr(command, '"')))
1151 * ptr = 0;
1152 ret = SearchPathW(NULL, command, L".exe", ARRAY_SIZE(fullpath), fullpath, &ptr);
1153 }
1154 else
1155 {
1156 LPCWSTR p;
1157 LPWSTR space;
1158 for (p = start; (space = const_cast<LPWSTR>(strchrW(p, ' '))); p = space + 1)
1159 {
1160 int idx = space - start;
1161 memcpy(command, start, idx * sizeof(WCHAR));
1162 command[idx] = '\0';
1163 if ((ret = SearchPathW(NULL, command, L".exe", ARRAY_SIZE(fullpath), fullpath, &ptr)))
1164 break;
1165 }
1166 if (!ret)
1167 ret = SearchPathW(NULL, start, L".exe", ARRAY_SIZE(fullpath), fullpath, &ptr);
1168 }
1169
1170 if (!ret)
1171 {
1172 ERR("Unable to find application path for command %s\n", debugstr_w(start));
1173 return ERROR_ACCESS_DENIED;
1174 }
1175 if (strlenW(ptr) + 1 > ARRAY_SIZE(app))
1176 {
1177 FIXME("size of found path %s larger than buffer\n", debugstr_w(ptr));
1178 return 2;
1179 }
1180 wcscpy(app, ptr);
1181
1182 /* Remove extensions (including .so) */
1183 ptr = app + wcslen(app) - 3;
1184 if (ptr > app && !wcscmp(ptr, L".so"))
1185 *ptr = 0;
1186
1187 ptr = const_cast<LPWSTR>(strrchrW(app, '.'));
1188 assert(ptr);
1189 *ptr = 0;
1190 }
1191
1192 if (strlenW(L"\\topic") + 1 > endkeyLen)
1193 {
1194 FIXME("endkey %s overruns buffer\n", debugstr_w(L"\\topic"));
1195 return 2;
1196 }
1197 wcscpy(endkey, L"\\topic");
1198 topiclen = sizeof(topic);
1199 if (RegQueryValueW(HKEY_CLASSES_ROOT, regkey, topic, &topiclen) != ERROR_SUCCESS)
1200 {
1201 wcscpy(topic, L"System");
1202 }
1203
1204 if (unicode)
1205 {
1207 return 2;
1208 }
1209 else
1210 {
1212 return 2;
1213 }
1214
1217
1218 hConv = DdeConnect(ddeInst, hszApp, hszTopic, NULL);
1219 exec = ddeexec;
1220 if (!hConv)
1221 {
1222 TRACE("Launching %s\n", debugstr_w(start));
1223 ret = execfunc(start, env, TRUE, psei, psei_out);
1224 if (ret <= 32)
1225 {
1226 TRACE("Couldn't launch\n");
1227 goto error;
1228 }
1229 /* if ddeexec is NULL, then we just need to exit here */
1230 if (ddeexec == NULL)
1231 {
1232 TRACE("Exiting because ddeexec is NULL. ret=42.\n");
1233 /* See https://docs.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shellexecutew */
1234 /* for reason why we use 42 here and also "Shell32_apitest ShellExecuteW" regression test */
1235 return 42;
1236 }
1237 /* if ddeexec is 'empty string', then we just need to exit here */
1238 if (wcscmp(ddeexec, L"") == 0)
1239 {
1240 TRACE("Exiting because ddeexec is 'empty string'. ret=42.\n");
1241 /* See https://docs.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shellexecutew */
1242 /* for reason why we use 42 here and also "Shell32_apitest ShellExecuteW" regression test */
1243 return 42;
1244 }
1245 hConv = DdeConnect(ddeInst, hszApp, hszTopic, NULL);
1246 if (!hConv)
1247 {
1248 TRACE("Couldn't connect. ret=%d\n", ret);
1251 return 30; /* whatever */
1252 }
1253 if (strlenW(L"\\ifexec") + 1 > endkeyLen)
1254 {
1255 FIXME("endkey %s overruns buffer\n", debugstr_w(L"\\ifexec"));
1256 return 2;
1257 }
1258 strcpyW(endkey, L"\\ifexec");
1259 ifexeclen = sizeof(ifexec);
1260 if (RegQueryValueW(HKEY_CLASSES_ROOT, regkey, ifexec, &ifexeclen) == ERROR_SUCCESS)
1261 {
1262 exec = ifexec;
1263 }
1264 }
1265
1266 SHELL_ArgifyW(static_res, ARRAY_SIZE(static_res), exec, lpFile, pidl, szCommandline, &resultLen, NULL);
1267 if (resultLen > ARRAY_SIZE(static_res))
1268 {
1269 dynamic_res.Allocate(resultLen);
1270 res = dynamic_res;
1271 SHELL_ArgifyW(dynamic_res, resultLen, exec, lpFile, pidl, szCommandline, NULL, NULL);
1272 }
1273 else
1274 res = static_res;
1275 TRACE("%s %s => %s\n", debugstr_w(exec), debugstr_w(lpFile), debugstr_w(res));
1276
1277 /* It's documented in the KB 330337 that IE has a bug and returns
1278 * error DMLERR_NOTPROCESSED on XTYP_EXECUTE request.
1279 */
1280 if (unicode)
1281 hDdeData = DdeClientTransaction((LPBYTE)res, (strlenW(res) + 1) * sizeof(WCHAR), hConv, 0L, 0, XTYP_EXECUTE, 30000, &tid);
1282 else
1283 {
1284 DWORD lenA = WideCharToMultiByte(CP_ACP, 0, res, -1, NULL, 0, NULL, NULL);
1286 resA.Allocate(lenA);
1287 WideCharToMultiByte(CP_ACP, 0, res, -1, resA, lenA, NULL, NULL);
1288 hDdeData = DdeClientTransaction( (LPBYTE)(LPSTR)resA, lenA, hConv, 0L, 0,
1289 XTYP_EXECUTE, 10000, &tid );
1290 }
1291 if (hDdeData)
1292 DdeFreeDataHandle(hDdeData);
1293 else
1294 WARN("DdeClientTransaction failed with error %04x\n", DdeGetLastError(ddeInst));
1295 ret = 33;
1296
1297 DdeDisconnect(hConv);
1298
1299error:
1301
1302 return ret;
1303}
#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
DWORD WINAPI GetVersion(void)
Definition: version.c:1458
#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
_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:135
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:1081
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:299
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,
PCWSTR  filename 
)
static

Definition at line 1996 of file shlexec.cpp.

1997{
1998 WCHAR msg[2048];
1999 DWORD_PTR msgArguments[3] = { (DWORD_PTR)filename, 0, 0 };
2000 const DWORD error_code = GetLastError();
2001
2002 if (retval == SE_ERR_NOASSOC)
2004 else
2006 NULL,
2007 error_code,
2009 msg,
2010 ARRAY_SIZE(msg),
2011 (va_list*)msgArguments);
2012
2014 SetLastError(error_code); // Restore
2015}
#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
INT WINAPI DECLSPEC_HOTPATCH LoadStringW(HINSTANCE instance, UINT resource_id, LPWSTR buffer, INT buflen)
Definition: string.c:1220
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:456
#define FORMAT_MESSAGE_ARGUMENT_ARRAY
Definition: winbase.h:457
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
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 1308 of file shlexec.cpp.

1312{
1313 WCHAR cmd[256], param[1024], ddeexec[256];
1314 DWORD cmdlen = sizeof(cmd), ddeexeclen = sizeof(ddeexec);
1316 DWORD resultLen;
1317 LPWSTR tmp;
1318
1319 TRACE("%s %s %s %s %s\n", debugstr_w(key), debugstr_w(lpFile), debugstr_w(env),
1320 debugstr_w(szCommandline), debugstr_w(executable_name));
1321
1322 cmd[0] = '\0';
1323 param[0] = '\0';
1324
1325 /* Get the application from the registry */
1327 {
1328 TRACE("got cmd: %s\n", debugstr_w(cmd));
1329
1330 /* Is there a replace() function anywhere? */
1331 cmdlen /= sizeof(WCHAR);
1332 if (cmdlen >= ARRAY_SIZE(cmd))
1333 cmdlen = ARRAY_SIZE(cmd) - 1;
1334 cmd[cmdlen] = '\0';
1335 SHELL_ArgifyW(param, ARRAY_SIZE(param), cmd, lpFile, (LPITEMIDLIST)psei->lpIDList, szCommandline, &resultLen,
1336 (psei->lpDirectory && *psei->lpDirectory) ? psei->lpDirectory : NULL);
1337 if (resultLen > ARRAY_SIZE(param))
1338 ERR("Argify buffer not large enough, truncating\n");
1339 }
1340
1341 /* Get the parameters needed by the application
1342 from the associated ddeexec key */
1343 tmp = const_cast<LPWSTR>(strstrW(key, L"command"));
1344 assert(tmp);
1345 wcscpy(tmp, L"ddeexec");
1346
1347 if (RegQueryValueW(HKEY_CLASSES_ROOT, key, ddeexec, (LONG *)&ddeexeclen) == ERROR_SUCCESS)
1348 {
1349 TRACE("Got ddeexec %s => %s\n", debugstr_w(key), debugstr_w(ddeexec));
1350 if (!param[0]) strcpyW(param, executable_name);
1351 retval = dde_connect(key, param, ddeexec, lpFile, env, szCommandline, (LPITEMIDLIST)psei->lpIDList, execfunc, psei, psei_out);
1352 }
1353 else if (param[0])
1354 {
1355 TRACE("executing: %s\n", debugstr_w(param));
1356 retval = execfunc(param, env, FALSE, psei, psei_out);
1357 }
1358 else
1359 WARN("Nothing appropriate found for %s\n", debugstr_w(key));
1360
1361 return retval;
1362}
#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:1099
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
LPCWSTR lpDirectory
Definition: shellapi.h:340
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 2017 of file shlexec.cpp.

2018{
2020 DWORD len;
2021
2023 if (!len) return NULL;
2024
2025 if (!buf.Allocate(len))
2026 return NULL;
2027
2029 if (!len)
2030 return NULL;
2031
2032 return buf.Detach();
2033}
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 1367 of file shlexec.cpp.

1368{
1370 WCHAR *wFile = NULL, *wDirectory = NULL;
1371 WCHAR wResult[MAX_PATH];
1372
1373 if (lpFile) __SHCloneStrAtoW(&wFile, lpFile);
1374 if (lpDirectory) __SHCloneStrAtoW(&wDirectory, lpDirectory);
1375
1376 retval = FindExecutableW(wFile, wDirectory, wResult);
1377 WideCharToMultiByte(CP_ACP, 0, wResult, -1, lpResult, MAX_PATH, NULL, NULL);
1378 SHFree(wFile);
1379 SHFree(wDirectory);
1380
1381 TRACE("returning %s\n", lpResult);
1382 return retval;
1383}
void WINAPI SHFree(LPVOID pv)
Definition: shellole.c:337
static __inline LPWSTR __SHCloneStrAtoW(WCHAR **target, const char *source)
Definition: shell32_main.h:189
_In_opt_ LPCSTR lpDirectory
Definition: shellapi.h:496
HINSTANCE WINAPI FindExecutableW(LPCWSTR lpFile, LPCWSTR lpDirectory, LPWSTR lpResult)
Definition: shlexec.cpp:1410

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

◆ FindExecutableW()

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

Definition at line 1410 of file shlexec.cpp.

1411{
1413 WCHAR old_dir[MAX_PATH], res[MAX_PATH];
1414 DWORD cch = _countof(res);
1415 LPCWSTR dirs[2];
1416
1417 TRACE("File %s, Dir %s\n", debugstr_w(lpFile), debugstr_w(lpDirectory));
1418
1419 *lpResult = UNICODE_NULL;
1420
1421 GetCurrentDirectoryW(_countof(old_dir), old_dir);
1422
1423 if (lpDirectory && *lpDirectory)
1424 {
1426 dirs[0] = lpDirectory;
1427 }
1428 else
1429 {
1430 dirs[0] = old_dir;
1431 }
1432 dirs[1] = NULL;
1433
1434 if (!GetShortPathNameW(lpFile, res, _countof(res)))
1435 StringCchCopyW(res, _countof(res), lpFile);
1436
1438 {
1439 // NOTE: The last parameter of this AssocQueryStringW call is "strange" in Windows.
1440 if (PathIsExeW(res) ||
1442 {
1443 StringCchCopyW(lpResult, MAX_PATH, res);
1444 retval = 42;
1445 }
1446 else
1447 {
1449 }
1450 }
1451 else
1452 {
1454 }
1455
1456 TRACE("returning %s\n", debugstr_w(lpResult));
1457 SetCurrentDirectoryW(old_dir);
1458 return (HINSTANCE)retval;
1459}
#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:441
#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:125
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().

◆ InvokeOpenWith()

static UINT_PTR InvokeOpenWith ( HWND  hWndOwner,
SHELLEXECUTEINFOW sei 
)
static

Definition at line 86 of file shlexec.cpp.

87{
88 extern HRESULT SH32_InvokeOpenWith(PCWSTR, LPCMINVOKECOMMANDINFO, HANDLE *);
89
90 HANDLE *phProc = (sei.fMask & SEE_MASK_NOCLOSEPROCESS) ? &sei.hProcess : NULL;
91 UINT fCmic = (sei.fMask & SEE_CMIC_COMMON_BASICFLAGS) | CMIC_MASK_FLAG_NO_UI;
92 CMINVOKECOMMANDINFO ici = { sizeof(ici), fCmic, hWndOwner };
93 ici.nShow = SW_SHOW;
94 HRESULT hr = SH32_InvokeOpenWith(sei.lpFile, &ici, phProc);
96 return SUCCEEDED(hr) ? 42 : SE_ERR_NOASSOC;
97}
HRESULT SH32_InvokeOpenWith(_In_ PCWSTR pszPath, _In_ LPCMINVOKECOMMANDINFO pici, _Out_ HANDLE *phProcess)
unsigned int UINT
Definition: ndis.h:50
#define SEE_MASK_NOCLOSEPROCESS
Definition: shellapi.h:33
HRESULT hr
Definition: shlfolder.c:183
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define ERROR_NO_ASSOCIATION
Definition: winerror.h:677
#define SW_SHOW
Definition: winuser.h:786

Referenced by SHELL_execute().

◆ InvokeShellExecuteHook()

static HRESULT InvokeShellExecuteHook ( PCWSTR  pszClsid,
LPSHELLEXECUTEINFOW  pSEI 
)
static

Definition at line 99 of file shlexec.cpp.

100{
103 return S_FALSE;
106 return pWide->Execute(pSEI);
108#if 0 // TODO
111 {
113 // TODO: Convert the strings
114 hr = pAnsi->Execute(sei);
115 pSEI->hProcess = sei.hProcess;
116 pSEI->hInstApp = sei.hInstApp;
117 }
118#endif
119 return hr;
120}
HRESULT WINAPI SHExtCoCreateInstance(_In_opt_ LPCWSTR aclsid, _In_opt_ const CLSID *clsid, _In_opt_ LPUNKNOWN pUnkOuter, _In_ REFIID refiid, _Out_ LPVOID *ppv)
Definition: shellole.c:196
static void *static void *static LPDIRECTPLAY IUnknown * pUnk
Definition: dplayx.c:30
nsresult QueryInterface(nsIIDRef riid, void **result)
#define FAILED(hr)
Definition: intsafe.h:51
HINSTANCE hInstApp
Definition: shellapi.h:319
HINSTANCE hInstApp
Definition: shellapi.h:342
#define S_FALSE
Definition: winerror.h:2357
#define IID_PPV_ARG(Itype, ppType)

Referenced by TryShellExecuteHooks().

◆ OpenAs_RunDLLA()

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

Definition at line 2684 of file shlexec.cpp.

2685{
2686 LPWSTR pszCmdLineW = NULL;
2687 TRACE("%p, %p, %s, %d\n", hwnd, hinst, debugstr_a(cmdline), cmdshow);
2688
2689 if (cmdline)
2690 __SHCloneStrAtoW(&pszCmdLineW, cmdline);
2691 OpenAs_RunDLLW(hwnd, hinst, pszCmdLineW, cmdshow);
2692 SHFree(pszCmdLineW);
2693}
#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:2673
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 2673 of file shlexec.cpp.

2674{
2676 TRACE("%p, %p, %s, %d\n", hwnd, hinst, debugstr_w(cmdline), cmdshow);
2678}
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

Referenced by OpenAs_RunDLLA().

◆ ParseNoTildeEffect()

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

Definition at line 150 of file shlexec.cpp.

151{
152 bool firstCharQuote = false;
153 bool quotes_opened = false;
154 bool backslash_encountered = false;
155
156 for (int curArg = 0; curArg <= argNum && *args; ++curArg)
157 {
158 firstCharQuote = false;
159 if (*args == '"')
160 {
161 quotes_opened = true;
162 firstCharQuote = true;
163 args++;
164 }
165
166 while(*args)
167 {
168 if (*args == '\\')
169 {
170 // if we found a backslash then flip the variable
171 backslash_encountered = !backslash_encountered;
172 }
173 else if (*args == '"')
174 {
175 if (quotes_opened)
176 {
177 if (*(args + 1) != '"')
178 {
179 quotes_opened = false;
180 args++;
181 break;
182 }
183 else
184 {
185 args++;
186 }
187 }
188 else
189 {
190 quotes_opened = true;
191 }
192
193 backslash_encountered = false;
194 }
195 else
196 {
197 backslash_encountered = false;
198 if (*args == ' ' && !firstCharQuote)
199 break;
200 }
201
202 if (curArg == argNum)
203 {
204 used++;
205 if (used < len)
206 *res++ = *args;
207 }
208
209 args++;
210 }
211
212 while(*args == ' ')
213 ++args;
214 }
215}
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 217 of file shlexec.cpp.

218{
219 bool quotes_opened = false;
220 bool backslash_encountered = false;
221
222 for (int curArg = 0; curArg <= argNum && *args; ++curArg)
223 {
224 while(*args)
225 {
226 if (*args == '\\')
227 {
228 // if we found a backslash then flip the variable
229 backslash_encountered = !backslash_encountered;
230 }
231 else if (*args == '"')
232 {
233 if (quotes_opened)
234 {
235 if (*(args + 1) != '"')
236 {
237 quotes_opened = false;
238 }
239 else
240 {
241 args++;
242 }
243 }
244 else
245 {
246 quotes_opened = true;
247 }
248
249 backslash_encountered = false;
250 }
251 else
252 {
253 backslash_encountered = false;
254 if (*args == ' ' && !quotes_opened && curArg != argNum)
255 break;
256 }
257
258 if (curArg == argNum)
259 {
260 used++;
261 if (used < len)
262 *res++ = *args;
263 }
264
265 args++;
266 }
267 }
268}

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 3068 of file shlexec.cpp.

3073{
3074 TRACE("%s, %p, %d, 0x%X\n", wine_dbgstr_w(pszSrc), pszDest, cchDest, dwFlags);
3075
3076 if (!pszSrc)
3077 return -1;
3078
3080 PCWSTR pchArg = NULL;
3081
3082 if (*pszSrc == L'"') // Quoted?
3083 {
3084 ++pszSrc;
3085
3086 PCWSTR pch = wcschr(pszSrc, L'"');
3087 if (pch)
3088 {
3089 szPath.SetString(pszSrc, pch - pszSrc);
3090 pchArg = pch + 1;
3091 }
3092 else
3093 {
3094 szPath = pszSrc;
3095 }
3096
3098 {
3100 szPath.ReleaseBuffer();
3101 if (!ret)
3102 return -1;
3103 }
3104 }
3105 else // Not quoted?
3106 {
3107 BOOL resolved = FALSE;
3108 BOOL resolveRelative = PathIsRelativeW(pszSrc) || (dwFlags & PPCF_FORCEQUALIFY);
3109 INT cchPath = 0;
3110
3111 for (INT ich = 0; ; ++ich)
3112 {
3113 szPath += pszSrc[ich];
3114
3115 if (pszSrc[ich] && pszSrc[ich] != L' ')
3116 continue;
3117
3118 szPath = szPath.Left(ich);
3119
3120 if (resolveRelative &&
3122 {
3123 szPath.ReleaseBuffer();
3124 szPath += pszSrc[ich];
3125 }
3126 else
3127 {
3128 szPath.ReleaseBuffer();
3129
3131 if (attrs != INVALID_FILE_ATTRIBUTES &&
3133 {
3134 resolved = TRUE;
3135 pchArg = pszSrc + ich;
3136
3138 break;
3139
3140 cchPath = ich;
3141 break;
3142 }
3143 else if (!resolveRelative)
3144 {
3145 szPath += pszSrc[ich];
3146 }
3147 }
3148
3149 if (!szPath[ich])
3150 {
3151 szPath.ReleaseBuffer(); // Remove excessive '\0'
3152 break;
3153 }
3154 }
3155
3156 if (!resolved)
3157 return -1;
3158
3159 if (cchPath && (dwFlags & PPCF_LONGESTPOSSIBLE))
3160 {
3161 szPath = szPath.Left(cchPath);
3162 pchArg = pszSrc + cchPath;
3163 }
3164 }
3165
3166 BOOL needsQuoting = (dwFlags & PPCF_ADDQUOTES) && wcschr(szPath, L' ');
3167 CStringW result = needsQuoting ? (L"\"" + szPath + L"\"") : szPath;
3168
3169 if (pchArg && (dwFlags & PPCF_ADDARGUMENTS))
3170 result += pchArg;
3171
3172 LONG requiredSize = result.GetLength() + 1;
3173 if (!pszDest)
3174 return requiredSize;
3175
3176 if (requiredSize > cchDest || StringCchCopyW(pszDest, cchDest, result) != S_OK)
3177 return -1;
3178
3179 return requiredSize;
3180}
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:652
BOOL WINAPI PathIsRelativeW(const WCHAR *path)
Definition: path.c:973
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
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
_In_ DWORD _In_ int _In_ int cchDest
Definition: winnls.h:1197

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 3006 of file shlexec.cpp.

3017{
3019 lpOperation,
3020 lpFile,
3021 lpParameters,
3023 lpReturn,
3024 lpTitle,
3025 lpReserved,
3026 nCmdShow,
3027 lphProcess,
3028 0);
3029}
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:2872
_In_ DWORD _In_ int _In_ int _In_opt_ LPNLSVERSIONINFO _In_opt_ LPVOID lpReserved
Definition: winnls.h:1199

◆ 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 2872 of file shlexec.cpp.

2884{
2885 SHELLEXECUTEINFOA ExecInfo;
2886
2887 TRACE("(%p, %s, %s, %s, %s, %p, %s, %p, %u, %p, %lu)\n",
2888 hwnd, debugstr_a(lpOperation), debugstr_a(lpFile), debugstr_a(lpParameters),
2890 lpReserved, nCmdShow, lphProcess, dwFlags);
2891
2892 ZeroMemory(&ExecInfo, sizeof(ExecInfo));
2893 ExecInfo.cbSize = sizeof(ExecInfo);
2895 ExecInfo.hwnd = hwnd;
2896 ExecInfo.lpVerb = lpOperation;
2897 ExecInfo.lpFile = lpFile;
2898 ExecInfo.lpParameters = lpParameters;
2899 ExecInfo.lpDirectory = lpDirectory;
2900 ExecInfo.nShow = (WORD)nCmdShow;
2901
2902 if (lpReserved)
2903 {
2904 ExecInfo.fMask |= SEE_MASK_USE_RESERVED;
2905 ExecInfo.hInstApp = (HINSTANCE)lpReserved;
2906 }
2907
2908 if (lpTitle)
2909 {
2910 ExecInfo.fMask |= SEE_MASK_HASTITLE;
2911 ExecInfo.lpClass = lpTitle;
2912 }
2913
2914 if (dwFlags & 1)
2915 ExecInfo.fMask |= SEE_MASK_FLAG_SEPVDM;
2916
2917 if (dwFlags & 2)
2918 ExecInfo.fMask |= SEE_MASK_NO_CONSOLE;
2919
2920 if (lphProcess == NULL)
2921 {
2922 ShellExecuteExA(&ExecInfo);
2923 }
2924 else
2925 {
2926 ExecInfo.fMask |= SEE_MASK_NOCLOSEPROCESS;
2927 ShellExecuteExA(&ExecInfo);
2928 *lphProcess = ExecInfo.hProcess;
2929 }
2930
2931 return ExecInfo.hInstApp;
2932}
unsigned short WORD
Definition: ntddk_ex.h:93
#define SEE_MASK_FLAG_NO_UI
Definition: shellapi.h:38
#define SEE_MASK_NO_CONSOLE
Definition: shellapi.h:41
BOOL WINAPI DECLSPEC_HOTPATCH ShellExecuteExA(LPSHELLEXECUTEINFOA sei)
Definition: shlexec.cpp:2494
LPCSTR lpParameters
Definition: shellapi.h:316
LPCSTR lpDirectory
Definition: shellapi.h:317
HANDLE HINSTANCE
Definition: typedefs.h:77
#define SEE_MASK_USE_RESERVED
Definition: undocshell.h:684
#define SEE_MASK_FLAG_SEPVDM
Definition: undocshell.h:683
#define SEE_MASK_HASTITLE
Definition: undocshell.h:685
#define SEE_MASK_UNKNOWN_0x1000
Definition: undocshell.h:680
#define ZeroMemory
Definition: winbase.h:1753

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 2939 of file shlexec.cpp.

2951{
2952 SHELLEXECUTEINFOW ExecInfo;
2953
2954 TRACE("(%p, %s, %s, %s, %s, %p, %s, %p, %u, %p, %lu)\n",
2955 hwnd, debugstr_w(lpOperation), debugstr_w(lpFile), debugstr_w(lpParameters),
2957 lpReserved, nCmdShow, lphProcess, dwFlags);
2958
2959 ZeroMemory(&ExecInfo, sizeof(ExecInfo));
2960 ExecInfo.cbSize = sizeof(ExecInfo);
2962 ExecInfo.hwnd = hwnd;
2963 ExecInfo.lpVerb = lpOperation;
2964 ExecInfo.lpFile = lpFile;
2965 ExecInfo.lpParameters = lpParameters;
2966 ExecInfo.lpDirectory = lpDirectory;
2967 ExecInfo.nShow = (WORD)nCmdShow;
2968
2969 if (lpReserved)
2970 {
2971 ExecInfo.fMask |= SEE_MASK_USE_RESERVED;
2972 ExecInfo.hInstApp = (HINSTANCE)lpReserved;
2973 }
2974
2975 if (lpTitle)
2976 {
2977 ExecInfo.fMask |= SEE_MASK_HASTITLE;
2978 ExecInfo.lpClass = lpTitle;
2979 }
2980
2981 if (dwFlags & 1)
2982 ExecInfo.fMask |= SEE_MASK_FLAG_SEPVDM;
2983
2984 if (dwFlags & 2)
2985 ExecInfo.fMask |= SEE_MASK_NO_CONSOLE;
2986
2987 if (lphProcess == NULL)
2988 {
2989 ShellExecuteExW(&ExecInfo);
2990 }
2991 else
2992 {
2993 ExecInfo.fMask |= SEE_MASK_NOCLOSEPROCESS;
2994 ShellExecuteExW(&ExecInfo);
2995 *lphProcess = ExecInfo.hProcess;
2996 }
2997
2998 return ExecInfo.hInstApp;
2999}
BOOL WINAPI DECLSPEC_HOTPATCH ShellExecuteExW(LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:2552
LPCWSTR lpParameters
Definition: shellapi.h:339

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 3036 of file shlexec.cpp.

3047{
3049 lpOperation,
3050 lpFile,
3051 lpParameters,
3053 lpReturn,
3054 lpTitle,
3055 lpReserved,
3056 nCmdShow,
3057 lphProcess,
3058 0);
3059}
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:2939

◆ 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 299 of file shlexec.cpp.

300{
301 BOOL done = FALSE;
302 BOOL found_p1 = FALSE;
303 PWSTR res = out;
304 DWORD used = 0;
305 bool tildeEffect = false;
306
307 TRACE("Before parsing: %p, %d, %s, %s, %p, %p\n", out, len, debugstr_w(fmt),
308 debugstr_w(lpFile), pidl, args);
309
310 while (*fmt)
311 {
312 if (*fmt == '%')
313 {
314 switch (*++fmt)
315 {
316 case '\0':
317 case '%':
318 {
319 used++;
320 if (used < len)
321 *res++ = '%';
322 };
323 break;
324
325 case '*':
326 {
327 if (args)
328 {
329 if (*fmt == '*')
330 {
331 used++;
332 while(*args)
333 {
334 used++;
335 if (used < len)
336 *res++ = *args++;
337 else
338 args++;
339 }
340 used++;
341 break;
342 }
343 }
344 };
345 break;
346
347 case '~':
348
349 case '2':
350 case '3':
351 case '4':
352 case '5':
353 case '6':
354 case '7':
355 case '8':
356 case '9':
357 //case '0':
358 {
359 if (*fmt == '~')
360 {
361 fmt++;
362 tildeEffect = true;
363 }
364
365 if (args)
366 {
367 if (tildeEffect)
368 {
369 ParseTildeEffect(res, args, len, used, *fmt - '2');
370 tildeEffect = false;
371 }
372 else
373 {
375 }
376 }
377 };
378 break;
379
380 case '1':
381 if ((!done || (*fmt == '1')) && lpFile)
382 {
383 SIZE_T filelen = wcslen(lpFile);
384 used += filelen;
385 if (used < len)
386 {
387 wcscpy(res, lpFile);
388 res += filelen;
389 }
390 }
391 found_p1 = TRUE;
392 break;
393
394 /*
395 * IE uses this a lot for activating things such as windows media
396 * player. This is not verified to be fully correct but it appears
397 * to work just fine.
398 */
399 case 'l':
400 case 'L':
401 if (lpFile)
402 {
403 used += wcslen(lpFile);
404 if (used < len)
405 {
406 wcscpy(res, lpFile);
407 res += wcslen(lpFile);
408 }
409 }
410 found_p1 = TRUE;
411 break;
412
413 case 'w':
414 case 'W':
415 if (lpDir)
416 {
417 used += wcslen(lpDir);
418 if (used < len)
419 {
420 wcscpy(res, lpDir);
421 res += wcslen(lpDir);
422 }
423 }
424 break;
425
426 case 'v':
427 case 'V':
428 if (lpFile)
429 {
430 used += wcslen(lpFile);
431 if (used < len)
432 {
433 wcscpy(res, lpFile);
434 res += wcslen(lpFile);
435 }
436 found_p1 = TRUE;
437 }
438 else if (lpDir)
439 {
440 used += wcslen(lpDir);
441 if (used < len)
442 {
443 wcscpy(res, lpDir);
444 res += wcslen(lpDir);
445 }
446 }
447 break;
448
449 case 'i':
450 case 'I':
451 if (pidl)
452 {
453 DWORD chars = 0;
454 /* %p should not exceed 8, maybe 16 when looking forward to 64bit.
455 * allowing a buffer of 100 should more than exceed all needs */
456 WCHAR buf[100];
457 LPVOID pv;
458 HGLOBAL hmem = SHAllocShared(pidl, ILGetSize(pidl), 0);
459 pv = SHLockShared(hmem, 0);
460 chars = swprintf(buf, L":%p", pv);
461
462 if (chars >= ARRAY_SIZE(buf))
463 ERR("pidl format buffer too small!\n");
464
465 used += chars;
466
467 if (used < len)
468 {
469 wcscpy(res, buf);
470 res += chars;
471 }
472 SHUnlockShared(pv);
473 }
474 found_p1 = TRUE;
475 break;
476
477 default:
478 /*
479 * Check if this is an env-variable here...
480 */
481
482 /* Make sure that we have at least one more %.*/
483 if (strchrW(fmt, '%'))
484 {
485 WCHAR tmpBuffer[1024];
486 PWSTR tmpB = tmpBuffer;
487 WCHAR tmpEnvBuff[MAX_PATH];
488 DWORD envRet;
489
490 while (*fmt != '%')
491 *tmpB++ = *fmt++;
492 *tmpB++ = 0;
493
494 TRACE("Checking %s to be an env-var\n", debugstr_w(tmpBuffer));
495
496 envRet = GetEnvironmentVariableW(tmpBuffer, tmpEnvBuff, MAX_PATH);
497 if (envRet == 0 || envRet > MAX_PATH)
498 {
499 used += wcslen(tmpBuffer);
500 if (used < len)
501 {
502 wcscpy( res, tmpBuffer );
503 res += wcslen(tmpBuffer);
504 }
505 }
506 else
507 {
508 used += wcslen(tmpEnvBuff);
509 if (used < len)
510 {
511 wcscpy( res, tmpEnvBuff );
512 res += wcslen(tmpEnvBuff);
513 }
514 }
515 }
516 done = TRUE;
517 break;
518 }
519 /* Don't skip past terminator (catch a single '%' at the end) */
520 if (*fmt != '\0')
521 {
522 fmt++;
523 }
524 }
525 else
526 {
527 used ++;
528 if (used < len)
529 *res++ = *fmt++;
530 else
531 fmt++;
532 }
533 }
534
535 used++;
536 if (res - out < static_cast<int>(len))
537 *res = '\0';
538 else
539 out[len-1] = '\0';
540
541 TRACE("used %i of %i space\n", used, len);
542 if (out_len)
543 *out_len = used;
544
545 TRACE("After parsing: %p, %d, %s, %s, %p, %p\n", out, len, debugstr_w(fmt),
546 debugstr_w(lpFile), pidl, args);
547
548 return found_p1;
549}
#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:150
static void ParseTildeEffect(PWSTR &res, LPCWSTR &args, DWORD &len, DWORD &used, int argNum)
Definition: shlexec.cpp:217
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 677 of file shlexec.cpp.

678{
680 WCHAR *strings, *p, *p2;
681 int total = wcslen(path) + 1;
682 BOOL got_path = FALSE;
683
684 if (!(strings = GetEnvironmentStringsW())) return NULL;
685 p = strings;
686 while (*p)
687 {
688 int len = wcslen(p) + 1;
689 if (!_wcsnicmp( p, L"PATH=", 5 )) got_path = TRUE;
690 total += len;
691 p += len;
692 }
693 if (!got_path) total += 5; /* we need to create PATH */
694 total++; /* terminating null */
695
696 if (!new_env.Allocate(total))
697 {
699 return NULL;
700 }
701 p = strings;
702 p2 = new_env;
703 while (*p)
704 {
705 int len = wcslen(p) + 1;
706 memcpy(p2, p, len * sizeof(WCHAR));
707 if (!_wcsnicmp( p, L"PATH=", 5 ))
708 {
709 p2[len - 1] = ';';
710 wcscpy( p2 + len, path );
711 p2 += wcslen(path) + 1;
712 }
713 p += len;
714 p2 += len;
715 }
716 if (!got_path)
717 {
718 wcscpy(p2, L"PATH=");
719 wcscat(p2, path);
720 p2 += wcslen(p2) + 1;
721 }
722 *p2 = 0;
724 return new_env.Detach();
725}
T * Detach()
Definition: atlalloc.h:168
wcscat
BOOL WINAPI FreeEnvironmentStringsW(IN LPWSTR EnvironmentStrings)
Definition: environ.c:389
LPWSTR WINAPI DECLSPEC_HOTPATCH GetEnvironmentStringsW(void)
Definition: process.c:1538
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)

Referenced by SHELL_TryAppPathW().

◆ SHELL_execute()

static BOOL SHELL_execute ( LPSHELLEXECUTEINFOW  sei,
SHELL_ExecuteW32  execfunc 
)
static

Definition at line 2038 of file shlexec.cpp.

2039{
2040 static const DWORD unsupportedFlags =
2042
2043 DWORD len;
2045 BOOL appKnownSingular = FALSE;
2046
2047 /* make a local copy of the LPSHELLEXECUTEINFO structure and work with this from now on */
2048 sei->hProcess = NULL;
2049 SHELLEXECUTEINFOW sei_tmp = *sei;
2050
2051 TRACE("mask=0x%08x hwnd=%p verb=%s file=%s parm=%s dir=%s show=0x%08x class=%s\n",
2052 sei_tmp.fMask, sei_tmp.hwnd, debugstr_w(sei_tmp.lpVerb),
2053 debugstr_w(sei_tmp.lpFile), debugstr_w(sei_tmp.lpParameters),
2054 debugstr_w(sei_tmp.lpDirectory), sei_tmp.nShow,
2055 ((sei_tmp.fMask & SEE_MASK_CLASSALL) == SEE_MASK_CLASSNAME) ?
2056 debugstr_w(sei_tmp.lpClass) : "not used");
2057
2058 // Call hooks before expanding and resolving strings
2060 if (hr != S_FALSE)
2061 {
2062 int err = Win32ErrFromHInst(sei->hInstApp);
2063 if (err <= 0)
2064 {
2065 sei->hInstApp = (HINSTANCE)UlongToHandle(42);
2066 return TRUE;
2067 }
2069 return FALSE;
2070 }
2071
2072 /* make copies of all path/command strings */
2073 CHeapPtr<WCHAR, CLocalAllocator> wszApplicationName;
2074 DWORD dwApplicationNameLen = MAX_PATH + 2;
2075 if (!sei_tmp.lpFile)
2076 {
2077 wszApplicationName.Allocate(dwApplicationNameLen);
2078 *wszApplicationName = '\0';
2079 }
2080 else if (*sei_tmp.lpFile == '\"' && sei_tmp.lpFile[(len = strlenW(sei_tmp.lpFile))-1] == '\"')
2081 {
2082 if(len-1 >= dwApplicationNameLen)
2083 dwApplicationNameLen = len;
2084
2085 wszApplicationName.Allocate(dwApplicationNameLen);
2086 memcpy(wszApplicationName, sei_tmp.lpFile + 1, len * sizeof(WCHAR));
2087
2088 if(len > 2)
2089 wszApplicationName[len-2] = '\0';
2090 appKnownSingular = TRUE;
2091
2092 TRACE("wszApplicationName=%s\n", debugstr_w(wszApplicationName));
2093 }
2094 else
2095 {
2096 DWORD l = strlenW(sei_tmp.lpFile) + 1;
2097 if(l > dwApplicationNameLen) dwApplicationNameLen = l + 1;
2098 wszApplicationName.Allocate(dwApplicationNameLen);
2099 memcpy(wszApplicationName, sei_tmp.lpFile, l * sizeof(WCHAR));
2100
2101 if (wszApplicationName[2] == 0 && wszApplicationName[1] == L':' &&
2102 ((L'A' <= wszApplicationName[0] && wszApplicationName[0] <= L'Z') ||
2103 (L'a' <= wszApplicationName[0] && wszApplicationName[0] <= L'z')))
2104 {
2105 // 'C:' --> 'C:\'
2106 PathAddBackslashW(wszApplicationName);
2107 }
2108 }
2109
2110 WCHAR parametersBuffer[1024];
2111 LPWSTR wszParameters = parametersBuffer;
2113 DWORD parametersLen = _countof(parametersBuffer);
2114
2115 if (sei_tmp.lpParameters)
2116 {
2117 len = lstrlenW(sei_tmp.lpParameters) + 1;
2118 if (len > parametersLen)
2119 {
2120 wszParamAlloc.Allocate(len);
2121 wszParameters = wszParamAlloc;
2122 parametersLen = len;
2123 }
2124 strcpyW(wszParameters, sei_tmp.lpParameters);
2125 }
2126 else
2127 *wszParameters = L'\0';
2128
2129 // Get the working directory
2130 WCHAR dirBuffer[MAX_PATH];
2131 LPWSTR wszDir = dirBuffer;
2132 wszDir[0] = UNICODE_NULL;
2134 if (sei_tmp.lpDirectory && *sei_tmp.lpDirectory)
2135 {
2136 if (sei_tmp.fMask & SEE_MASK_DOENVSUBST)
2137 {
2138 LPWSTR tmp = expand_environment(sei_tmp.lpDirectory);
2139 if (tmp)
2140 {
2141 wszDirAlloc.Attach(tmp);
2142 wszDir = wszDirAlloc;
2143 }
2144 }
2145 else
2146 {
2147 __SHCloneStrW(&wszDirAlloc, sei_tmp.lpDirectory);
2148 if (wszDirAlloc)
2149 wszDir = wszDirAlloc;
2150 }
2151 }
2152 if (!wszDir[0])
2153 {
2154 ::GetCurrentDirectoryW(_countof(dirBuffer), dirBuffer);
2155 wszDir = dirBuffer;
2156 }
2157 // NOTE: ShellExecute should accept the invalid working directory for historical reason.
2158 if (!PathIsDirectoryW(wszDir))
2159 {
2160 INT iDrive = PathGetDriveNumberW(wszDir);
2161 if (iDrive >= 0)
2162 {
2163 PathStripToRootW(wszDir);
2164 if (!PathIsDirectoryW(wszDir))
2165 {
2166 ::GetWindowsDirectoryW(dirBuffer, _countof(dirBuffer));
2167 wszDir = dirBuffer;
2168 }
2169 }
2170 }
2171
2172 /* adjust string pointers to point to the new buffers */
2173 sei_tmp.lpFile = wszApplicationName;
2174 sei_tmp.lpParameters = wszParameters;
2175 sei_tmp.lpDirectory = wszDir;
2176
2177 if (sei_tmp.fMask & unsupportedFlags)
2178 {
2179 FIXME("flags ignored: 0x%08x\n", sei_tmp.fMask & unsupportedFlags);
2180 }
2181
2182 /* process the IDList */
2183 if (sei_tmp.fMask & SEE_MASK_IDLIST &&
2185 {
2186 LPCITEMIDLIST pidl = (LPCITEMIDLIST)sei_tmp.lpIDList;
2187 hr = SHGetNameAndFlagsW(pidl, SHGDN_FORPARSING, wszApplicationName, dwApplicationNameLen, NULL);
2188 if (FAILED(hr))
2189 {
2190 if (dwApplicationNameLen)
2191 *wszApplicationName = UNICODE_NULL;
2192 if (!_ILIsDesktop(pidl))
2193 TRACE("Unable to get PIDL parsing path\n");
2194 }
2195 appKnownSingular = TRUE;
2196 TRACE("-- idlist=%p (%s)\n", sei_tmp.lpIDList, debugstr_w(wszApplicationName));
2197 }
2198
2199 if ((sei_tmp.fMask & SEE_MASK_DOENVSUBST) && !StrIsNullOrEmpty(sei_tmp.lpFile))
2200 {
2201 WCHAR *tmp = expand_environment(sei_tmp.lpFile);
2202 if (tmp)
2203 {
2204 wszApplicationName.Attach(tmp);
2205 sei_tmp.lpFile = wszApplicationName;
2206 }
2207 }
2208
2210 {
2211 hr = ShellExecute_ContextMenuVerb(&sei_tmp);
2212 if (SUCCEEDED(hr))
2213 {
2214 sei->hInstApp = (HINSTANCE)42;
2215 return TRUE;
2216 }
2217 }
2218
2220 {
2221 sei->hInstApp = (HINSTANCE) 33;
2222 return TRUE;
2223 }
2224
2225 if (sei_tmp.fMask & SEE_MASK_CLASSALL)
2226 {
2227 retval = SHELL_execute_class(wszApplicationName, &sei_tmp, sei, execfunc);
2228 if (retval <= 32 && !(sei_tmp.fMask & SEE_MASK_FLAG_NO_UI))
2229 {
2231
2232 //FIXME
2233 // need full path
2234
2235 Info.pcszFile = wszApplicationName;
2236 Info.pcszClass = NULL;
2237 Info.oaifInFlags = OAIF_ALLOW_REGISTRATION | OAIF_EXEC;
2238
2239 //if (SHOpenWithDialog(sei_tmp.hwnd, &Info) != S_OK)
2241 do_error_dialog(retval, sei_tmp.hwnd, wszApplicationName);
2242 }
2243 return retval > 32;
2244 }
2245
2246 if (!(sei_tmp.fMask & SEE_MASK_IDLIST) && // Not an ID List
2247 (StrCmpNIW(sei_tmp.lpFile, L"shell:", 6) == 0 ||
2248 StrCmpNW(sei_tmp.lpFile, L"::{", 3) == 0))
2249 {
2250 CComHeapPtr<ITEMIDLIST> pidlParsed;
2251 hr = SHParseDisplayName(sei_tmp.lpFile, NULL, &pidlParsed, 0, NULL);
2252 if (SUCCEEDED(hr) && SHELL_InvokePidl(&sei_tmp, pidlParsed))
2253 {
2254 sei_tmp.hInstApp = (HINSTANCE)UlongToHandle(42);
2255 return TRUE;
2256 }
2257 }
2258
2259 /* Has the IDList not yet been translated? */
2260 if (sei_tmp.fMask & SEE_MASK_IDLIST)
2261 {
2262 appKnownSingular = SHELL_translate_idlist( &sei_tmp, wszParameters,
2263 parametersLen,
2264 wszApplicationName,
2265 dwApplicationNameLen );
2266 }
2267
2268 /* convert file URLs */
2269 if (UrlIsFileUrlW(sei_tmp.lpFile))
2270 {
2273 if (!buf.Allocate(size) || FAILED(PathCreateFromUrlW(sei_tmp.lpFile, buf, &size, 0)))
2274 {
2276 return FALSE;
2277 }
2278
2279 wszApplicationName.Attach(buf.Detach());
2280 sei_tmp.lpFile = wszApplicationName;
2281 }
2282
2283 /* Else, try to execute the filename */
2284 TRACE("execute: %s,%s,%s\n", debugstr_w(wszApplicationName), debugstr_w(wszParameters), debugstr_w(wszDir));
2285
2286 /* separate out command line arguments from executable file name */
2287 LPCWSTR lpFile = sei_tmp.lpFile;
2288 if (!*sei_tmp.lpParameters && !appKnownSingular)
2289 {
2290 /* If the executable path is quoted, handle the rest of the command line as parameters. */
2291 if (sei_tmp.lpFile[0] == L'"')
2292 {
2293 LPWSTR pszArgs = PathGetArgsW(wszApplicationName);
2294 PathRemoveArgsW(wszApplicationName);
2295 PathUnquoteSpacesW(wszApplicationName);
2296 parametersLen = lstrlenW(pszArgs);
2297 if (parametersLen < _countof(parametersBuffer))
2298 {
2299 StringCchCopyW(parametersBuffer, _countof(parametersBuffer), pszArgs);
2300 wszParameters = parametersBuffer;
2301 }
2302 else
2303 {
2304 wszParamAlloc.Attach(StrDupW(pszArgs));
2305 wszParameters = wszParamAlloc;
2306 }
2307 }
2308 /* We have to test sei instead of sei_tmp because sei_tmp had its
2309 * input fMask modified above in SHELL_translate_idlist.
2310 * This code is needed to handle the case where we only have an
2311 * lpIDList with multiple CLSID/PIDL's (not 'My Computer' only) */
2312 else if ((sei->fMask & SEE_MASK_IDLIST) == SEE_MASK_IDLIST)
2313 {
2314 WCHAR buffer[MAX_PATH], xlpFile[MAX_PATH];
2315 LPWSTR space, s;
2316
2317 LPWSTR beg = wszApplicationName;
2318 for(s = beg; (space = const_cast<LPWSTR>(strchrW(s, L' '))); s = space + 1)
2319 {
2320 int idx = space - sei_tmp.lpFile;
2321 memcpy(buffer, sei_tmp.lpFile, idx * sizeof(WCHAR));
2322 buffer[idx] = '\0';
2323
2324 if (SearchPathW(*sei_tmp.lpDirectory ? sei_tmp.lpDirectory : NULL,
2325 buffer, L".exe", _countof(xlpFile), xlpFile, NULL))
2326 {
2327 /* separate out command from parameter string */
2328 LPCWSTR p = space + 1;
2329
2330 while(isspaceW(*p))
2331 ++p;
2332
2333 strcpyW(wszParameters, p);
2334 *space = L'\0';
2335
2336 break;
2337 }
2338 }
2339 }
2340 }
2341
2342 WCHAR wcmdBuffer[1024];
2343 LPWSTR wcmd = wcmdBuffer;
2344 DWORD wcmdLen = _countof(wcmdBuffer);
2346
2347 /* Only execute if it has an executable extension */
2348 if (PathIsExeW(lpFile))
2349 {
2350 len = lstrlenW(wszApplicationName) + 3;
2351 if (sei_tmp.lpParameters[0])
2352 len += 1 + lstrlenW(wszParameters);
2353 if (len > wcmdLen)
2354 {
2355 wcmdAlloc.Allocate(len);
2356 wcmd = wcmdAlloc;
2357 wcmdLen = len;
2358 }
2359 swprintf(wcmd, L"\"%s\"", (LPWSTR)wszApplicationName);
2360 if (sei_tmp.lpParameters[0])
2361 {
2362 strcatW(wcmd, L" ");
2363 strcatW(wcmd, wszParameters);
2364 }
2365
2366 retval = execfunc(wcmd, NULL, FALSE, &sei_tmp, sei);
2367 if (retval > 32)
2368 return TRUE;
2369 }
2370
2371 /* Else, try to find the executable */
2372 WCHAR wszKeyname[256];
2374 wcmd[0] = UNICODE_NULL;
2375 retval = SHELL_FindExecutable(sei_tmp.lpDirectory, lpFile, sei_tmp.lpVerb, wcmd, wcmdLen, wszKeyname, &env, (LPITEMIDLIST)sei_tmp.lpIDList, sei_tmp.lpParameters);
2376 if (retval > 32) /* Found */
2377 {
2378 retval = SHELL_quote_and_execute(wcmd, wszParameters, wszKeyname,
2379 wszApplicationName, env, &sei_tmp,
2380 sei, execfunc);
2381 }
2382 else if (PathIsDirectoryW(lpFile))
2383 {
2384 WCHAR wExec[MAX_PATH];
2386 if (lpQuotedFile.Allocate(strlenW(lpFile) + 3))
2387 {
2388 retval = SHELL_FindExecutable(sei_tmp.lpDirectory, L"explorer",
2389 L"open", wExec, MAX_PATH,
2390 NULL, &env, NULL, NULL);
2391 if (retval > 32)
2392 {
2393 swprintf(lpQuotedFile, L"\"%s\"", lpFile);
2394 retval = SHELL_quote_and_execute(wExec, lpQuotedFile,
2395 wszKeyname,
2396 wszApplicationName, env,
2397 &sei_tmp, sei, execfunc);
2398 }
2399 }
2400 else
2401 retval = 0; /* Out of memory */
2402 }
2403 else if (PathIsURLW(lpFile)) /* File not found, check for URL */
2404 {
2405 retval = SHELL_execute_url(lpFile, wcmd, &sei_tmp, sei, execfunc );
2406 }
2407 /* Check if file specified is in the form www.??????.*** */
2408 else if (!strncmpiW(lpFile, L"www", 3))
2409 {
2410 /* if so, prefix lpFile with http:// and call ShellExecute */
2411 WCHAR lpstrTmpFile[256];
2412 strcpyW(lpstrTmpFile, L"http://");
2413 strcatW(lpstrTmpFile, lpFile); // FIXME: Possible buffer overflow
2414 // FIXME: This will not correctly return the hProcess to the caller
2415 retval = (UINT_PTR)ShellExecuteW(sei_tmp.hwnd, sei_tmp.lpVerb, lpstrTmpFile, NULL, NULL, 0);
2416 }
2417
2418 TRACE("retval %lu\n", retval);
2419
2420 if (retval <= 32 && !(sei_tmp.fMask & SEE_MASK_FLAG_NO_UI))
2421 {
2422 if (retval == SE_ERR_NOASSOC && !(sei->fMask & SEE_MASK_CLASSALL))
2423 retval = InvokeOpenWith(sei_tmp.hwnd, *sei);
2424 if (retval <= 32)
2425 do_error_dialog(retval, sei_tmp.hwnd, lpFile);
2426 }
2427
2428 sei->hInstApp = (HINSTANCE)(retval > 32 ? 33 : retval);
2429
2430 return retval > 32;
2431}
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
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
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
void WINAPI PathUnquoteSpacesW(WCHAR *path)
Definition: path.c:1949
int WINAPI PathGetDriveNumberW(const WCHAR *path)
Definition: path.c:1753
HRESULT WINAPI PathCreateFromUrlW(const WCHAR *url, WCHAR *path, DWORD *pcchPath, DWORD dwReserved)
Definition: path.c:3016
BOOL WINAPI PathStripToRootW(WCHAR *path)
Definition: path.c:1138
BOOL WINAPI PathIsURLW(const WCHAR *path)
Definition: path.c:3181
WCHAR *WINAPI PathGetArgsW(const WCHAR *path)
Definition: path.c:1683
WCHAR *WINAPI StrDupW(const WCHAR *str)
Definition: string.c:313
HRESULT SHGetNameAndFlagsW(_In_ LPCITEMIDLIST pidl, _In_ DWORD dwFlags, _Out_opt_ LPWSTR pszText, _In_ UINT cchBuf, _Inout_opt_ DWORD *pdwAttributes)
Definition: utils.cpp:503
void WINAPI PathRemoveArgsW(LPWSTR lpszPath)
Definition: path.c:779
BOOL WINAPI PathIsDirectoryW(LPCWSTR lpszPath)
Definition: path.c:1729
GLdouble s
Definition: gl.h:2039
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
#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:1542
#define strncmpiW(s1, s2, n)
Definition: unicode.h:46
#define strcatW(d, s)
Definition: unicode.h:36
#define isspaceW(n)
Definition: unicode.h:58
#define err(...)
static __inline void __SHCloneStrW(WCHAR **target, const WCHAR *source)
Definition: shell32_main.h:183
#define SEE_MASK_DOENVSUBST
Definition: shellapi.h:37
#define SEE_MASK_CLASSNAME
Definition: shellapi.h:25
#define SEE_MASK_ASYNCOK
Definition: shellapi.h:43
#define SEE_MASK_IDLIST
Definition: shellapi.h:27
#define SEE_MASK_FLAG_DDEWAIT
Definition: shellapi.h:36
#define SEE_MASK_CONNECTNETDRV
Definition: shellapi.h:34
#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:1759
static HRESULT ShellExecute_ContextMenuVerb(LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:1648
static UINT_PTR InvokeOpenWith(HWND hWndOwner, SHELLEXECUTEINFOW &sei)
Definition: shlexec.cpp:86
static void do_error_dialog(UINT_PTR retval, HWND hwnd, PCWSTR filename)
Definition: shlexec.cpp:1996
static BOOL SHELL_InvokePidl(_In_ LPSHELLEXECUTEINFOW sei, _In_ LPCITEMIDLIST pidl)
Definition: shlexec.cpp:1874
static LONG ShellExecute_FromContextMenuHandlers(LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:1714
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:863
#define SEE_MASK_CLASSALL
Definition: shlexec.cpp:31
static WCHAR * expand_environment(const WCHAR *str)
Definition: shlexec.cpp:2017
static HRESULT TryShellExecuteHooks(LPSHELLEXECUTEINFOW pSEI)
Definition: shlexec.cpp:122
static UINT_PTR SHELL_execute_url(LPCWSTR lpFile, LPCWSTR wcmd, LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out, SHELL_ExecuteW32 execfunc)
Definition: shlexec.cpp:1962
HINSTANCE WINAPI ShellExecuteW(HWND hwnd, LPCWSTR lpVerb, LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd)
Definition: shlexec.cpp:2607
static BOOL SHELL_translate_idlist(LPSHELLEXECUTEINFOW sei, LPWSTR wszParameters, DWORD parametersLen, LPWSTR wszApplicationName, DWORD dwApplicationNameLen)
Definition: shlexec.cpp:1818
static int Win32ErrFromHInst(HINSTANCE hInst)
Definition: shlexec.cpp:36
static UINT_PTR SHELL_quote_and_execute(LPCWSTR wcmd, LPCWSTR wszParameters, LPCWSTR wszKeyname, LPCWSTR wszApplicationName, LPWSTR env, LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out, SHELL_ExecuteW32 execfunc)
Definition: shlexec.cpp:1926
#define UrlIsFileUrlW(x)
Definition: shlwapi.h:1423
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

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 1759 of file shlexec.cpp.

1760{
1761 WCHAR execCmd[1024], classname[1024];
1762 /* launch a document by fileclass like 'WordPad.Document.1' */
1763 /* the Commandline contains 'c:\Path\wordpad.exe "%1"' */
1764 /* FIXME: wcmd should not be of a fixed size. Fixed to 1024, MAX_PATH is way too short! */
1765 ULONG cmask = (psei->fMask & SEE_MASK_CLASSALL);
1766 DWORD resultLen;
1767 BOOL done;
1768 UINT_PTR rslt;
1769
1770 /* FIXME: remove following block when SHELL_quote_and_execute supports hkeyClass parameter */
1771 if (cmask != SEE_MASK_CLASSNAME)
1772 {
1773 WCHAR wcmd[1024];
1775 (cmask == SEE_MASK_CLASSNAME) ? psei->lpClass : NULL,
1776 psei->lpVerb,
1777 execCmd, sizeof(execCmd));
1778
1779 /* FIXME: get the extension of lpFile, check if it fits to the lpClass */
1780 TRACE("SEE_MASK_CLASSNAME->%s, doc->%s\n", debugstr_w(execCmd), debugstr_w(wszApplicationName));
1781
1782 wcmd[0] = '\0';
1783 done = SHELL_ArgifyW(wcmd, ARRAY_SIZE(wcmd), execCmd, wszApplicationName, (LPITEMIDLIST)psei->lpIDList, psei->lpParameters,
1784 &resultLen, (psei->lpDirectory && *psei->lpDirectory) ? psei->lpDirectory : NULL);
1785 if (!done && wszApplicationName[0])
1786 {
1787#if 0 // Given HKCR\.test=SZ:"test" and HKCR\test\shell\open\command=SZ:"cmd.exe /K echo.Hello", no filename is
1788 // appended on Windows when there is no %1 nor %L when executed with: shlextdbg.exe /shellexec=c:\file.test /INVOKE
1789 strcatW(wcmd, L" ");
1790 if (*wszApplicationName != '"')
1791 {
1792 strcatW(wcmd, L"\"");
1793 strcatW(wcmd, wszApplicationName);
1794 strcatW(wcmd, L"\"");
1795 }
1796 else
1797 strcatW(wcmd, wszApplicationName);
1798#endif
1799 }
1800 if (resultLen > ARRAY_SIZE(wcmd))
1801 ERR("Argify buffer not large enough... truncating\n");
1802 return execfunc(wcmd, NULL, FALSE, psei, psei_out);
1803 }
1804
1805 strcpyW(classname, psei->lpClass);
1806 rslt = SHELL_FindExecutableByVerb(psei->lpVerb, NULL, classname, execCmd, sizeof(execCmd));
1807
1808 TRACE("SHELL_FindExecutableByVerb returned %u (%s, %s)\n", (unsigned int)rslt, debugstr_w(classname), debugstr_w(execCmd));
1809 if (33 > rslt)
1810 return rslt;
1811 rslt = SHELL_quote_and_execute( execCmd, L"", classname,
1812 wszApplicationName, NULL, psei,
1813 psei_out, execfunc );
1814 return rslt;
1815
1816}
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:795
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 1962 of file shlexec.cpp.

1963{
1966 LPCWSTR lpstrRes;
1967 INT iSize;
1968 DWORD len;
1969
1970 lpstrRes = strchrW(lpFile, ':');
1971 if (lpstrRes)
1972 iSize = lpstrRes - lpFile;
1973 else
1974 iSize = strlenW(lpFile);
1975
1976 TRACE("Got URL: %s\n", debugstr_w(lpFile));
1977 /* Looking for ...<protocol>\shell<lpVerb>\command */
1978 len = iSize + lstrlenW(L"\\shell\\") + lstrlenW(L"\\command") + 1;
1979 if (psei->lpVerb && *psei->lpVerb)
1980 len += lstrlenW(psei->lpVerb);
1981 else
1982 len += lstrlenW(L"open"); // FIXME: Use HCR_GetExecuteCommandW or AssocAPI
1983 lpstrProtocol.Allocate(len);
1984 memcpy(lpstrProtocol, lpFile, iSize * sizeof(WCHAR));
1985 lpstrProtocol[iSize] = '\0';
1986 strcatW(lpstrProtocol, L"\\shell\\");
1987 strcatW(lpstrProtocol, psei->lpVerb && *psei->lpVerb ? psei->lpVerb : L"open");
1988 strcatW(lpstrProtocol, L"\\command");
1989
1990 retval = execute_from_key(lpstrProtocol, lpFile, NULL, psei->lpParameters,
1991 wcmd, execfunc, psei, psei_out);
1992
1993 return retval;
1994}
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:1308

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 573 of file shlexec.cpp.

575{
579 UINT gcdret = 0;
580 WCHAR curdir[MAX_PATH];
581 DWORD dwCreationFlags;
582 const WCHAR *lpDirectory = NULL;
583
584 TRACE("Execute %s from directory %s\n", debugstr_w(lpCmd), debugstr_w(psei->lpDirectory));
585
586 /* make sure we don't fail the CreateProcess if the calling app passes in
587 * a bad working directory */
588 if (!StrIsNullOrEmpty(psei->lpDirectory))
589 {
592 lpDirectory = psei->lpDirectory;
593 }
594
595 /* ShellExecute specifies the command from psei->lpDirectory
596 * if present. Not from the current dir as CreateProcess does */
597 if (lpDirectory)
598 if ((gcdret = GetCurrentDirectoryW( MAX_PATH, curdir)))
600 ERR("cannot set directory %s\n", debugstr_w(lpDirectory));
601
603 startup.cb = sizeof(STARTUPINFOW);
605 startup.wShowWindow = psei->nShow;
606 dwCreationFlags = CREATE_UNICODE_ENVIRONMENT;
607 if (!(psei->fMask & SEE_MASK_NO_CONSOLE))
608 dwCreationFlags |= CREATE_NEW_CONSOLE;
609 if (psei->fMask & SEE_MASK_FLAG_SEPVDM)
610 dwCreationFlags |= CREATE_SEPARATE_WOW_VDM;
611 startup.lpTitle = (LPWSTR)(psei->fMask & (SEE_MASK_HASLINKNAME | SEE_MASK_HASTITLE) ? psei->lpClass : NULL);
612
613 if (psei->fMask & SEE_MASK_HASLINKNAME)
614 startup.dwFlags |= STARTF_TITLEISLINKNAME;
615
616 if (psei->fMask & SEE_MASK_HOTKEY)
617 {
618 startup.hStdInput = UlongToHandle(psei->dwHotKey);
619 startup.dwFlags |= STARTF_USEHOTKEY;
620 }
621
622 if (psei->fMask & SEE_MASK_ICON) // hIcon has higher precedence than hMonitor
623 {
624 startup.hStdOutput = psei->hIcon;
625 startup.dwFlags |= STARTF_SHELLPRIVATE;
626 }
627 else if ((psei->fMask & SEE_MASK_HMONITOR) || psei->hwnd)
628 {
629 if (psei->fMask & SEE_MASK_HMONITOR)
630 startup.hStdOutput = psei->hMonitor;
631 else if (psei->hwnd)
632 startup.hStdOutput = MonitorFromWindow(psei->hwnd, MONITOR_DEFAULTTONEAREST);
633 if (startup.hStdOutput)
634 startup.dwFlags |= STARTF_SHELLPRIVATE;
635 }
636
637 if (CreateProcessW(NULL, (LPWSTR)lpCmd, NULL, NULL, FALSE, dwCreationFlags, env,
639 {
640 /* Give 30 seconds to the app to come up, if desired. Probably only needed
641 when starting app immediately before making a DDE connection. */
642 if (shWait)
643 if (WaitForInputIdle(info.hProcess, 30000) == WAIT_FAILED)
644 WARN("WaitForInputIdle failed: Error %d\n", GetLastError() );
645 retval = 33;
646
647 if (psei->fMask & SEE_MASK_NOCLOSEPROCESS)
648 psei_out->hProcess = info.hProcess;
649 else
650 CloseHandle( info.hProcess );
651 CloseHandle( info.hThread );
652 }
653 else if ((retval = GetLastError()) >= 32)
654 {
655 WARN("CreateProcess returned error %ld\n", retval);
657 }
658
659 TRACE("returning %lu\n", retval);
660
661 psei_out->hInstApp = (HINSTANCE)retval;
662
663 if (gcdret)
664 if (!SetCurrentDirectoryW(curdir))
665 ERR("cannot return to directory %s\n", debugstr_w(curdir));
666
667 return retval;
668}
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)
#define STARTF_USEHOTKEY
Definition: pch.h:41
#define SEE_MASK_HOTKEY
Definition: shellapi.h:32
#define SEE_MASK_HMONITOR
Definition: shellapi.h:45
Definition: cookie.c:202
#define SEE_MASK_HASLINKNAME
Definition: undocshell.h:682
#define STARTF_USESHOWWINDOW
Definition: winbase.h:524
#define CREATE_UNICODE_ENVIRONMENT
Definition: winbase.h:196
#define CREATE_SEPARATE_WOW_VDM
Definition: winbase.h:197
#define WAIT_FAILED
Definition: winbase.h:446
#define CREATE_NEW_CONSOLE
Definition: winbase.h:190
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 863 of file shlexec.cpp.

865{
866 WCHAR *extension = NULL; /* pointer to file extension */
867 WCHAR classname[256]; /* registry name for this file type */
868 LONG classnamelen = sizeof(classname); /* length of above */
869 WCHAR command[1024]; /* command from registry */
870 WCHAR wBuffer[256]; /* Used to GetProfileString */
872 WCHAR *tok; /* token pointer */
873 WCHAR xlpFile[MAX_PATH]; /* result of PathResolve */
874 DWORD attribs; /* file attributes */
875 WCHAR curdir[MAX_PATH];
876 const WCHAR *search_paths[3] = {0};
877
878 TRACE("%s\n", debugstr_w(lpFile));
879
880 if (!lpResult)
882
883 xlpFile[0] = '\0';
884 lpResult[0] = '\0'; /* Start off with an empty return string */
885 if (key) *key = '\0';
886
887 /* trap NULL parameters on entry */
888 if (!lpFile)
889 {
890 WARN("(lpFile=%s,lpResult=%s): NULL parameter\n",
891 debugstr_w(lpFile), debugstr_w(lpResult));
892 return ERROR_FILE_NOT_FOUND; /* File not found. Close enough, I guess. */
893 }
894
895 if (SHELL_TryAppPathW( lpFile, lpResult, env ))
896 {
897 TRACE("found %s via App Paths\n", debugstr_w(lpResult));
898 return 33;
899 }
900
901 GetCurrentDirectoryW(ARRAY_SIZE(curdir), curdir);
902 if (lpPath && *lpPath)
903 {
904 search_paths[0] = lpPath;
905 search_paths[1] = curdir;
906 }
907 else
908 {
909 search_paths[0] = curdir;
910 }
911
912 lstrcpyW(xlpFile, lpFile);
913 if (PathResolveW(xlpFile, search_paths, PRF_TRYPROGRAMEXTENSIONS | PRF_VERIFYEXISTS) ||
914 PathFindOnPathW(xlpFile, search_paths))
915 {
916 TRACE("PathResolveW returned non-zero\n");
917 lpFile = xlpFile;
918 PathRemoveBlanksW(xlpFile);
919
920 /* Clear any trailing periods */
921 SIZE_T i = wcslen(xlpFile);
922 while (i > 0 && xlpFile[i - 1] == '.')
923 {
924 xlpFile[--i] = '\0';
925 }
926
927 lstrcpyW(lpResult, xlpFile);
928 /* The file was found in lpPath or one of the directories in the system-wide search path */
929 }
930 else
931 {
932 xlpFile[0] = '\0';
933 }
934
935 attribs = GetFileAttributesW(lpFile);
937 {
938 wcscpy(classname, L"Folder");
939 }
940 else
941 {
942 /* Did we get something? Anything? */
943 if (xlpFile[0] == 0)
944 {
945 TRACE("Returning SE_ERR_FNF\n");
946 return SE_ERR_FNF;
947 }
948 /* First thing we need is the file's extension */
949 extension = wcsrchr(xlpFile, '.'); /* Assume last "." is the one; */
950 /* File->Run in progman uses */
951 /* .\FILE.EXE :( */
952 TRACE("xlpFile=%s,extension=%s\n", debugstr_w(xlpFile), debugstr_w(extension));
953
954 if (extension == NULL || extension[1] == 0)
955 {
956 WARN("Returning SE_ERR_NOASSOC\n");
957 return SE_ERR_NOASSOC;
958 }
959
960 /* Three places to check: */
961 /* 1. win.ini, [windows], programs (NB no leading '.') */
962 /* 2. Registry, HKEY_CLASS_ROOT<classname>\shell\open\command */
963 /* 3. win.ini, [extensions], extension (NB no leading '.' */
964 /* All I know of the order is that registry is checked before */
965 /* extensions; however, it'd make sense to check the programs */
966 /* section first, so that's what happens here. */
967
968 /* See if it's a program - if GetProfileString fails, we skip this
969 * section. Actually, if GetProfileString fails, we've probably
970 * got a lot more to worry about than running a program... */
971 if (GetProfileStringW(L"windows", L"programs", L"exe pif bat cmd com", wBuffer, ARRAY_SIZE(wBuffer)) > 0)
972 {
973 CharLowerW(wBuffer);
974 tok = wBuffer;
975 while (*tok)
976 {
977 WCHAR *p = tok;
978 while (*p && *p != ' ' && *p != '\t') p++;
979 if (*p)
980 {
981 *p++ = 0;
982 while (*p == ' ' || *p == '\t') p++;
983 }
984
985 if (_wcsicmp(tok, &extension[1]) == 0) /* have to skip the leading "." */
986 {
987 wcscpy(lpResult, xlpFile);
988 /* Need to perhaps check that the file has a path
989 * attached */
990 TRACE("found %s\n", debugstr_w(lpResult));
991 return 33;
992 /* Greater than 32 to indicate success */
993 }
994 tok = p;
995 }
996 }
997
998 /* Check registry */
1000 &classnamelen) == ERROR_SUCCESS)
1001 {
1002 classnamelen /= sizeof(WCHAR);
1003 if (classnamelen == ARRAY_SIZE(classname))
1004 classnamelen--;
1005
1006 classname[classnamelen] = '\0';
1007 TRACE("File type: %s\n", debugstr_w(classname));
1008 }
1009 else
1010 {
1011 *classname = '\0';
1012 }
1013 }
1014
1015 if (*classname)
1016 {
1017 /* pass the verb string to SHELL_FindExecutableByVerb() */
1019
1020 if (retval > 32)
1021 {
1022 DWORD finishedLen;
1023 SHELL_ArgifyW(lpResult, resultLen, command, xlpFile, pidl, args, &finishedLen, lpPath);
1024 if (finishedLen > resultLen)
1025 ERR("Argify buffer not large enough.. truncated\n");
1026 /* Remove double quotation marks and command line arguments */
1027 if (*lpResult == '"')
1028 {
1029 WCHAR *p = lpResult;
1030 while (*(p + 1) != '"')
1031 {
1032 *p = *(p + 1);
1033 p++;
1034 }
1035 *p = '\0';
1036 }
1037 else
1038 {
1039 /* Truncate on first space */
1040 WCHAR *p = lpResult;
1041 while (*p != ' ' && *p != '\0')
1042 p++;
1043 *p = '\0';
1044 }
1045 }
1046 }
1047 else /* Check win.ini */
1048 {
1049 /* Toss the leading dot */
1050 extension++;
1051 if (GetProfileStringW(L"extensions", extension, L"", command, ARRAY_SIZE(command)) > 0)
1052 {
1053 if (wcslen(command) != 0)
1054 {
1055 wcscpy(lpResult, command);
1056 tok = wcschr(lpResult, '^'); /* should be ^.extension? */
1057 if (tok != NULL)
1058 {
1059 tok[0] = '\0';
1060 wcscat(lpResult, xlpFile); /* what if no dir in xlpFile? */
1061 tok = wcschr(command, '^'); /* see above */
1062 if ((tok != NULL) && (wcslen(tok) > 5))
1063 {
1064 wcscat(lpResult, &tok[5]);
1065 }
1066 }
1067 retval = 33; /* FIXME - see above */
1068 }
1069 }
1070 }
1071
1072 TRACE("returning path %s, retval %d\n", debugstr_w(lpResult), retval);
1073 return retval;
1074}
#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
void WINAPI PathRemoveBlanksW(WCHAR *path)
Definition: path.c:1853
LPWSTR WINAPI CharLowerW(WCHAR *str)
Definition: string.c:1092
BOOL WINAPI PathFindOnPathW(LPWSTR lpszFile, LPCWSTR *lppszOtherDirs)
Definition: path.c:1409
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:735

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 795 of file shlexec.cpp.

796{
797 HKEY hkeyClass;
798 WCHAR verb[MAX_PATH];
799
801 return SE_ERR_NOASSOC;
802 if (!HCR_GetDefaultVerbW(hkeyClass, lpVerb, verb, ARRAY_SIZE(verb)))
803 return SE_ERR_NOASSOC;
804 RegCloseKey(hkeyClass);
805
806 /* Looking for ...buffer\shell<verb>\command */
807 wcscat(classname, L"\\shell\\"); // FIXME: Use HCR_GetExecuteCommandW or AssocAPI
808 wcscat(classname, verb);
809 wcscat(classname, L"\\command");
810
812 &commandlen) == ERROR_SUCCESS)
813 {
814 commandlen /= sizeof(WCHAR);
815 if (key) wcscpy(key, classname);
816#if 0
817 LPWSTR tmp;
818 WCHAR param[256];
819 LONG paramlen = sizeof(param);
820
821 /* FIXME: it seems all Windows version don't behave the same here.
822 * the doc states that this ddeexec information can be found after
823 * the exec names.
824 * on Win98, it doesn't appear, but I think it does on Win2k
825 */
826 /* Get the parameters needed by the application
827 from the associated ddeexec key */
828 tmp = strstrW(classname, L"\\command");
829 tmp[0] = '\0';
830 wcscat(classname, wDdeexec);
832 &paramlen) == ERROR_SUCCESS)
833 {
834 paramlen /= sizeof(WCHAR);
835 wcscat(command, L" ");
837 commandlen += paramlen;
838 }
839#endif
840
841 command[commandlen] = '\0';
842
843 return 33; /* FIXME see SHELL_FindExecutable() */
844 }
845
846 return SE_ERR_NOASSOC;
847}
#define RegCloseKey(hKey)
Definition: registry.h:49
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
#define KEY_READ
Definition: nt_native.h:1023
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 551 of file shlexec.cpp.

552{
553 STRRET strret;
554 CComPtr<IShellFolder> desktop;
555
556 HRESULT hr = SHGetDesktopFolder(&desktop);
557
558 if (SUCCEEDED(hr))
559 {
560 hr = desktop->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &strret);
561
562 if (SUCCEEDED(hr))
563 StrRetToStrNW(pszPath, uOutSize, &strret, pidl);
564 }
565
566 return hr;
567}
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 73 of file shlexec.cpp.

74{
75 WCHAR szModule[MAX_PATH];
76 static INT s_bInDllProcess = -1;
77
78 if (s_bInDllProcess != -1)
79 return s_bInDllProcess;
80
81 s_bInDllProcess = GetModuleFileNameW(NULL, szModule, _countof(szModule)) &&
82 (StrStrIW(PathFindFileNameW(szModule), L"rundll") != NULL);
83 return s_bInDllProcess;
84}
LPWSTR WINAPI StrStrIW(LPCWSTR lpszStr, LPCWSTR lpszSearch)
Definition: string.c:380
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:600
WCHAR *WINAPI PathFindFileNameW(const WCHAR *path)
Definition: path.c:1644

Referenced by ShellExec_RunDLL_Helper(), and ShellExecuteExW().

◆ SHELL_InvokePidl()

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

Definition at line 1874 of file shlexec.cpp.

1877{
1878 // Bind pidl
1879 CComPtr<IShellFolder> psfFolder;
1880 LPCITEMIDLIST pidlLast;
1881 HRESULT hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &psfFolder), &pidlLast);
1883 return FALSE;
1884
1885 // Get the context menu to invoke a command
1887 hr = psfFolder->GetUIObjectOf(NULL, 1, &pidlLast, IID_NULL_PPV_ARG(IContextMenu, &pCM));
1889 return FALSE;
1890
1891 // Invoke a command
1892 CMINVOKECOMMANDINFO ici = { sizeof(ici) };
1893 ici.fMask = (sei->fMask & SEE_CMIC_COMMON_BASICFLAGS) & ~CMIC_MASK_UNICODE; // FIXME: Unicode?
1894 ici.nShow = sei->nShow;
1895 ici.hwnd = sei->hwnd;
1896 char szVerb[VERBKEY_CCHMAX];
1897 if (sei->lpVerb && sei->lpVerb[0])
1898 {
1899 WideCharToMultiByte(CP_ACP, 0, sei->lpVerb, -1, szVerb, _countof(szVerb), NULL, NULL);
1900 szVerb[_countof(szVerb) - 1] = ANSI_NULL; // Avoid buffer overrun
1901 ici.lpVerb = szVerb;
1902 }
1903 else // The default verb?
1904 {
1905 HMENU hMenu = CreatePopupMenu();
1906 const INT idCmdFirst = 1, idCmdLast = 0x7FFF;
1907 hr = pCM->QueryContextMenu(hMenu, 0, idCmdFirst, idCmdLast, CMF_DEFAULTONLY);
1909 {
1910 DestroyMenu(hMenu);
1911 return FALSE;
1912 }
1913
1914 INT nDefaultID = GetMenuDefaultItem(hMenu, FALSE, 0);
1915 DestroyMenu(hMenu);
1916 if (nDefaultID == -1)
1917 nDefaultID = idCmdFirst;
1918
1919 ici.lpVerb = MAKEINTRESOURCEA(nDefaultID - idCmdFirst);
1920 }
1921 hr = pCM->InvokeCommand(&ici);
1922
1923 return !FAILED_UNEXPECTEDLY(hr);
1924}
#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
HRESULT WINAPI SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCITEMIDLIST *ppidlLast)
Definition: pidl.c:1498
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  wszKeyname,
LPCWSTR  wszApplicationName,
LPWSTR  env,
LPSHELLEXECUTEINFOW  psei,
LPSHELLEXECUTEINFOW  psei_out,
SHELL_ExecuteW32  execfunc 
)
static

Definition at line 1926 of file shlexec.cpp.

1927{
1929 DWORD len;
1931
1932 /* Length of quotes plus length of command plus NULL terminator */
1933 len = 2 + lstrlenW(wcmd) + 1;
1934 if (wszParameters[0])
1935 {
1936 /* Length of space plus length of parameters */
1937 len += 1 + lstrlenW(wszParameters);
1938 }
1939 wszQuotedCmd.Allocate(len);
1940 /* Must quote to handle case where cmd contains spaces,
1941 * else security hole if malicious user creates executable file "C:\\Program"
1942 */
1943 strcpyW(wszQuotedCmd, L"\"");
1944 strcatW(wszQuotedCmd, wcmd);
1945 strcatW(wszQuotedCmd, L"\"");
1946 if (wszParameters[0])
1947 {
1948 strcatW(wszQuotedCmd, L" ");
1949 strcatW(wszQuotedCmd, wszParameters);
1950 }
1951
1952 TRACE("%s/%s => %s/%s\n", debugstr_w(wszApplicationName), debugstr_w(psei->lpVerb), debugstr_w(wszQuotedCmd), debugstr_w(wszKeyname));
1953
1954 if (*wszKeyname)
1955 retval = execute_from_key(wszKeyname, wszApplicationName, env, psei->lpParameters, wcmd, execfunc, psei, psei_out);
1956 else
1957 retval = execfunc(wszQuotedCmd, env, FALSE, psei, psei_out);
1958
1959 return retval;
1960}

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 1818 of file shlexec.cpp.

1819{
1821 BOOL appKnownSingular = FALSE;
1822
1823 /* last chance to translate IDList: now also allow CLSID paths */
1825 if (buffer[0] == ':' && buffer[1] == ':') {
1826 /* open shell folder for the specified class GUID */
1827 if (strlenW(buffer) + 1 > parametersLen)
1828 ERR("parameters len exceeds buffer size (%i > %i), truncating\n",
1829 lstrlenW(buffer) + 1, parametersLen);
1830 lstrcpynW(wszParameters, buffer, parametersLen);
1831 if (strlenW(L"explorer.exe") > dwApplicationNameLen)
1832 ERR("application len exceeds buffer size (%i), truncating\n",
1833 dwApplicationNameLen);
1834 lstrcpynW(wszApplicationName, L"explorer.exe", dwApplicationNameLen);
1835 appKnownSingular = TRUE;
1836
1837 sei->fMask &= ~SEE_MASK_INVOKEIDLIST;
1838 } else {
1840 DWORD attribs;
1841 DWORD resultLen;
1842 /* Check if we're executing a directory and if so use the
1843 handler for the Folder class */
1848 HCR_GetExecuteCommandW(0, L"Folder",
1849 sei->lpVerb,
1850 buffer, sizeof(buffer))) {
1851 SHELL_ArgifyW(wszApplicationName, dwApplicationNameLen,
1852 buffer, target, (LPITEMIDLIST)sei->lpIDList, NULL, &resultLen,
1853 !StrIsNullOrEmpty(sei->lpDirectory) ? sei->lpDirectory : NULL);
1854 if (resultLen > dwApplicationNameLen)
1855 ERR("Argify buffer not large enough... truncating\n"); // FIXME: Report this to the caller?
1856 appKnownSingular = FALSE;
1857 // HACKFIX: We really want the !appKnownSingular code in SHELL_execute to split the
1858 // parameters for us but we cannot guarantee that the exe in the registry is quoted.
1859 // We have now turned 'explorer.exe "%1" into 'explorer.exe "c:\path\from\pidl"' and
1860 // need to split to application and parameters.
1861 LPCWSTR params = PathGetArgsW(wszApplicationName);
1862 lstrcpynW(wszParameters, params, parametersLen);
1863 PathRemoveArgsW(wszApplicationName);
1864 PathUnquoteSpacesW(wszApplicationName);
1865 appKnownSingular = TRUE;
1866 }
1867 sei->fMask &= ~SEE_MASK_INVOKEIDLIST;
1868 }
1869 }
1870 return appKnownSingular;
1871}
#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:551
#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 735 of file shlexec.cpp.

736{
737 HKEY hkApp = NULL;
738 WCHAR buffer[1024];
739 DWORD len, dwType;
740 LONG res;
741 BOOL found = FALSE;
742
743 if (env) *env = NULL;
744 wcscpy(buffer, L"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\");
747 if (res)
748 {
749 // Add ".exe" extension, if extension does not exists
750 if (PathAddExtensionW(buffer, L".exe"))
751 {
753 }
754 if (res) goto end;
755 }
756
757 len = MAX_PATH * sizeof(WCHAR);
758 res = SHRegQueryValueExW(hkApp, NULL, NULL, &dwType, (LPBYTE)lpResult, &len);
759 if (res != ERROR_SUCCESS || dwType != REG_SZ)
760 goto end;
761
762 found = TRUE;
763
764 if (env)
765 {
766 len = sizeof(buffer);
767 res = SHRegQueryValueExW(hkApp, L"Path", NULL, &dwType, (LPBYTE)buffer, &len);
768 if (res == ERROR_SUCCESS && dwType == REG_SZ && buffer[0])
770 }
771
772end:
773 if (hkApp) RegCloseKey(hkApp);
774 return found;
775}
GLuint GLuint end
Definition: gl.h:1545
#define REG_SZ
Definition: layer.c:22
#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:677
#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 1609 of file shlexec.cpp.

1610{
1611 CComHeapPtr<ITEMIDLIST> allocatedPidl;
1612 LPITEMIDLIST pidl = NULL;
1613
1614 if (sei->lpIDList)
1615 {
1616 pidl = (LPITEMIDLIST)sei->lpIDList;
1617 }
1618 else
1619 {
1620 SFGAOF sfga = 0;
1621 HRESULT hr = SHParseDisplayName(sei->lpFile, NULL, &allocatedPidl, SFGAO_STORAGECAPMASK, &sfga);
1622 if (FAILED(hr))
1623 {
1624 WCHAR Buffer[MAX_PATH] = {};
1625 // FIXME: MAX_PATH.....
1627 if (retval <= 32)
1628 return HRESULT_FROM_WIN32(retval);
1629
1630 hr = SHParseDisplayName(Buffer, NULL, &allocatedPidl, SFGAO_STORAGECAPMASK, &sfga);
1631 // This should not happen, we found it...
1633 return hr;
1634 }
1635
1636 pidl = allocatedPidl;
1637 }
1638
1640 LPCITEMIDLIST pidllast = NULL;
1641 HRESULT hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &shf), &pidllast);
1642 if (FAILED(hr))
1643 return hr;
1644
1645 return shf->GetUIObjectOf(NULL, 1, &pidllast, IID_NULL_PPV_ARG(IContextMenu, &cm));
1646}
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 1481 of file shlexec.cpp.

1482{
1483 CComHeapPtr<ITEMIDLIST> allocatedPidl;
1484 LPITEMIDLIST pidl = NULL;
1485
1486 if (sei->fMask & SEE_MASK_CLASSALL) // FIXME: This makes no sense? SEE_MASK_IDLIST?
1487 {
1488 pidl = (LPITEMIDLIST)sei->lpIDList;
1489 }
1490 else
1491 {
1492 WCHAR fullpath[MAX_PATH];
1493 BOOL ret;
1494
1495 fullpath[0] = 0;
1496 ret = GetFullPathNameW(sei->lpFile, MAX_PATH, fullpath, NULL);
1497 if (!ret)
1499
1500 pidl = ILCreateFromPathW(fullpath);
1501 allocatedPidl.Attach(pidl);
1502 }
1504}
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:1102

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 1575 of file shlexec.cpp.

1576{
1577 TRACE("%p %s %p\n", hkey, debugstr_guid(guid), sei);
1578
1579 CCoInit coInit;
1580
1581 if (FAILED_UNEXPECTEDLY(coInit.hr))
1582 return coInit.hr;
1583
1585 HRESULT hr = CoCreateInstance(*guid, NULL, CLSCTX_INPROC_SERVER,
1588 return hr;
1589
1590 CComPtr<IDataObject> dataobj;
1591 hr = shellex_get_dataobj(sei, dataobj);
1593 return hr;
1594
1595 hr = obj->Initialize(NULL, dataobj, hkey);
1597 return hr;
1598
1600 hr = obj->QueryInterface(IID_PPV_ARG(IObjectWithSite, &ows));
1602 return hr;
1603
1604 ows->SetSite(NULL);
1605
1607}
GUID guid
Definition: version.c:147
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
static HRESULT shellex_run_context_menu_default(IShellExtInit *obj, LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:1506
static HRESULT shellex_get_dataobj(LPSHELLEXECUTEINFOW sei, CComPtr< IDataObject > &dataObj)
Definition: shlexec.cpp:1481

Referenced by ShellExecute_FromContextMenuHandlers().

◆ shellex_run_context_menu_default()

static HRESULT shellex_run_context_menu_default ( IShellExtInit obj,
LPSHELLEXECUTEINFOW  sei 
)
static

Definition at line 1506 of file shlexec.cpp.

1508{
1510 CMINVOKECOMMANDINFOEX ici;
1512 WCHAR string[0x80];
1513 INT i, n, def = -1;
1514 HMENU hmenu = 0;
1515 HRESULT r;
1516
1517 TRACE("%p %p\n", obj, sei);
1518
1519 r = obj->QueryInterface(IID_PPV_ARG(IContextMenu, &cm));
1520 if (FAILED(r))
1521 return r;
1522
1523 hmenu = CreateMenu();
1524 if (!hmenu)
1525 goto end;
1526
1527 /* the number of the last menu added is returned in r */
1528 r = cm->QueryContextMenu(hmenu, 0, 0x20, 0x7fff, CMF_DEFAULTONLY);
1529 if (FAILED(r))
1530 goto end;
1531
1533 for (i = 0; i < n; i++)
1534 {
1535 memset(&info, 0, sizeof(info));
1536 info.cbSize = sizeof info;
1538 info.dwTypeData = string;
1539 info.cch = sizeof string;
1540 string[0] = 0;
1542
1543 TRACE("menu %d %s %08x %08lx %08x %08x\n", i, debugstr_w(string),
1544 info.fState, info.dwItemData, info.fType, info.wID);
1545 if ((!sei->lpVerb && (info.fState & MFS_DEFAULT)) ||
1546 (sei->lpVerb && !lstrcmpiW(sei->lpVerb, string)))
1547 {
1548 def = i;
1549 break;
1550 }
1551 }
1552
1553 r = E_FAIL;
1554 if (def == -1)
1555 goto end;
1556
1557 memset(&ici, 0, sizeof ici);
1558 ici.cbSize = sizeof ici;
1559 ici.fMask = (sei->fMask & SEE_CMIC_COMMON_BASICFLAGS) | CMIC_MASK_UNICODE;
1560 ici.nShow = sei->nShow;
1561 ici.lpVerb = MAKEINTRESOURCEA(def);
1562 ici.hwnd = sei->hwnd;
1563 ici.lpParametersW = sei->lpParameters;
1564
1565 r = cm->InvokeCommand((LPCMINVOKECOMMANDINFO)&ici);
1566
1567 TRACE("invoke command returned %08x\n", r);
1568
1569end:
1570 if (hmenu)
1571 DestroyMenu( hmenu );
1572 return r;
1573}
#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 3184 of file shlexec.cpp.

3189{
3190 TRACE("(%p, %p, %s, 0x%X)\n", hwnd, hInstance, wine_dbgstr_w(pszCmdLine), nCmdShow);
3191
3192 if (!pszCmdLine || !*pszCmdLine)
3193 return;
3194
3195 // '?' enables us to specify the additional mask value
3196 ULONG fNewMask = SEE_MASK_NOASYNC;
3197 if (*pszCmdLine == L'?') // 1st question
3198 {
3199 INT MaskValue;
3200 if (StrToIntExW(pszCmdLine + 1, STIF_SUPPORT_HEX, &MaskValue))
3201 fNewMask |= MaskValue;
3202
3203 PCWSTR pch2ndQuestion = StrChrW(pszCmdLine + 1, L'?'); // 2nd question
3204 if (pch2ndQuestion)
3205 pszCmdLine = pch2ndQuestion + 1;
3206 }
3207
3208 WCHAR szPath[2 * MAX_PATH];
3210 if (PathProcessCommandW(pszCmdLine, szPath, _countof(szPath), dwFlags) == -1)
3211 StrCpyNW(szPath, pszCmdLine, _countof(szPath));
3212
3213 // Split arguments from the path
3215 if (*Args)
3216 *(Args - 1) = UNICODE_NULL;
3217
3219
3220 // Execute
3221 SHELLEXECUTEINFOW execInfo = { sizeof(execInfo) };
3222 execInfo.fMask = fNewMask;
3223 execInfo.hwnd = hwnd;
3224 execInfo.lpFile = szPath;
3225 execInfo.lpParameters = Args;
3226 execInfo.nShow = nCmdShow;
3227 if (!ShellExecuteExW(&execInfo))
3228 {
3229 DWORD dwError = GetLastError();
3230 if (SHELL_InRunDllProcess()) // Is it a RUNDLL process?
3231 ExitProcess(dwError); // Terminate it now
3232 }
3233}
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(const WCHAR *str, DWORD flags, INT *ret)
Definition: string.c:972
WCHAR *WINAPI StrCpyNW(WCHAR *dst, const WCHAR *src, int count)
Definition: string.c:462
#define SEE_MASK_NOASYNC
Definition: shellapi.h:35
EXTERN_C LONG PathProcessCommandW(_In_ PCWSTR pszSrc, _Out_writes_opt_(dwBuffSize) PWSTR pszDest, _In_ INT cchDest, _In_ DWORD dwFlags)
Definition: shlexec.cpp:3068
static BOOL SHELL_InRunDllProcess(VOID)
Definition: shlexec.cpp:73
#define PPCF_INCLUDEARGS
Definition: shlobj.h:2425
#define STIF_SUPPORT_HEX
Definition: shlwapi.h:1498

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 3242 of file shlexec.cpp.

3247{
3248 CStringW strCmdLine = pszCmdLine; // Keep
3249 ShellExec_RunDLL_Helper(hwnd, hInstance, strCmdLine, nCmdShow);
3250}
static VOID ShellExec_RunDLL_Helper(_In_opt_ HWND hwnd, _In_opt_ HINSTANCE hInstance, _In_ PCWSTR pszCmdLine, _In_ INT nCmdShow)
Definition: shlexec.cpp:3184

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 3259 of file shlexec.cpp.

3264{
3265 ShellExec_RunDLL_Helper(hwnd, hInstance, pszCmdLine, nCmdShow);
3266}

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 2744 of file shlexec.cpp.

2751{
2754 LPCWSTR pszVerb = NULL;
2755 WCHAR szFile[MAX_PATH], szFile2[MAX_PATH];
2756 HRESULT hr;
2757 LPCWSTR pchParams;
2758 LPWSTR lpCommand = NULL;
2759
2760 if (pwszCommand == NULL)
2762 1, (ULONG_PTR*)pwszCommand);
2763
2764 __SHCloneStrW(&lpCommand, pwszCommand);
2765 StrTrimW(lpCommand, L" \t");
2766
2767 if (dwSeclFlags & SECL_NO_UI)
2769 if (dwSeclFlags & SECL_LOG_USAGE)
2771 if (dwSeclFlags & SECL_USE_IDLIST)
2773
2774 if (dwSeclFlags & SECL_RUNAS)
2775 {
2776 dwSize = 0;
2777 hr = AssocQueryStringW(ASSOCF_NONE, ASSOCSTR_COMMAND, lpCommand, L"runas", NULL, &dwSize);
2778 if (SUCCEEDED(hr) && dwSize != 0)
2779 {
2780 pszVerb = L"runas";
2781 }
2782 }
2783
2784 if (PathIsURLW(lpCommand) || UrlIsW(lpCommand, URLIS_APPLIABLE))
2785 {
2786 StringCchCopyW(szFile, _countof(szFile), lpCommand);
2787 pchParams = NULL;
2788 }
2789 else
2790 {
2791 PCWSTR apPathList[2];
2792
2793 pchParams = SplitParams(lpCommand, szFile, _countof(szFile));
2794 if (szFile[0] != UNICODE_NULL && szFile[1] == L':' &&
2795 szFile[2] == UNICODE_NULL)
2796 {
2797 PathAddBackslashW(szFile);
2798 }
2799
2800 WCHAR szCurDir[MAX_PATH];
2801 GetCurrentDirectoryW(_countof(szCurDir), szCurDir);
2802 if (pwszStartDir)
2803 {
2804 SetCurrentDirectoryW(pwszStartDir);
2805 }
2806
2807 if ((PathIsRelativeW(szFile) &&
2808 GetFullPathNameW(szFile, _countof(szFile2), szFile2, NULL) &&
2809 PathFileExistsW(szFile2)) ||
2810 SearchPathW(NULL, szFile, NULL, _countof(szFile2), szFile2, NULL))
2811 {
2812 StringCchCopyW(szFile, _countof(szFile), szFile2);
2813 }
2814
2815 apPathList[0] = pwszStartDir;
2816 apPathList[1] = NULL;
2817 PathFindOnPathExW(szFile, apPathList, WHICH_DEFAULT);
2818
2819 if (!(dwSeclFlags & SECL_ALLOW_NONEXE))
2820 {
2821 if (!GetBinaryTypeW(szFile, &dwType))
2822 {
2823 SHFree(lpCommand);
2824
2825 if (!(dwSeclFlags & SECL_NO_UI))
2826 {
2827 WCHAR szText[128 + MAX_PATH], szFormat[128];
2829 StringCchPrintfW(szText, _countof(szText), szFormat, szFile);
2830 MessageBoxW(hwnd, szText, NULL, MB_ICONERROR);
2831 }
2832 return CO_E_APPNOTFOUND;
2833 }
2834 }
2835 else
2836 {
2838 {
2839 SHFree(lpCommand);
2840
2841 if (!(dwSeclFlags & SECL_NO_UI))
2842 {
2843 WCHAR szText[128 + MAX_PATH], szFormat[128];
2845 StringCchPrintfW(szText, _countof(szText), szFormat, szFile);
2846 MessageBoxW(hwnd, szText, NULL, MB_ICONERROR);
2847 }
2849 }
2850 }
2851 }
2852
2853 ZeroMemory(&info, sizeof(info));
2854 info.cbSize = sizeof(info);
2855 info.fMask = dwFlags;
2856 info.hwnd = hwnd;
2857 info.lpVerb = pszVerb;
2858 info.lpFile = szFile;
2859 info.lpParameters = (pchParams && *pchParams) ? pchParams : NULL;
2860 info.lpDirectory = pwszStartDir;
2861 info.nShow = nShow;
2863 SHFree(lpCommand);
2864 return HRESULT_FROM_WIN32(error);
2865}
#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 UrlIsW(const WCHAR *url, URLIS Urlis)
Definition: path.c:4755
BOOL WINAPI PathFileExistsW(const WCHAR *path)
Definition: path.c:2550
BOOL WINAPI StrTrimW(WCHAR *str, const WCHAR *trim)
Definition: string.c:796
BOOL WINAPI PathFindOnPathExW(LPWSTR lpszFile, LPCWSTR *lppszOtherDirs, DWORD dwWhich)
Definition: path.c:1357
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
#define SEE_MASK_FLAG_LOG_USAGE
Definition: shellapi.h:55
static LPCWSTR SplitParams(LPCWSTR psz, LPWSTR pszArg0, size_t cchArg0)
Definition: shlexec.cpp:2698
@ ASSOCSTR_COMMAND
Definition: shlwapi.h:612
@ URLIS_APPLIABLE
Definition: shlwapi.h:1238
#define WHICH_DEFAULT
#define IDS_FILE_NOT_FOUND
Definition: shresdef.h:369
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:344
#define CO_E_APPNOTFOUND
Definition: winerror.h:2808

◆ ShellExecute_ContextMenuVerb()

static HRESULT ShellExecute_ContextMenuVerb ( LPSHELLEXECUTEINFOW  sei)
static

Definition at line 1648 of file shlexec.cpp.

1649{
1650 TRACE("%p\n", sei);
1651
1652 CCoInit coInit;
1653
1654 if (FAILED_UNEXPECTEDLY(coInit.hr))
1655 return coInit.hr;
1656
1660 return hr;
1661
1662 CComHeapPtr<char> verb, parameters, dir;
1663 __SHCloneStrWtoA(&verb, sei->lpVerb);
1664 __SHCloneStrWtoA(&parameters, sei->lpParameters);
1666
1667 BOOL fDefault = StrIsNullOrEmpty(sei->lpVerb);
1668 CMINVOKECOMMANDINFOEX ici = { sizeof(ici) };
1669 ici.fMask = SeeFlagsToCmicFlags(sei->fMask) | CMIC_MASK_UNICODE;
1670 ici.nShow = sei->nShow;
1671 if (!fDefault)
1672 {
1673 ici.lpVerb = verb;
1674 ici.lpVerbW = sei->lpVerb;
1675 }
1676 ici.hwnd = sei->hwnd;
1677 ici.lpParameters = parameters;
1678 ici.lpParametersW = sei->lpParameters;
1679 ici.lpDirectory = dir;
1680 ici.lpDirectoryW = sei->lpDirectory;
1681 ici.dwHotKey = sei->dwHotKey;
1682 ici.hIcon = sei->hIcon;
1683 if (ici.fMask & (CMIC_MASK_HASLINKNAME | CMIC_MASK_HASTITLE))
1684 ici.lpTitleW = sei->lpClass;
1685
1686 enum { idFirst = 1, idLast = 0x7fff };
1687 HMENU hMenu = CreatePopupMenu();
1688 // Note: Windows does not pass CMF_EXTENDEDVERBS so "hidden" verbs cannot be executed
1689 hr = cm->QueryContextMenu(hMenu, 0, idFirst, idLast, fDefault ? CMF_DEFAULTONLY : 0);
1690 if (!FAILED_UNEXPECTEDLY(hr))
1691 {
1692 if (fDefault)
1693 {
1694 INT uDefault = GetMenuDefaultItem(hMenu, FALSE, 0);
1695 uDefault = (uDefault != -1) ? uDefault - idFirst : 0;
1696 ici.lpVerb = MAKEINTRESOURCEA(uDefault);
1697 ici.lpVerbW = MAKEINTRESOURCEW(uDefault);
1698 }
1699
1700 hr = cm->InvokeCommand((LPCMINVOKECOMMANDINFO)&ici);
1701 if (!FAILED_UNEXPECTEDLY(hr))
1702 hr = S_OK;
1703 }
1704
1705 DestroyMenu(hMenu);
1706
1707 return hr;
1708}
unsigned int dir
Definition: maze.c:112
static __inline void __SHCloneStrWtoA(char **target, const WCHAR *source)
Definition: shell32_main.h:176
static HRESULT shellex_get_contextmenu(LPSHELLEXECUTEINFOW sei, CComPtr< IContextMenu > &cm)
Definition: shlexec.cpp:1609
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582

Referenced by SHELL_execute().

◆ ShellExecute_FromContextMenuHandlers()

static LONG ShellExecute_FromContextMenuHandlers ( LPSHELLEXECUTEINFOW  sei)
static

Definition at line 1714 of file shlexec.cpp.

1715{
1716 HKEY hkey, hkeycm = 0;
1717 WCHAR szguid[39];
1718 HRESULT hr;
1719 GUID guid;
1720 DWORD i;
1721 LONG r;
1722
1723 TRACE("%s\n", debugstr_w(sei->lpFile));
1724
1725 hkey = ShellExecute_GetClassKey(sei);
1726 if (!hkey)
1727 return ERROR_FUNCTION_FAILED;
1728
1729 // FIXME: Words cannot describe how broken this is, all of it needs to die
1730 r = RegOpenKeyW(hkey, L"shellex\\ContextMenuHandlers", &hkeycm);
1731 if (r == ERROR_SUCCESS)
1732 {
1733 i = 0;
1734 while (1)
1735 {
1736 r = RegEnumKeyW(hkeycm, i++, szguid, ARRAY_SIZE(szguid));
1737 if (r != ERROR_SUCCESS)
1738 break;
1739
1740 hr = CLSIDFromString(szguid, &guid);
1741 if (SUCCEEDED(hr))
1742 {
1743 /* stop at the first one that succeeds in running */
1744 hr = shellex_load_object_and_run(hkey, &guid, sei);
1745 if (SUCCEEDED(hr))
1746 break;
1747 }
1748 }
1749 RegCloseKey(hkeycm);
1750 }
1751
1752 if (hkey != sei->hkeyClass)
1753 RegCloseKey(hkey);
1754 return r;
1755}
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:1575
static HKEY ShellExecute_GetClassKey(const SHELLEXECUTEINFOW *sei)
Definition: shlexec.cpp:1462
#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 1462 of file shlexec.cpp.

1463{
1465 return sei->hkeyClass;
1466
1467 HKEY hKey = NULL;
1468 if (sei->fMask & SEE_MASK_CLASSNAME)
1469 {
1470 TRACE("class = %s\n", debugstr_w(sei->lpClass));
1472 return hKey;
1473 }
1475 TRACE("ext = %s\n", debugstr_w(ext));
1476 if (!StrIsNullOrEmpty(ext) && SUCCEEDED(HCR_GetProgIdKeyOfExtension(ext, &hKey, FALSE)))
1477 return hKey;
1478 return NULL;
1479}
static const WCHAR *const ext[]
Definition: module.c:53
LPWSTR WINAPI PathFindExtensionW(const WCHAR *path)
Definition: path.c:1217
FxAutoRegKey hKey
HRESULT HCR_GetProgIdKeyOfExtension(PCWSTR szExtension, PHKEY phKey, BOOL AllowFallback)
Definition: classes.c:55

Referenced by ShellExecute_FromContextMenuHandlers().

◆ ShellExecute_Normal()

static DWORD ShellExecute_Normal ( _Inout_ LPSHELLEXECUTEINFOW  sei)
static

Definition at line 2466 of file shlexec.cpp.

2467{
2468 // FIXME
2469 if (SHELL_execute(sei, SHELL_ExecuteW))
2470 return ERROR_SUCCESS;
2472#if DBG
2473 if (!err)
2474 DbgPrint("FIXME: Failed with error 0 on '%ls'\n", sei->lpFile);
2475#endif
2476 return err ? err : ERROR_FILE_NOT_FOUND;
2477}
#define DbgPrint
Definition: hal.h:12
static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
Definition: shlexec.cpp:2038
static UINT_PTR SHELL_ExecuteW(const WCHAR *lpCmd, WCHAR *env, BOOL shWait, const SHELLEXECUTEINFOW *psei, LPSHELLEXECUTEINFOW psei_out)
Definition: shlexec.cpp:573

Referenced by ShellExecuteExW().

◆ ShellExecute_ShowError()

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

Definition at line 2480 of file shlexec.cpp.

2484{
2485 // FIXME: Show error message
2486}

Referenced by ShellExecuteExW().

◆ ShellExecuteA()

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

Definition at line 2436 of file shlexec.cpp.

2438{
2440
2441 TRACE("%p,%s,%s,%s,%s,%d\n",
2442 hWnd, debugstr_a(lpVerb), debugstr_a(lpFile),
2443 debugstr_a(lpParameters), debugstr_a(lpDirectory), iShowCmd);
2444
2445 sei.cbSize = sizeof(sei);
2447 sei.hwnd = hWnd;
2448 sei.lpVerb = lpVerb;
2449 sei.lpFile = lpFile;
2450 sei.lpParameters = lpParameters;
2452 sei.nShow = iShowCmd;
2453 sei.lpIDList = 0;
2454 sei.lpClass = 0;
2455 sei.hkeyClass = 0;
2456 sei.dwHotKey = 0;
2457 sei.hProcess = 0;
2458
2460 sei.fMask |= SEE_MASK_NOASYNC;
2461 ShellExecuteExA(&sei);
2462 return sei.hInstApp;
2463}
HWND hWnd
Definition: settings.c:17
DWORD WINAPI SHGetAppCompatFlags(DWORD dwUnknown)
Definition: ordinal.c:4732
#define SHACF_WIN95SHLEXEC

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

◆ ShellExecuteExA()

Definition at line 2494 of file shlexec.cpp.

2495{
2496 SHELLEXECUTEINFOW seiW;
2497 BOOL ret;
2498 WCHAR *wVerb = NULL, *wFile = NULL, *wParameters = NULL, *wDirectory = NULL, *wClass = NULL;
2499
2500 TRACE("%p\n", sei);
2501
2502 if (sei->cbSize != sizeof(SHELLEXECUTEINFOA))
2503 {
2506 return FALSE;
2507 }
2508
2509 memcpy(&seiW, sei, sizeof(SHELLEXECUTEINFOW));
2510
2511 seiW.cbSize = sizeof(SHELLEXECUTEINFOW);
2512
2513 if (sei->lpVerb)
2514 seiW.lpVerb = __SHCloneStrAtoW(&wVerb, sei->lpVerb);
2515
2516 if (sei->lpFile)
2517 seiW.lpFile = __SHCloneStrAtoW(&wFile, sei->lpFile);
2518
2519 if (sei->lpParameters)
2520 seiW.lpParameters = __SHCloneStrAtoW(&wParameters, sei->lpParameters);
2521
2522 if (sei->lpDirectory)
2523 seiW.lpDirectory = __SHCloneStrAtoW(&wDirectory, sei->lpDirectory);
2524
2525 if ((sei->fMask & SEE_MASK_CLASSALL) == SEE_MASK_CLASSNAME && sei->lpClass)
2526 seiW.lpClass = __SHCloneStrAtoW(&wClass, sei->lpClass);
2527 else
2528 seiW.lpClass = NULL;
2529
2530 ret = ShellExecuteExW(&seiW);
2531
2532 sei->hInstApp = seiW.hInstApp;
2533
2534 if (sei->fMask & SEE_MASK_NOCLOSEPROCESS)
2535 sei->hProcess = seiW.hProcess;
2536
2537 SHFree(wVerb);
2538 SHFree(wFile);
2539 SHFree(wParameters);
2540 SHFree(wDirectory);
2541 SHFree(wClass);
2542
2543 return ret;
2544}
struct _SHELLEXECUTEINFOW SHELLEXECUTEINFOW

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

◆ ShellExecuteExW()

Definition at line 2552 of file shlexec.cpp.

2553{
2554 HRESULT hrCoInit;
2555 DWORD dwError;
2556 ULONG fOldMask;
2557
2558 if (sei->cbSize != sizeof(SHELLEXECUTEINFOW))
2559 {
2562 return FALSE;
2563 }
2564
2565 hrCoInit = SHCoInitializeAnyApartment();
2566
2567 if (SHRegGetBoolUSValueW(L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer",
2568 L"MaximizeApps", FALSE, FALSE))
2569 {
2570 switch (sei->nShow)
2571 {
2572 case SW_SHOW:
2573 case SW_SHOWDEFAULT:
2574 case SW_SHOWNORMAL:
2575 case SW_RESTORE:
2576 sei->nShow = SW_SHOWMAXIMIZED;
2577 break;
2578 default:
2579 break;
2580 }
2581 }
2582
2583 fOldMask = sei->fMask;
2584
2585 if (!(fOldMask & SEE_MASK_NOASYNC) && SHELL_InRunDllProcess())
2587
2588 dwError = ShellExecute_Normal(sei);
2589
2590 if (dwError && dwError != ERROR_DLL_NOT_FOUND && dwError != ERROR_CANCELLED)
2591 ShellExecute_ShowError(sei, NULL, dwError);
2592
2593 sei->fMask = fOldMask;
2594
2595 if (SUCCEEDED(hrCoInit))
2597
2598 if (dwError)
2599 SetLastError(dwError);
2600
2601 return dwError == ERROR_SUCCESS;
2602}
BOOL WINAPI SHRegGetBoolUSValueW(const WCHAR *subkey, const WCHAR *value, BOOL ignore_hkcu, BOOL default_value)
Definition: registry.c:4139
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
HRESULT SHCoInitializeAnyApartment(VOID)
Definition: utils.cpp:494
#define SE_ERR_ACCESSDENIED
Definition: shellapi.h:127
#define SEE_MASK_WAITFORINPUTIDLE
Definition: shellapi.h:52
static DWORD ShellExecute_Normal(_Inout_ LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:2466
static VOID ShellExecute_ShowError(_In_ const SHELLEXECUTEINFOW *ExecInfo, _In_opt_ LPCWSTR pszCaption, _In_ DWORD dwError)
Definition: shlexec.cpp:2480
#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

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(), SH32_InvokeOpenWith(), 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 2607 of file shlexec.cpp.

2609{
2611
2612 TRACE("\n");
2613 sei.cbSize = sizeof(sei);
2615 sei.hwnd = hwnd;
2616 sei.lpVerb = lpVerb;
2617 sei.lpFile = lpFile;
2618 sei.lpParameters = lpParameters;
2620 sei.nShow = nShowCmd;
2621 sei.lpIDList = 0;
2622 sei.lpClass = 0;
2623 sei.hkeyClass = 0;
2624 sei.dwHotKey = 0;
2625 sei.hProcess = 0;
2626
2628 sei.fMask |= SEE_MASK_NOASYNC;
2629 ShellExecuteExW(&sei);
2630 return sei.hInstApp;
2631}

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 2698 of file shlexec.cpp.

2699{
2700 LPCWSTR pch;
2701 size_t ich = 0;
2702 if (*psz == L'"')
2703 {
2704 // 1st argument is quoted. the string in quotes is quoted 1st argument.
2705 // [pch] --> [pszArg0+ich]
2706 for (pch = psz + 1; *pch && ich + 1 < cchArg0; ++ich, ++pch)
2707 {
2708 if (*pch == L'"' && pch[1] == L'"')
2709 {
2710 // doubled double quotations found!
2711 pszArg0[ich] = L'"';
2712 }
2713 else if (*pch == L'"')
2714 {
2715 // single double quotation found!
2716 ++pch;
2717 break;
2718 }
2719 else
2720 {
2721 // otherwise
2722 pszArg0[ich] = *pch;
2723 }
2724 }
2725 }
2726 else
2727 {
2728 // 1st argument is unquoted. non-space sequence is 1st argument.
2729 // [pch] --> [pszArg0+ich]
2730 for (pch = psz; *pch && !iswspace(*pch) && ich + 1 < cchArg0; ++ich, ++pch)
2731 {
2732 pszArg0[ich] = *pch;
2733 }
2734 }
2735 pszArg0[ich] = 0;
2736
2737 // skip space
2738 while (iswspace(*pch))
2739 ++pch;
2740
2741 return pch;
2742}
#define iswspace(_c)
Definition: ctype.h:669

Referenced by ShellExecCmdLine().

◆ TryShellExecuteHooks()

static HRESULT TryShellExecuteHooks ( LPSHELLEXECUTEINFOW  pSEI)
static

Definition at line 122 of file shlexec.cpp.

123{
124 // https://devblogs.microsoft.com/oldnewthing/20080910-00/?p=20933 claims hooks
125 // were removed in Vista but this is incorrect, they are disabled by default.
126 // https://groups.google.com/g/microsoft.public.platformsdk.shell/c/ixdOX1--IKk
127 // says they are now controlled by the EnableShellExecuteHooks policy.
128 if (pSEI->fMask & SEE_MASK_NO_HOOKS)
129 return S_FALSE;
131 return S_FALSE;
132
134 HKEY hKey;
136 if (res != ERROR_SUCCESS)
137 return S_FALSE;
138 for (UINT i = 0; hr == S_FALSE; ++i)
139 {
140 WCHAR szClsid[42];
141 DWORD cch = _countof(szClsid);
142 if (RegEnumValueW(hKey, i, szClsid, &cch, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
143 break;
144 hr = InvokeShellExecuteHook(szClsid, pSEI);
145 }
147 return hr;
148}
LONG WINAPI RegEnumValueW(_In_ HKEY hKey, _In_ DWORD index, _Out_ LPWSTR value, _Inout_ PDWORD val_count, _Reserved_ PDWORD reserved, _Out_opt_ PDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ PDWORD count)
Definition: reg.c:2830
#define LOBYTE(W)
Definition: jmemdos.c:487
#define REGSTR_PATH_EXPLORER
Definition: regstr.h:33
@ REST_SH32_ENABLESHELLEXECUTEHOOKS
Definition: shell32_main.h:41
DWORD SH32_InternalRestricted(DWORD rest)
Definition: shpolicy.c:180
static HRESULT InvokeShellExecuteHook(PCWSTR pszClsid, LPSHELLEXECUTEINFOW pSEI)
Definition: shlexec.cpp:99
#define SEE_MASK_NO_HOOKS
Definition: undocshell.h:681
LONG_PTR LRESULT
Definition: windef.h:209

Referenced by SHELL_execute().

◆ Win32ErrFromHInst()

static int Win32ErrFromHInst ( HINSTANCE  hInst)
static

Definition at line 36 of file shlexec.cpp.

37{
38 if ((SIZE_T)hInst > 32)
39 return ERROR_SUCCESS;
40 switch ((SIZE_T)hInst)
41 {
42 case SE_ERR_FNF:
43 case SE_ERR_PNF:
45 case SE_ERR_OOM:
46 return (UINT)(SIZE_T)hInst;
47 case SE_ERR_SHARE:
50 case SE_ERR_DDEFAIL:
51 case SE_ERR_DDEBUSY:
52 return ERROR_DDE_FAIL;
55 //case SE_ERR_ASSOCINCOMPLETE: Note: Windows treats this as a success code
56 case SE_ERR_NOASSOC:
58 case 10:
60 case 12:
61 return ERROR_APP_WRONG_OS;
62 case 15:
63 return ERROR_RMODE_APP;
64 case 16:
66 case 20:
67 return ERROR_INVALID_DLL;
68 }
69 return -1;
70}
HINSTANCE hInst
Definition: dxdiag.c:13
#define SE_ERR_SHARE
Definition: shellapi.h:130
#define SE_ERR_PNF
Definition: shellapi.h:126
#define SE_ERR_DLLNOTFOUND
Definition: shellapi.h:129
#define SE_ERR_OOM
Definition: shellapi.h:128
#define SE_ERR_DDEBUSY
Definition: shellapi.h:134
#define SE_ERR_DDETIMEOUT
Definition: shellapi.h:132
#define SE_ERR_DDEFAIL
Definition: shellapi.h:133
#define ERROR_APP_WRONG_OS
Definition: winerror.h:673
#define ERROR_SHARING_VIOLATION
Definition: winerror.h:135
#define ERROR_RMODE_APP
Definition: winerror.h:675
#define ERROR_INVALID_DLL
Definition: winerror.h:676
#define ERROR_SINGLE_INSTANCE_APP
Definition: winerror.h:674
#define ERROR_OLD_WIN_VERSION
Definition: winerror.h:672

Referenced by SHELL_execute().

◆ 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 2638 of file shlexec.cpp.

2640{
2641 SHELLEXECUTEINFOW seiW;
2642 WCHAR *wVerb = NULL, *wFile = NULL, *wParameters = NULL, *wDirectory = NULL;
2643 HANDLE hProcess = 0;
2644
2645 seiW.lpVerb = lpVerb ? __SHCloneStrAtoW(&wVerb, lpVerb) : NULL;
2646 seiW.lpFile = lpFile ? __SHCloneStrAtoW(&wFile, lpFile) : NULL;
2647 seiW.lpParameters = lpParameters ? __SHCloneStrAtoW(&wParameters, lpParameters) : NULL;
2648 seiW.lpDirectory = lpDirectory ? __SHCloneStrAtoW(&wDirectory, lpDirectory) : NULL;
2649
2650 seiW.cbSize = sizeof(seiW);
2651 seiW.fMask = 0;
2652 seiW.hwnd = hWnd;
2653 seiW.nShow = iShowCmd;
2654 seiW.lpIDList = 0;
2655 seiW.lpClass = 0;
2656 seiW.hkeyClass = 0;
2657 seiW.dwHotKey = 0;
2658 seiW.hProcess = hProcess;
2659
2661
2662 SHFree(wVerb);
2663 SHFree(wFile);
2664 SHFree(wParameters);
2665 SHFree(wDirectory);
2666 return seiW.hInstApp;
2667}
_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:33