ReactOS 0.4.17-dev-1190-g4c812f4
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.

Classes

struct  _RUNASDLGDATA
 

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)
 
typedef struct _RUNASDLGDATA RUNASDLGDATA
 

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 HWND SHELL_GetUsableDialogOwner (HWND hWnd)
 
static INT_PTR CALLBACK RunAsDlgProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 
static HRESULT PromptAndRunProcessAs (_In_opt_ HWND hwnd, _In_ LPWSTR Cmd, _In_ DWORD CreationFlags, _In_opt_ LPWSTR Env, _In_opt_ LPCWSTR Dir, _In_ STARTUPINFOW *pSI, _Out_ PROCESS_INFORMATION *pPI)
 
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 UINT_PTR ExecuteFailed (UINT_PTR retval, SHELLEXECUTEINFOW &sei, LPCWSTR lpFile, BOOL AllowOpenWith=TRUE)
 
static WCHAR * expand_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

◆ RUNASDLGDATA

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

1261{
1262 TRACE("dde_cb: %04x, %04x, %p, %p, %p, %p, %08lx, %08lx\n",
1263 uType, uFmt, hConv, hsz1, hsz2, hData, dwData1, dwData2);
1264 return NULL;
1265}
#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 1276 of file shlexec.cpp.

1280{
1281 WCHAR regkey[256];
1282 WCHAR * endkey = regkey + wcslen(key);
1283 WCHAR app[256], topic[256], ifexec[256], static_res[256];
1285 WCHAR * res;
1286 LONG applen, topiclen, ifexeclen;
1287 WCHAR * exec;
1288 DWORD ddeInst = 0;
1289 DWORD tid;
1290 DWORD resultLen, endkeyLen;
1291 HSZ hszApp, hszTopic;
1292 HCONV hConv;
1293 HDDEDATA hDdeData;
1294 unsigned ret = SE_ERR_NOASSOC;
1295 BOOL unicode = !(GetVersion() & 0x80000000);
1296
1297 if (strlenW(key) + 1 > ARRAY_SIZE(regkey))
1298 {
1299 FIXME("input parameter %s larger than buffer\n", debugstr_w(key));
1300 return 2;
1301 }
1302 wcscpy(regkey, key);
1303 endkeyLen = ARRAY_SIZE(regkey) - (endkey - regkey);
1304 if (strlenW(L"\\application") + 1 > endkeyLen)
1305 {
1306 FIXME("endkey %s overruns buffer\n", debugstr_w(L"\\application"));
1307 return 2;
1308 }
1309 wcscpy(endkey, L"\\application");
1310 applen = sizeof(app);
1311 if (RegQueryValueW(HKEY_CLASSES_ROOT, regkey, app, &applen) != ERROR_SUCCESS)
1312 {
1313 WCHAR command[1024], fullpath[MAX_PATH];
1314 LPWSTR ptr = NULL;
1315 DWORD ret = 0;
1316
1317 /* Get application command from start string and find filename of application */
1318 if (*start == '"')
1319 {
1320 if (strlenW(start + 1) + 1 > ARRAY_SIZE(command))
1321 {
1322 FIXME("size of input parameter %s larger than buffer\n",
1323 debugstr_w(start + 1));
1324 return 2;
1325 }
1326 wcscpy(command, start + 1);
1327 if ((ptr = wcschr(command, '"')))
1328 * ptr = 0;
1329 ret = SearchPathW(NULL, command, L".exe", ARRAY_SIZE(fullpath), fullpath, &ptr);
1330 }
1331 else
1332 {
1333 LPCWSTR p;
1334 LPWSTR space;
1335 for (p = start; (space = const_cast<LPWSTR>(strchrW(p, ' '))); p = space + 1)
1336 {
1337 int idx = space - start;
1338 memcpy(command, start, idx * sizeof(WCHAR));
1339 command[idx] = '\0';
1340 if ((ret = SearchPathW(NULL, command, L".exe", ARRAY_SIZE(fullpath), fullpath, &ptr)))
1341 break;
1342 }
1343 if (!ret)
1344 ret = SearchPathW(NULL, start, L".exe", ARRAY_SIZE(fullpath), fullpath, &ptr);
1345 }
1346
1347 if (!ret)
1348 {
1349 ERR("Unable to find application path for command %s\n", debugstr_w(start));
1350 return ERROR_ACCESS_DENIED;
1351 }
1352 if (strlenW(ptr) + 1 > ARRAY_SIZE(app))
1353 {
1354 FIXME("size of found path %s larger than buffer\n", debugstr_w(ptr));
1355 return 2;
1356 }
1357 wcscpy(app, ptr);
1358
1359 /* Remove extensions (including .so) */
1360 ptr = app + wcslen(app) - 3;
1361 if (ptr > app && !wcscmp(ptr, L".so"))
1362 *ptr = 0;
1363
1364 ptr = const_cast<LPWSTR>(strrchrW(app, '.'));
1365 assert(ptr);
1366 *ptr = 0;
1367 }
1368
1369 if (strlenW(L"\\topic") + 1 > endkeyLen)
1370 {
1371 FIXME("endkey %s overruns buffer\n", debugstr_w(L"\\topic"));
1372 return 2;
1373 }
1374 wcscpy(endkey, L"\\topic");
1375 topiclen = sizeof(topic);
1376 if (RegQueryValueW(HKEY_CLASSES_ROOT, regkey, topic, &topiclen) != ERROR_SUCCESS)
1377 {
1378 wcscpy(topic, L"System");
1379 }
1380
1381 if (unicode)
1382 {
1384 return 2;
1385 }
1386 else
1387 {
1389 return 2;
1390 }
1391
1394
1395 hConv = DdeConnect(ddeInst, hszApp, hszTopic, NULL);
1396 exec = ddeexec;
1397 if (!hConv)
1398 {
1399 TRACE("Launching %s\n", debugstr_w(start));
1400 ret = execfunc(start, env, TRUE, psei, psei_out);
1401 if (ret <= 32)
1402 {
1403 TRACE("Couldn't launch\n");
1404 goto error;
1405 }
1406 /* if ddeexec is NULL, then we just need to exit here */
1407 if (ddeexec == NULL)
1408 {
1409 TRACE("Exiting because ddeexec is NULL. ret=42.\n");
1410 /* See https://docs.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shellexecutew */
1411 /* for reason why we use 42 here and also "Shell32_apitest ShellExecuteW" regression test */
1412 return 42;
1413 }
1414 /* if ddeexec is 'empty string', then we just need to exit here */
1415 if (wcscmp(ddeexec, L"") == 0)
1416 {
1417 TRACE("Exiting because ddeexec is 'empty string'. ret=42.\n");
1418 /* See https://docs.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shellexecutew */
1419 /* for reason why we use 42 here and also "Shell32_apitest ShellExecuteW" regression test */
1420 return 42;
1421 }
1422 hConv = DdeConnect(ddeInst, hszApp, hszTopic, NULL);
1423 if (!hConv)
1424 {
1425 TRACE("Couldn't connect. ret=%d\n", ret);
1428 return 30; /* whatever */
1429 }
1430 if (strlenW(L"\\ifexec") + 1 > endkeyLen)
1431 {
1432 FIXME("endkey %s overruns buffer\n", debugstr_w(L"\\ifexec"));
1433 return 2;
1434 }
1435 strcpyW(endkey, L"\\ifexec");
1436 ifexeclen = sizeof(ifexec);
1437 if (RegQueryValueW(HKEY_CLASSES_ROOT, regkey, ifexec, &ifexeclen) == ERROR_SUCCESS)
1438 {
1439 exec = ifexec;
1440 }
1441 }
1442
1443 SHELL_ArgifyW(static_res, ARRAY_SIZE(static_res), exec, lpFile, pidl, szCommandline, &resultLen, NULL);
1444 if (resultLen > ARRAY_SIZE(static_res))
1445 {
1446 dynamic_res.Allocate(resultLen);
1447 res = dynamic_res;
1448 SHELL_ArgifyW(dynamic_res, resultLen, exec, lpFile, pidl, szCommandline, NULL, NULL);
1449 }
1450 else
1451 res = static_res;
1452 TRACE("%s %s => %s\n", debugstr_w(exec), debugstr_w(lpFile), debugstr_w(res));
1453
1454 /* It's documented in the KB 330337 that IE has a bug and returns
1455 * error DMLERR_NOTPROCESSED on XTYP_EXECUTE request.
1456 */
1457 if (unicode)
1458 hDdeData = DdeClientTransaction((LPBYTE)res, (strlenW(res) + 1) * sizeof(WCHAR), hConv, 0L, 0, XTYP_EXECUTE, 30000, &tid);
1459 else
1460 {
1461 DWORD lenA = WideCharToMultiByte(CP_ACP, 0, res, -1, NULL, 0, NULL, NULL);
1463 resA.Allocate(lenA);
1464 WideCharToMultiByte(CP_ACP, 0, res, -1, resA, lenA, NULL, NULL);
1465 hDdeData = DdeClientTransaction( (LPBYTE)(LPSTR)resA, lenA, hConv, 0L, 0,
1466 XTYP_EXECUTE, 10000, &tid );
1467 }
1468 if (hDdeData)
1469 DdeFreeDataHandle(hDdeData);
1470 else
1471 WARN("DdeClientTransaction failed with error %04x\n", DdeGetLastError(ddeInst));
1472 ret = 33;
1473
1474 DdeDisconnect(hConv);
1475
1476error:
1478
1479 return ret;
1480}
#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
static LPCWSTR LPCWSTR LPCWSTR env
Definition: db.cpp:171
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:40
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:1397
DWORD WINAPI GetVersion(void)
Definition: version.c:1458
#define assert(_expr)
Definition: assert.h:32
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2988
_ACRTIMP int __cdecl wcscmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:1977
return ret
Definition: mutex.c:147
#define L(x)
Definition: resources.c:13
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
static TfClientId tid
#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
short WCHAR
Definition: pedump.c:58
long LONG
Definition: pedump.c:60
static const char topic[]
Definition: propsys.c:45
wcscpy
#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:1258
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
const uint16_t * LPCWSTR
Definition: typedefs.h:57
unsigned char * LPBYTE
Definition: typedefs.h:53
uint16_t * LPWSTR
Definition: typedefs.h:56
char * LPSTR
Definition: typedefs.h:51
#define strchrW(s, c)
Definition: unicode.h:34
#define strlenW(s)
Definition: unicode.h:28
#define strrchrW(s, c)
Definition: unicode.h:35
#define strcpyW(d, s)
Definition: unicode.h:29
#define ERROR_DDE_FAIL
Definition: winerror.h:1002
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10

Referenced by execute_from_key().

◆ do_error_dialog()

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

Definition at line 2173 of file shlexec.cpp.

2174{
2175 WCHAR msg[2048];
2176 DWORD_PTR msgArguments[3] = { (DWORD_PTR)filename, 0, 0 };
2177 const DWORD error_code = GetLastError();
2178
2179 if (retval == SE_ERR_NOASSOC)
2181 else
2183 NULL,
2184 error_code,
2186 msg,
2187 ARRAY_SIZE(msg),
2188 (va_list*)msgArguments);
2189
2191 SetLastError(error_code); // Restore
2192}
#define shell32_hInstance
#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
char * va_list
Definition: vadefs.h:50
const char * filename
Definition: ioapi.h:137
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
#define LoadStringW
Definition: utils.h:64
#define IDS_SHLEXEC_NOASSOC
Definition: shresdef.h:185
#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:53
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define FORMAT_MESSAGE_FROM_SYSTEM
Definition: winbase.h:400
#define FORMAT_MESSAGE_ARGUMENT_ARRAY
Definition: winbase.h:401
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023

Referenced by ExecuteFailed(), and 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 1485 of file shlexec.cpp.

1489{
1490 WCHAR cmd[256], param[1024], ddeexec[256];
1491 DWORD cmdlen = sizeof(cmd), ddeexeclen = sizeof(ddeexec);
1493 DWORD resultLen;
1494 LPWSTR tmp;
1495
1496 TRACE("%s %s %s %s %s\n", debugstr_w(key), debugstr_w(lpFile), debugstr_w(env),
1497 debugstr_w(szCommandline), debugstr_w(executable_name));
1498
1499 cmd[0] = '\0';
1500 param[0] = '\0';
1501
1502 /* Get the application from the registry */
1504 {
1505 TRACE("got cmd: %s\n", debugstr_w(cmd));
1506
1507 /* Is there a replace() function anywhere? */
1508 cmdlen /= sizeof(WCHAR);
1509 if (cmdlen >= ARRAY_SIZE(cmd))
1510 cmdlen = ARRAY_SIZE(cmd) - 1;
1511 cmd[cmdlen] = '\0';
1512 SHELL_ArgifyW(param, ARRAY_SIZE(param), cmd, lpFile, (LPITEMIDLIST)psei->lpIDList, szCommandline, &resultLen,
1513 (psei->lpDirectory && *psei->lpDirectory) ? psei->lpDirectory : NULL);
1514 if (resultLen > ARRAY_SIZE(param))
1515 ERR("Argify buffer not large enough, truncating\n");
1516 }
1517
1518 /* Get the parameters needed by the application
1519 from the associated ddeexec key */
1520 tmp = const_cast<LPWSTR>(strstrW(key, L"command"));
1521 assert(tmp);
1522 wcscpy(tmp, L"ddeexec");
1523
1524 if (RegQueryValueW(HKEY_CLASSES_ROOT, key, ddeexec, (LONG *)&ddeexeclen) == ERROR_SUCCESS)
1525 {
1526 TRACE("Got ddeexec %s => %s\n", debugstr_w(key), debugstr_w(ddeexec));
1527 if (!param[0]) strcpyW(param, executable_name);
1528 retval = dde_connect(key, param, ddeexec, lpFile, env, szCommandline, (LPITEMIDLIST)psei->lpIDList, execfunc, psei, psei_out);
1529 }
1530 else if (param[0])
1531 {
1532 TRACE("executing: %s\n", debugstr_w(param));
1533 retval = execfunc(param, env, FALSE, psei, psei_out);
1534 }
1535 else
1536 WARN("Nothing appropriate found for %s\n", debugstr_w(key));
1537
1538 return retval;
1539}
#define FALSE
Definition: types.h:117
GLfloat param
Definition: glext.h:5796
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
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:1276
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
LPCWSTR lpDirectory
Definition: shellapi.h:341
Definition: ftp_var.h:139
#define strstrW(d, s)
Definition: unicode.h:32

Referenced by SHELL_execute_url(), and SHELL_quote_and_execute().

◆ ExecuteFailed()

static UINT_PTR ExecuteFailed ( UINT_PTR  retval,
SHELLEXECUTEINFOW &  sei,
LPCWSTR  lpFile,
BOOL  AllowOpenWith = TRUE 
)
static

Definition at line 2194 of file shlexec.cpp.

2195{
2196 if (retval <= 32 && !(sei.fMask & SEE_MASK_FLAG_NO_UI))
2197 {
2198 if (retval == SE_ERR_NOASSOC && !(sei.fMask & SEE_MASK_CLASSALL) && AllowOpenWith)
2199 retval = InvokeOpenWith(sei.hwnd, sei);
2200 if (retval <= 32)
2201 do_error_dialog(retval, sei.hwnd, lpFile);
2202 }
2203 sei.hInstApp = (HINSTANCE)UlongToHandle(retval > 32 ? 33 : retval);
2204 return retval;
2205}
#define UlongToHandle(ul)
Definition: basetsd.h:91
#define SEE_MASK_FLAG_NO_UI
Definition: shellapi.h:38
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:2173
#define SEE_MASK_CLASSALL
Definition: shlexec.cpp:31
HINSTANCE hInstApp
Definition: shellapi.h:343
HANDLE HINSTANCE
Definition: typedefs.h:77

Referenced by SHELL_execute().

◆ expand_environment()

static WCHAR * expand_environment ( const WCHAR *  str)
static

Definition at line 2207 of file shlexec.cpp.

2208{
2210 DWORD len;
2211
2213 if (!len) return NULL;
2214
2215 if (!buf.Allocate(len))
2216 return NULL;
2217
2219 if (!len)
2220 return NULL;
2221
2222 return buf.Detach();
2223}
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:492
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 1544 of file shlexec.cpp.

1545{
1547 WCHAR *wFile = NULL, *wDirectory = NULL;
1548 WCHAR wResult[MAX_PATH];
1549
1550 if (lpFile) __SHCloneStrAtoW(&wFile, lpFile);
1551 if (lpDirectory) __SHCloneStrAtoW(&wDirectory, lpDirectory);
1552
1553 retval = FindExecutableW(wFile, wDirectory, wResult);
1554 WideCharToMultiByte(CP_ACP, 0, wResult, -1, lpResult, MAX_PATH, NULL, NULL);
1555 SHFree(wFile);
1556 SHFree(wDirectory);
1557
1558 TRACE("returning %s\n", lpResult);
1559 return retval;
1560}
void WINAPI SHFree(LPVOID pv)
Definition: shellole.c:370
static __inline LPWSTR __SHCloneStrAtoW(WCHAR **target, const char *source)
Definition: shell32_main.h:227
_In_opt_ LPCSTR lpDirectory
Definition: shellapi.h:492
HINSTANCE WINAPI FindExecutableW(LPCWSTR lpFile, LPCWSTR lpDirectory, LPWSTR lpResult)
Definition: shlexec.cpp:1587

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

◆ FindExecutableW()

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

Definition at line 1587 of file shlexec.cpp.

1588{
1590 WCHAR old_dir[MAX_PATH], res[MAX_PATH];
1591 DWORD cch = _countof(res);
1592 LPCWSTR dirs[2];
1593
1594 TRACE("File %s, Dir %s\n", debugstr_w(lpFile), debugstr_w(lpDirectory));
1595
1596 *lpResult = UNICODE_NULL;
1597
1598 GetCurrentDirectoryW(_countof(old_dir), old_dir);
1599
1600 if (lpDirectory && *lpDirectory)
1601 {
1603 dirs[0] = lpDirectory;
1604 }
1605 else
1606 {
1607 dirs[0] = old_dir;
1608 }
1609 dirs[1] = NULL;
1610
1611 if (!GetShortPathNameW(lpFile, res, _countof(res)))
1612 StringCchCopyW(res, _countof(res), lpFile);
1613
1615 {
1616 // NOTE: The last parameter of this AssocQueryStringW call is "strange" in Windows.
1617 if (PathIsExeW(res) ||
1619 {
1620 StringCchCopyW(lpResult, MAX_PATH, res);
1621 retval = 42;
1622 }
1623 else
1624 {
1626 }
1627 }
1628 else
1629 {
1631 }
1632
1633 TRACE("returning %s\n", debugstr_w(lpResult));
1634 SetCurrentDirectoryW(old_dir);
1635 return (HINSTANCE)retval;
1636}
#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:2267
DWORD WINAPI GetShortPathNameW(IN LPCWSTR lpszLongPath, OUT LPWSTR lpszShortPath, IN DWORD cchBuffer)
Definition: path.c:1851
BOOL WINAPI PathResolveW(WCHAR *path, const WCHAR **dirs, DWORD flags)
Definition: shellpath.c:1447
HRESULT WINAPI AssocQueryStringW(ASSOCF cfFlags, ASSOCSTR str, LPCWSTR pszAssoc, LPCWSTR pszExtra, LPWSTR pszOut, DWORD *pcchOut)
Definition: assoc.c:569
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define UNICODE_NULL
@ ASSOCSTR_EXECUTABLE
Definition: shlwapi.h:887
@ ASSOCF_NONE
Definition: shlwapi.h:858
_In_ UINT _In_ UINT cch
Definition: shellapi.h:428
#define SE_ERR_FNF
Definition: shellapi.h:125
EXTERN_C BOOL PathIsExeW(LPCWSTR lpszPath)
#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)
HRESULT hr
Definition: delayimp.cpp:582
unsigned int UINT
Definition: sysinfo.c:13
#define SW_SHOW
Definition: winuser.h:786
#define SEE_MASK_NOCLOSEPROCESS
Definition: shellapi.h:33
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define ERROR_NO_ASSOCIATION
Definition: winerror.h:1001

Referenced by ExecuteFailed().

◆ 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}
#define IID_PPV_ARG(Itype, ppType)
HRESULT WINAPI SHExtCoCreateInstance(_In_opt_ LPCWSTR aclsid, _In_opt_ const CLSID *clsid, _In_opt_ LPUNKNOWN pUnkOuter, _In_ REFIID riid, _Out_ LPVOID *ppv)
Definition: shellole.c:222
static void *static void *static LPDIRECTPLAY IUnknown * pUnk
Definition: dplayx.c:41
nsresult QueryInterface(nsIIDRef riid, void **result)
#define FAILED(hr)
Definition: intsafe.h:51
HINSTANCE hInstApp
Definition: shellapi.h:320
#define S_FALSE
Definition: winerror.h:3451

Referenced by TryShellExecuteHooks().

◆ OpenAs_RunDLLA()

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

Definition at line 2870 of file shlexec.cpp.

2871{
2872 LPWSTR pszCmdLineW = NULL;
2873 TRACE("%p, %p, %s, %d\n", hwnd, hinst, debugstr_a(cmdline), cmdshow);
2874
2875 if (cmdline)
2876 __SHCloneStrAtoW(&pszCmdLineW, cmdline);
2877 OpenAs_RunDLLW(hwnd, hinst, pszCmdLineW, cmdshow);
2878 SHFree(pszCmdLineW);
2879}
#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:2859
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 2859 of file shlexec.cpp.

2860{
2862 TRACE("%p, %p, %s, %d\n", hwnd, hinst, debugstr_w(cmdline), cmdshow);
2864}
HRESULT WINAPI SHOpenWithDialog(HWND hwndParent, const OPENASINFO *poainfo)
@ OAIF_EXEC
Definition: shlobj.h:2729
@ OAIF_REGISTER_EXT
Definition: shlobj.h:2728
@ OAIF_ALLOW_REGISTRATION
Definition: shlobj.h:2727

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)

Referenced by FindExecutableW(), 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 3254 of file shlexec.cpp.

3259{
3260 TRACE("%s, %p, %d, 0x%X\n", wine_dbgstr_w(pszSrc), pszDest, cchDest, dwFlags);
3261
3262 if (!pszSrc)
3263 return -1;
3264
3266 PCWSTR pchArg = NULL;
3267
3268 if (*pszSrc == L'"') // Quoted?
3269 {
3270 ++pszSrc;
3271
3272 PCWSTR pch = wcschr(pszSrc, L'"');
3273 if (pch)
3274 {
3275 szPath.SetString(pszSrc, pch - pszSrc);
3276 pchArg = pch + 1;
3277 }
3278 else
3279 {
3280 szPath = pszSrc;
3281 }
3282
3284 {
3286 szPath.ReleaseBuffer();
3287 if (!ret)
3288 return -1;
3289 }
3290 }
3291 else // Not quoted?
3292 {
3293 BOOL resolved = FALSE;
3294 BOOL resolveRelative = PathIsRelativeW(pszSrc) || (dwFlags & PPCF_FORCEQUALIFY);
3295 INT cchPath = 0;
3296
3297 for (INT ich = 0; ; ++ich)
3298 {
3299 szPath += pszSrc[ich];
3300
3301 if (pszSrc[ich] && pszSrc[ich] != L' ')
3302 continue;
3303
3304 szPath = szPath.Left(ich);
3305
3306 if (resolveRelative &&
3308 {
3309 szPath.ReleaseBuffer();
3310 szPath += pszSrc[ich];
3311 }
3312 else
3313 {
3314 szPath.ReleaseBuffer();
3315
3317 if (attrs != INVALID_FILE_ATTRIBUTES &&
3319 {
3320 resolved = TRUE;
3321 pchArg = pszSrc + ich;
3322
3324 break;
3325
3326 cchPath = ich;
3327 break;
3328 }
3329 else if (!resolveRelative)
3330 {
3331 szPath += pszSrc[ich];
3332 }
3333 }
3334
3335 if (!szPath[ich])
3336 {
3337 szPath.ReleaseBuffer(); // Remove excessive '\0'
3338 break;
3339 }
3340 }
3341
3342 if (!resolved)
3343 return -1;
3344
3345 if (cchPath && (dwFlags & PPCF_LONGESTPOSSIBLE))
3346 {
3347 szPath = szPath.Left(cchPath);
3348 pchArg = pszSrc + cchPath;
3349 }
3350 }
3351
3352 BOOL needsQuoting = (dwFlags & PPCF_ADDQUOTES) && wcschr(szPath, L' ');
3353 CStringW result = needsQuoting ? (L"\"" + szPath + L"\"") : szPath;
3354
3355 if (pchArg && (dwFlags & PPCF_ADDARGUMENTS))
3356 result += pchArg;
3357
3358 LONG requiredSize = result.GetLength() + 1;
3359 if (!pszDest)
3360 return requiredSize;
3361
3362 if (requiredSize > cchDest || StringCchCopyW(pszDest, cchDest, result) != S_OK)
3363 return -1;
3364
3365 return requiredSize;
3366}
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:636
BOOL WINAPI PathIsRelativeW(const WCHAR *path)
Definition: path.c:1006
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
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
_In_ INT cchDest
Definition: shlwapi.h:1161
#define PPCF_FORCEQUALIFY
Definition: shlobj.h:2468
#define PPCF_LONGESTPOSSIBLE
Definition: shlobj.h:2469
#define PPCF_ADDQUOTES
Definition: shlobj.h:2463
#define PPCF_ADDARGUMENTS
Definition: shlobj.h:2465
#define PPCF_NODIRECTORIES
Definition: shlobj.h:2466
int32_t INT
Definition: typedefs.h:58
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23

Referenced by ShellExec_RunDLL_Helper().

◆ PromptAndRunProcessAs()

static HRESULT PromptAndRunProcessAs ( _In_opt_ HWND  hwnd,
_In_ LPWSTR  Cmd,
_In_ DWORD  CreationFlags,
_In_opt_ LPWSTR  Env,
_In_opt_ LPCWSTR  Dir,
_In_ STARTUPINFOW *  pSI,
_Out_ PROCESS_INFORMATION *  pPI 
)
static

Definition at line 661 of file shlexec.cpp.

669{
671 UINT error;
672 INT_PTR dlgret;
674
675again:
678 if (dlgret == IDOK && data.Name)
679 {
680 if (CreateProcessWithLogonW(data.Name, data.Domain, data.Password, data.LogonFlags,
681 NULL, Cmd, CreationFlags, Env, Dir, pSI, pPI))
683 else
685 switch (error)
686 {
695 goto again;
696 }
697 }
698 else if (dlgret == IDOK)
699 {
700 // TODO: Use the Safer API if requested to
701 if (CreateProcessW(NULL, Cmd, NULL, NULL, FALSE, CreationFlags, Env, Dir, pSI, pPI))
703 else
705 }
706 else if (dlgret == IDCANCEL)
707 {
709 pPI->hProcess = NULL;
710 return S_FALSE;
711 }
712 else
713 {
714 pPI->hProcess = NULL;
715 return E_FAIL;
716 }
717 SecureZeroMemory(&data, sizeof(data));
719}
#define E_FAIL
Definition: ddrawi.h:102
static PVOID Env
Definition: dem.c:259
BOOL WINAPI CreateProcessWithLogonW(_In_ LPCWSTR lpUsername, _In_opt_ LPCWSTR lpDomain, _In_ LPCWSTR lpPassword, _In_ DWORD dwLogonFlags, _In_opt_ LPCWSTR lpApplicationName, _Inout_opt_ LPWSTR lpCommandLine, _In_ DWORD dwCreationFlags, _In_opt_ LPVOID lpEnvironment, _In_opt_ LPCWSTR lpCurrentDirectory, _In_ LPSTARTUPINFOW lpStartupInfo, _Out_ LPPROCESS_INFORMATION lpProcessInformation)
Definition: security.c:3728
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:4493
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
LONG_PTR LPARAM
Definition: minwindef.h:175
#define IDCANCEL
Definition: winuser.h:842
#define IDOK
Definition: winuser.h:841
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
INT_PTR WINAPI DialogBoxParamW(_In_opt_ HINSTANCE, _In_ LPCWSTR, _In_opt_ HWND, _In_opt_ DLGPROC, _In_ LPARAM)
@ Cmd
Definition: sacdrv.h:278
#define SHELL_ErrorBox
Definition: shellutils.h:126
static INT_PTR CALLBACK RunAsDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: shlexec.cpp:596
static HWND SHELL_GetUsableDialogOwner(HWND hWnd)
Definition: shlexec.cpp:569
#define IDD_RUN_AS
Definition: shresdef.h:401
int32_t INT_PTR
Definition: typedefs.h:64
#define SecureZeroMemory
Definition: winbase.h:1441
static HRESULT HRESULT_FROM_WIN32(unsigned int x)
Definition: winerror.h:210
#define ERROR_INVALID_LOGON_HOURS
Definition: winerror.h:1155
#define ERROR_ACCOUNT_RESTRICTION
Definition: winerror.h:1154
#define ERROR_LOGON_FAILURE
Definition: winerror.h:1153
#define ERROR_INVALID_ACCOUNT_NAME
Definition: winerror.h:1142
#define ERROR_CANCELLED
Definition: winerror.h:1055
#define ERROR_ACCOUNT_DISABLED
Definition: winerror.h:1158
#define ERROR_NO_SUCH_USER
Definition: winerror.h:1144
#define ERROR_PASSWORD_EXPIRED
Definition: winerror.h:1157

Referenced by SHELL_ExecuteW().

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

3203{
3205 lpOperation,
3206 lpFile,
3207 lpParameters,
3209 lpReturn,
3210 lpTitle,
3211 lpReserved,
3212 nCmdShow,
3213 lphProcess,
3214 0);
3215}
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:3058
_In_ DWORD _In_ int _In_ int _In_opt_ LPNLSVERSIONINFO _In_opt_ LPVOID lpReserved
Definition: winnls.h:1279

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

3070{
3071 SHELLEXECUTEINFOA ExecInfo;
3072
3073 TRACE("(%p, %s, %s, %s, %s, %p, %s, %p, %u, %p, %lu)\n",
3074 hwnd, debugstr_a(lpOperation), debugstr_a(lpFile), debugstr_a(lpParameters),
3076 lpReserved, nCmdShow, lphProcess, dwFlags);
3077
3078 ZeroMemory(&ExecInfo, sizeof(ExecInfo));
3079 ExecInfo.cbSize = sizeof(ExecInfo);
3081 ExecInfo.hwnd = hwnd;
3082 ExecInfo.lpVerb = lpOperation;
3083 ExecInfo.lpFile = lpFile;
3084 ExecInfo.lpParameters = lpParameters;
3085 ExecInfo.lpDirectory = lpDirectory;
3086 ExecInfo.nShow = (WORD)nCmdShow;
3087
3088 if (lpReserved)
3089 {
3090 ExecInfo.fMask |= SEE_MASK_USE_RESERVED;
3091 ExecInfo.hInstApp = (HINSTANCE)lpReserved;
3092 }
3093
3094 if (lpTitle)
3095 {
3096 ExecInfo.fMask |= SEE_MASK_HASTITLE;
3097 ExecInfo.lpClass = lpTitle;
3098 }
3099
3100 if (dwFlags & 1)
3101 ExecInfo.fMask |= SEE_MASK_FLAG_SEPVDM;
3102
3103 if (dwFlags & 2)
3104 ExecInfo.fMask |= SEE_MASK_NO_CONSOLE;
3105
3106 if (lphProcess == NULL)
3107 {
3108 ShellExecuteExA(&ExecInfo);
3109 }
3110 else
3111 {
3112 ExecInfo.fMask |= SEE_MASK_NOCLOSEPROCESS;
3113 ShellExecuteExA(&ExecInfo);
3114 *lphProcess = ExecInfo.hProcess;
3115 }
3116
3117 return ExecInfo.hInstApp;
3118}
unsigned short WORD
Definition: ntddk_ex.h:93
#define ZeroMemory
Definition: minwinbase.h:31
#define SEE_MASK_NO_CONSOLE
Definition: shellapi.h:41
BOOL WINAPI DECLSPEC_HOTPATCH ShellExecuteExA(LPSHELLEXECUTEINFOA sei)
Definition: shlexec.cpp:2680
LPCSTR lpParameters
Definition: shellapi.h:317
LPCSTR lpDirectory
Definition: shellapi.h:318
#define SEE_MASK_USE_RESERVED
Definition: undocshell.h:739
#define SEE_MASK_FLAG_SEPVDM
Definition: undocshell.h:738
#define SEE_MASK_HASTITLE
Definition: undocshell.h:740
#define SEE_MASK_UNKNOWN_0x1000
Definition: undocshell.h:735

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

3137{
3138 SHELLEXECUTEINFOW ExecInfo;
3139
3140 TRACE("(%p, %s, %s, %s, %s, %p, %s, %p, %u, %p, %lu)\n",
3141 hwnd, debugstr_w(lpOperation), debugstr_w(lpFile), debugstr_w(lpParameters),
3143 lpReserved, nCmdShow, lphProcess, dwFlags);
3144
3145 ZeroMemory(&ExecInfo, sizeof(ExecInfo));
3146 ExecInfo.cbSize = sizeof(ExecInfo);
3148 ExecInfo.hwnd = hwnd;
3149 ExecInfo.lpVerb = lpOperation;
3150 ExecInfo.lpFile = lpFile;
3151 ExecInfo.lpParameters = lpParameters;
3152 ExecInfo.lpDirectory = lpDirectory;
3153 ExecInfo.nShow = (WORD)nCmdShow;
3154
3155 if (lpReserved)
3156 {
3157 ExecInfo.fMask |= SEE_MASK_USE_RESERVED;
3158 ExecInfo.hInstApp = (HINSTANCE)lpReserved;
3159 }
3160
3161 if (lpTitle)
3162 {
3163 ExecInfo.fMask |= SEE_MASK_HASTITLE;
3164 ExecInfo.lpClass = lpTitle;
3165 }
3166
3167 if (dwFlags & 1)
3168 ExecInfo.fMask |= SEE_MASK_FLAG_SEPVDM;
3169
3170 if (dwFlags & 2)
3171 ExecInfo.fMask |= SEE_MASK_NO_CONSOLE;
3172
3173 if (lphProcess == NULL)
3174 {
3175 ShellExecuteExW(&ExecInfo);
3176 }
3177 else
3178 {
3179 ExecInfo.fMask |= SEE_MASK_NOCLOSEPROCESS;
3180 ShellExecuteExW(&ExecInfo);
3181 *lphProcess = ExecInfo.hProcess;
3182 }
3183
3184 return ExecInfo.hInstApp;
3185}
BOOL WINAPI DECLSPEC_HOTPATCH ShellExecuteExW(LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:2738
LPCWSTR lpParameters
Definition: shellapi.h:340

Referenced by RealShellExecuteW().

◆ RealShellExecuteW()

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

Definition at line 3222 of file shlexec.cpp.

3233{
3235 lpOperation,
3236 lpFile,
3237 lpParameters,
3239 lpReturn,
3240 lpTitle,
3241 lpReserved,
3242 nCmdShow,
3243 lphProcess,
3244 0);
3245}
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:3125

◆ RunAsDlgProc()

static INT_PTR CALLBACK RunAsDlgProc ( HWND  hwnd,
UINT  uMsg,
WPARAM  wParam,
LPARAM  lParam 
)
static

Definition at line 596 of file shlexec.cpp.

597{
599 switch (uMsg)
600 {
601 case WM_INITDIALOG:
602 {
607
609 WCHAR fmtbuf[200], buf[_countof(fmtbuf) + _countof(pData->NameBuffer)];
610 DWORD cch = _countof(pData->NameBuffer);
611 if (GetUserNameW(pData->NameBuffer, &cch))
612 {
613 SendMessageW(hCtl, WM_GETTEXT, _countof(fmtbuf), (LPARAM)buf);
614 StringCchPrintfW(fmtbuf, _countof(fmtbuf), buf, L"(%s)"); // Change "Blah blah %s" to "Blah blah (%s)"
615 StringCchPrintfW(buf, _countof(buf), fmtbuf, pData->NameBuffer);
616 SendMessageW(hCtl, WM_SETTEXT, 0, (LPARAM)buf);
618 }
620 return TRUE;
621 }
622
623 case WM_COMMAND:
624 switch (LOWORD(wParam))
625 {
626 case IDCANCEL:
628 break;
629
630 case IDOK:
631 {
634 pData->Name = pData->NameBuffer;
635 pData->Domain = wcsstr(pData->Name, L"\\");
636 if (pData->Domain)
637 {
638 LPWSTR tmp = pData->Domain + 1;
639 pData->Domain[0] = UNICODE_NULL;
640 pData->Domain = pData->Name;
641 pData->Name = tmp;
642 }
646 pData->Name = NULL;
648 break;
649 }
650
651 case IDC_RUNAS_BROWSE:
652 return SHELL_ErrorBox(hwnd, ERROR_NOT_SUPPORTED); // TODO
653 }
654 break;
655 }
656 return FALSE;
657}
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
BOOL WINAPI GetUserNameW(LPWSTR lpszName, LPDWORD lpSize)
Definition: misc.c:291
#define ERROR_NOT_SUPPORTED
Definition: compat.h:100
_ACRTIMP wchar_t *__cdecl wcsstr(const wchar_t *, const wchar_t *)
Definition: wcs.c:2998
#define LOWORD(l)
Definition: pedump.c:82
#define EM_LIMITTEXT
Definition: winuser.h:2029
#define DWLP_USER
Definition: winuser.h:883
#define GetWindowLongPtrW
Definition: winuser.h:4983
#define WM_COMMAND
Definition: winuser.h:1768
#define CB_SETCURSEL
Definition: winuser.h:1990
#define WM_GETTEXT
Definition: winuser.h:1646
#define WM_INITDIALOG
Definition: winuser.h:1767
HWND WINAPI GetDlgItem(_In_opt_ HWND, _In_ int)
LRESULT WINAPI SendDlgItemMessageW(_In_ HWND, _In_ int, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
UINT WINAPI IsDlgButtonChecked(_In_ HWND, _In_ int)
#define WM_SETTEXT
Definition: winuser.h:1645
#define BM_CLICK
Definition: winuser.h:1946
#define CB_ADDSTRING
Definition: winuser.h:1965
#define VK_SHIFT
Definition: winuser.h:2238
#define SetWindowLongPtrW
Definition: winuser.h:5512
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
SHORT WINAPI GetKeyState(_In_ int)
BOOL WINAPI EndDialog(_In_ HWND, _In_ INT_PTR)
#define IDC_RUNAS_PWD
Definition: shresdef.h:407
#define IDC_RUNAS_CURRENT
Definition: shresdef.h:402
#define IDC_RUNAS_OTHER
Definition: shresdef.h:403
#define IDC_RUNAS_SAFER
Definition: shresdef.h:404
#define IDC_RUNAS_NAME
Definition: shresdef.h:405
#define IDC_RUNAS_BROWSE
Definition: shresdef.h:406
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1830
#define LOGON_WITH_PROFILE
Definition: winbase.h:596
#define LOGON_NETCREDENTIALS_ONLY
Definition: winbase.h:597

Referenced by PromptAndRunProcessAs().

◆ 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:167
PVOID WINAPI SHLockShared(HANDLE hShared, DWORD dwProcId)
Definition: ordinal.c:257
BOOL WINAPI SHUnlockShared(LPVOID lpView)
Definition: ordinal.c:293
#define _swprintf(buf, format,...)
Definition: sprintf.c:56
UINT WINAPI ILGetSize(LPCITEMIDLIST pidl)
Definition: pidl.c:941
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 848 of file shlexec.cpp.

849{
851 WCHAR *strings, *p, *p2;
852 int total = wcslen(path) + 1;
853 BOOL got_path = FALSE;
854
855 if (!(strings = GetEnvironmentStringsW())) return NULL;
856 p = strings;
857 while (*p)
858 {
859 int len = wcslen(p) + 1;
860 if (!_wcsnicmp( p, L"PATH=", 5 )) got_path = TRUE;
861 total += len;
862 p += len;
863 }
864 if (!got_path) total += 5; /* we need to create PATH */
865 total++; /* terminating null */
866
867 if (!new_env.Allocate(total))
868 {
870 return NULL;
871 }
872 p = strings;
873 p2 = new_env;
874 while (*p)
875 {
876 int len = wcslen(p) + 1;
877 memcpy(p2, p, len * sizeof(WCHAR));
878 if (!_wcsnicmp( p, L"PATH=", 5 ))
879 {
880 p2[len - 1] = ';';
881 wcscpy( p2 + len, path );
882 p2 += wcslen(path) + 1;
883 }
884 p += len;
885 p2 += len;
886 }
887 if (!got_path)
888 {
889 wcscpy(p2, L"PATH=");
890 wcscat(p2, path);
891 p2 += wcslen(p2) + 1;
892 }
893 *p2 = 0;
895 return new_env.Detach();
896}
T * Detach()
Definition: atlalloc.h:168
BOOL WINAPI FreeEnvironmentStringsW(IN LPWSTR EnvironmentStrings)
Definition: environ.c:362
LPWSTR WINAPI DECLSPEC_HOTPATCH GetEnvironmentStringsW(void)
Definition: process.c:1556
_ACRTIMP int __cdecl _wcsnicmp(const wchar_t *, const wchar_t *, size_t)
Definition: wcs.c:200
size_t total
GLsizei const GLchar *const * strings
Definition: glext.h:7622
wcscat

Referenced by SHELL_TryAppPathW().

◆ SHELL_execute()

static BOOL SHELL_execute ( LPSHELLEXECUTEINFOW  sei,
SHELL_ExecuteW32  execfunc 
)
static

Definition at line 2228 of file shlexec.cpp.

2229{
2230 static const DWORD unsupportedFlags =
2232
2233 DWORD len;
2235 BOOL appKnownSingular = FALSE;
2236
2237 /* make a local copy of the LPSHELLEXECUTEINFO structure and work with this from now on */
2238 sei->hProcess = NULL;
2239 SHELLEXECUTEINFOW sei_tmp = *sei;
2240
2241 TRACE("mask=0x%08x hwnd=%p verb=%s file=%s parm=%s dir=%s show=0x%08x class=%s\n",
2242 sei_tmp.fMask, sei_tmp.hwnd, debugstr_w(sei_tmp.lpVerb),
2243 debugstr_w(sei_tmp.lpFile), debugstr_w(sei_tmp.lpParameters),
2244 debugstr_w(sei_tmp.lpDirectory), sei_tmp.nShow,
2245 ((sei_tmp.fMask & SEE_MASK_CLASSALL) == SEE_MASK_CLASSNAME) ?
2246 debugstr_w(sei_tmp.lpClass) : "not used");
2247
2248 // Call hooks before expanding and resolving strings
2250 if (hr != S_FALSE)
2251 {
2252 int err = Win32ErrFromHInst(sei->hInstApp);
2253 if (err <= 0)
2254 {
2255 sei->hInstApp = (HINSTANCE)UlongToHandle(42);
2256 return TRUE;
2257 }
2259 return FALSE;
2260 }
2261
2262 /* make copies of all path/command strings */
2263 CHeapPtr<WCHAR, CLocalAllocator> wszApplicationName;
2264 DWORD dwApplicationNameLen = MAX_PATH + 2;
2265 if (!sei_tmp.lpFile)
2266 {
2267 wszApplicationName.Allocate(dwApplicationNameLen);
2268 *wszApplicationName = '\0';
2269 }
2270 else if (*sei_tmp.lpFile == '\"' && sei_tmp.lpFile[(len = strlenW(sei_tmp.lpFile))-1] == '\"')
2271 {
2272 if(len-1 >= dwApplicationNameLen)
2273 dwApplicationNameLen = len;
2274
2275 wszApplicationName.Allocate(dwApplicationNameLen);
2276 memcpy(wszApplicationName, sei_tmp.lpFile + 1, len * sizeof(WCHAR));
2277
2278 if(len > 2)
2279 wszApplicationName[len-2] = '\0';
2280 appKnownSingular = TRUE;
2281
2282 TRACE("wszApplicationName=%s\n", debugstr_w(wszApplicationName));
2283 }
2284 else
2285 {
2286 DWORD l = strlenW(sei_tmp.lpFile) + 1;
2287 if(l > dwApplicationNameLen) dwApplicationNameLen = l + 1;
2288 wszApplicationName.Allocate(dwApplicationNameLen);
2289 memcpy(wszApplicationName, sei_tmp.lpFile, l * sizeof(WCHAR));
2290
2291 if (wszApplicationName[2] == 0 && wszApplicationName[1] == L':' &&
2292 ((L'A' <= wszApplicationName[0] && wszApplicationName[0] <= L'Z') ||
2293 (L'a' <= wszApplicationName[0] && wszApplicationName[0] <= L'z')))
2294 {
2295 // 'C:' --> 'C:\'
2296 PathAddBackslashW(wszApplicationName);
2297 }
2298 }
2299
2300 WCHAR parametersBuffer[1024];
2301 LPWSTR wszParameters = parametersBuffer;
2303 DWORD parametersLen = _countof(parametersBuffer);
2304
2305 if (sei_tmp.lpParameters)
2306 {
2307 len = lstrlenW(sei_tmp.lpParameters) + 1;
2308 if (len > parametersLen)
2309 {
2310 wszParamAlloc.Allocate(len);
2311 wszParameters = wszParamAlloc;
2312 parametersLen = len;
2313 }
2314 strcpyW(wszParameters, sei_tmp.lpParameters);
2315 }
2316 else
2317 *wszParameters = L'\0';
2318
2319 // Get the working directory
2320 WCHAR dirBuffer[MAX_PATH];
2321 LPWSTR wszDir = dirBuffer;
2322 wszDir[0] = UNICODE_NULL;
2324 if (sei_tmp.lpDirectory && *sei_tmp.lpDirectory)
2325 {
2326 if (sei_tmp.fMask & SEE_MASK_DOENVSUBST)
2327 {
2328 LPWSTR tmp = expand_environment(sei_tmp.lpDirectory);
2329 if (tmp)
2330 {
2331 wszDirAlloc.Attach(tmp);
2332 wszDir = wszDirAlloc;
2333 }
2334 }
2335 else
2336 {
2337 __SHCloneStrW(&wszDirAlloc, sei_tmp.lpDirectory);
2338 if (wszDirAlloc)
2339 wszDir = wszDirAlloc;
2340 }
2341 }
2342 if (!wszDir[0])
2343 {
2344 ::GetCurrentDirectoryW(_countof(dirBuffer), dirBuffer);
2345 wszDir = dirBuffer;
2346 }
2347 // NOTE: ShellExecute should accept the invalid working directory for historical reason.
2348 if (!PathIsDirectoryW(wszDir))
2349 {
2350 INT iDrive = PathGetDriveNumberW(wszDir);
2351 if (iDrive >= 0)
2352 {
2353 PathStripToRootW(wszDir);
2354 if (!PathIsDirectoryW(wszDir))
2355 {
2356 ::GetWindowsDirectoryW(dirBuffer, _countof(dirBuffer));
2357 wszDir = dirBuffer;
2358 }
2359 }
2360 }
2361
2362 /* adjust string pointers to point to the new buffers */
2363 sei_tmp.lpFile = wszApplicationName;
2364 sei_tmp.lpParameters = wszParameters;
2365 sei_tmp.lpDirectory = wszDir;
2366
2367 if (sei_tmp.fMask & unsupportedFlags)
2368 {
2369 FIXME("flags ignored: 0x%08x\n", sei_tmp.fMask & unsupportedFlags);
2370 }
2371
2372 /* process the IDList */
2373 if ((sei_tmp.fMask & SEE_MASK_INVOKEIDLIST) == SEE_MASK_IDLIST)
2374 {
2375 LPCITEMIDLIST pidl = (LPCITEMIDLIST)sei_tmp.lpIDList;
2376 hr = SHGetNameAndFlagsW(pidl, SHGDN_FORPARSING, wszApplicationName, dwApplicationNameLen, NULL);
2377 if (FAILED(hr))
2378 {
2379 if (dwApplicationNameLen)
2380 *wszApplicationName = UNICODE_NULL;
2381 if (!_ILIsDesktop(pidl))
2382 TRACE("Unable to get PIDL parsing path\n");
2383 }
2384 appKnownSingular = TRUE;
2385 TRACE("-- idlist=%p (%s)\n", sei_tmp.lpIDList, debugstr_w(wszApplicationName));
2386 }
2387
2388 if ((sei_tmp.fMask & SEE_MASK_DOENVSUBST) && !StrIsNullOrEmpty(sei_tmp.lpFile))
2389 {
2390 WCHAR *tmp = expand_environment(sei_tmp.lpFile);
2391 if (tmp)
2392 {
2393 wszApplicationName.Attach(tmp);
2394 sei_tmp.lpFile = wszApplicationName;
2395 }
2396 }
2397
2399 {
2400 hr = ShellExecute_ContextMenuVerb(&sei_tmp);
2401 if (SUCCEEDED(hr))
2402 {
2403 sei->hInstApp = (HINSTANCE)42;
2404 return TRUE;
2405 }
2408 return ExecuteFailed(retval, *sei, NULL, FALSE) > 32;
2409 }
2410
2412 {
2413 sei->hInstApp = (HINSTANCE) 33;
2414 return TRUE;
2415 }
2416
2417 if (sei_tmp.fMask & SEE_MASK_CLASSALL)
2418 {
2419 retval = SHELL_execute_class(wszApplicationName, &sei_tmp, sei, execfunc);
2420 if (retval <= 32 && !(sei_tmp.fMask & SEE_MASK_FLAG_NO_UI))
2421 {
2423
2424 //FIXME
2425 // need full path
2426
2427 Info.pcszFile = wszApplicationName;
2428 Info.pcszClass = NULL;
2429 Info.oaifInFlags = OAIF_ALLOW_REGISTRATION | OAIF_EXEC;
2430
2431 //if (SHOpenWithDialog(sei_tmp.hwnd, &Info) != S_OK)
2433 do_error_dialog(retval, sei_tmp.hwnd, wszApplicationName);
2434 }
2435 return retval > 32;
2436 }
2437
2438 if (!(sei_tmp.fMask & SEE_MASK_IDLIST) && // Not an ID List
2439 (StrCmpNIW(sei_tmp.lpFile, L"shell:", 6) == 0 ||
2440 StrCmpNW(sei_tmp.lpFile, L"::{", 3) == 0))
2441 {
2442 CComHeapPtr<ITEMIDLIST> pidlParsed;
2443 hr = SHParseDisplayName(sei_tmp.lpFile, NULL, &pidlParsed, 0, NULL);
2444 if (SUCCEEDED(hr) && SHELL_InvokePidl(&sei_tmp, pidlParsed))
2445 {
2446 sei_tmp.hInstApp = (HINSTANCE)UlongToHandle(42);
2447 return TRUE;
2448 }
2449 }
2450
2451 /* Has the IDList not yet been translated? */
2452 if (sei_tmp.fMask & SEE_MASK_IDLIST)
2453 {
2454 appKnownSingular = SHELL_translate_idlist( &sei_tmp, wszParameters,
2455 parametersLen,
2456 wszApplicationName,
2457 dwApplicationNameLen );
2458 }
2459
2460 /* convert file URLs */
2461 if (UrlIsFileUrlW(sei_tmp.lpFile))
2462 {
2465 if (!buf.Allocate(size) || FAILED(PathCreateFromUrlW(sei_tmp.lpFile, buf, &size, 0)))
2466 {
2468 return FALSE;
2469 }
2470
2471 wszApplicationName.Attach(buf.Detach());
2472 sei_tmp.lpFile = wszApplicationName;
2473 }
2474
2475 /* Else, try to execute the filename */
2476 TRACE("execute: %s,%s,%s\n", debugstr_w(wszApplicationName), debugstr_w(wszParameters), debugstr_w(wszDir));
2477
2478 /* separate out command line arguments from executable file name */
2479 LPCWSTR lpFile = sei_tmp.lpFile;
2480 if (!*sei_tmp.lpParameters && !appKnownSingular)
2481 {
2482 /* If the executable path is quoted, handle the rest of the command line as parameters. */
2483 if (sei_tmp.lpFile[0] == L'"')
2484 {
2485 LPWSTR pszArgs = PathGetArgsW(wszApplicationName);
2486 PathRemoveArgsW(wszApplicationName);
2487 PathUnquoteSpacesW(wszApplicationName);
2488 parametersLen = lstrlenW(pszArgs);
2489 if (parametersLen < _countof(parametersBuffer))
2490 {
2491 StringCchCopyW(parametersBuffer, _countof(parametersBuffer), pszArgs);
2492 wszParameters = parametersBuffer;
2493 }
2494 else
2495 {
2496 wszParamAlloc.Attach(StrDupW(pszArgs));
2497 wszParameters = wszParamAlloc;
2498 }
2499 }
2500 /* We have to test sei instead of sei_tmp because sei_tmp had its
2501 * input fMask modified above in SHELL_translate_idlist.
2502 * This code is needed to handle the case where we only have an
2503 * lpIDList with multiple CLSID/PIDL's (not 'My Computer' only) */
2504 else if ((sei->fMask & SEE_MASK_IDLIST) == SEE_MASK_IDLIST)
2505 {
2506 WCHAR buffer[MAX_PATH], xlpFile[MAX_PATH];
2507 LPWSTR space, s;
2508
2509 LPWSTR beg = wszApplicationName;
2510 for(s = beg; (space = const_cast<LPWSTR>(strchrW(s, L' '))); s = space + 1)
2511 {
2512 int idx = space - sei_tmp.lpFile;
2513 memcpy(buffer, sei_tmp.lpFile, idx * sizeof(WCHAR));
2514 buffer[idx] = '\0';
2515
2516 if (SearchPathW(*sei_tmp.lpDirectory ? sei_tmp.lpDirectory : NULL,
2517 buffer, L".exe", _countof(xlpFile), xlpFile, NULL))
2518 {
2519 /* separate out command from parameter string */
2520 LPCWSTR p = space + 1;
2521
2522 while(isspaceW(*p))
2523 ++p;
2524
2525 strcpyW(wszParameters, p);
2526 *space = L'\0';
2527
2528 break;
2529 }
2530 }
2531 }
2532 }
2533
2534 WCHAR wcmdBuffer[1024];
2535 LPWSTR wcmd = wcmdBuffer;
2536 DWORD wcmdLen = _countof(wcmdBuffer);
2538
2539 /* Only execute if it has an executable extension */
2540 if (PathIsExeW(lpFile))
2541 {
2542 len = lstrlenW(wszApplicationName) + 3;
2543 if (sei_tmp.lpParameters[0])
2544 len += 1 + lstrlenW(wszParameters);
2545 if (len > wcmdLen)
2546 {
2547 wcmdAlloc.Allocate(len);
2548 wcmd = wcmdAlloc;
2549 wcmdLen = len;
2550 }
2551 _swprintf(wcmd, L"\"%s\"", (LPWSTR)wszApplicationName);
2552 if (sei_tmp.lpParameters[0])
2553 {
2554 strcatW(wcmd, L" ");
2555 strcatW(wcmd, wszParameters);
2556 }
2557
2558 retval = execfunc(wcmd, NULL, FALSE, &sei_tmp, sei);
2559 if (retval > 32)
2560 return TRUE;
2561 }
2562
2563 /* Else, try to find the executable */
2564 WCHAR wszKeyname[256];
2566 wcmd[0] = UNICODE_NULL;
2567 retval = SHELL_FindExecutable(sei_tmp.lpDirectory, lpFile, sei_tmp.lpVerb, wcmd, wcmdLen, wszKeyname, &env, (LPITEMIDLIST)sei_tmp.lpIDList, sei_tmp.lpParameters);
2568 if (retval > 32) /* Found */
2569 {
2570 retval = SHELL_quote_and_execute(wcmd, wszParameters, wszKeyname,
2571 wszApplicationName, env, &sei_tmp,
2572 sei, execfunc);
2573 }
2574 else if (PathIsDirectoryW(lpFile))
2575 {
2576 WCHAR wExec[MAX_PATH];
2578 if (lpQuotedFile.Allocate(strlenW(lpFile) + 3))
2579 {
2580 retval = SHELL_FindExecutable(sei_tmp.lpDirectory, L"explorer",
2581 L"open", wExec, MAX_PATH,
2582 NULL, &env, NULL, NULL);
2583 if (retval > 32)
2584 {
2585 _swprintf(lpQuotedFile, L"\"%s\"", lpFile);
2586 retval = SHELL_quote_and_execute(wExec, lpQuotedFile,
2587 wszKeyname,
2588 wszApplicationName, env,
2589 &sei_tmp, sei, execfunc);
2590 }
2591 }
2592 else
2593 retval = 0; /* Out of memory */
2594 }
2595 else if (PathIsURLW(lpFile)) /* File not found, check for URL */
2596 {
2597 retval = SHELL_execute_url(lpFile, wcmd, &sei_tmp, sei, execfunc );
2598 }
2599 /* Check if file specified is in the form www.??????.*** */
2600 else if (!strncmpiW(lpFile, L"www", 3))
2601 {
2602 /* if so, prefix lpFile with http:// and call ShellExecute */
2603 WCHAR lpstrTmpFile[256];
2604 strcpyW(lpstrTmpFile, L"http://");
2605 strcatW(lpstrTmpFile, lpFile); // FIXME: Possible buffer overflow
2606 // FIXME: This will not correctly return the hProcess to the caller
2607 retval = (UINT_PTR)ShellExecuteW(sei_tmp.hwnd, sei_tmp.lpVerb, lpstrTmpFile, NULL, NULL, 0);
2608 }
2609
2610 TRACE("retval %lu\n", retval);
2611
2612 if (retval <= 32)
2613 retval = ExecuteFailed(retval, *sei, lpFile);
2614
2615 sei->hInstApp = (HINSTANCE)(retval > 32 ? 33 : retval);
2616 return retval > 32;
2617}
BOOL _ILIsDesktop(LPCITEMIDLIST pidl)
Definition: CBandSite.h:24
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:2370
void WINAPI PathUnquoteSpacesW(WCHAR *path)
Definition: path.c:1982
int WINAPI PathGetDriveNumberW(const WCHAR *path)
Definition: path.c:1786
HRESULT WINAPI PathCreateFromUrlW(const WCHAR *url, WCHAR *path, DWORD *pcchPath, DWORD dwReserved)
Definition: path.c:3049
BOOL WINAPI PathStripToRootW(WCHAR *path)
Definition: path.c:1171
BOOL WINAPI PathIsURLW(const WCHAR *path)
Definition: path.c:3214
WCHAR *WINAPI PathGetArgsW(const WCHAR *path)
Definition: path.c:1716
WCHAR *WINAPI StrDupW(const WCHAR *str)
Definition: string.c:317
EXTERN_C HRESULT SHGetNameAndFlagsW(_In_ LPCITEMIDLIST pidl, _In_ DWORD dwFlags, _Out_opt_ LPWSTR pszText, _In_ UINT cchBuf, _Inout_opt_ DWORD *pdwAttributes)
Definition: utils.cpp:551
void WINAPI PathRemoveArgsW(LPWSTR lpszPath)
Definition: path.c:153
BOOL WINAPI PathIsDirectoryW(LPCWSTR lpszPath)
Definition: path.c:669
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:302
HRESULT WINAPI SHParseDisplayName(LPCWSTR pszName, IBindCtx *pbc, LPITEMIDLIST *ppidl, SFGAOF sfgaoIn, SFGAOF *psfgaoOut)
Definition: pidl.c:1548
#define UrlIsFileUrlW(x)
Definition: shlwapi.h:643
#define err(...)
static __inline void __SHCloneStrW(WCHAR **target, const WCHAR *source)
Definition: shell32_main.h:221
#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:1936
static HRESULT ShellExecute_ContextMenuVerb(LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:1825
static BOOL SHELL_InvokePidl(_In_ LPSHELLEXECUTEINFOW sei, _In_ LPCITEMIDLIST pidl)
Definition: shlexec.cpp:2051
static LONG ShellExecute_FromContextMenuHandlers(LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:1891
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:1034
static UINT_PTR ExecuteFailed(UINT_PTR retval, SHELLEXECUTEINFOW &sei, LPCWSTR lpFile, BOOL AllowOpenWith=TRUE)
Definition: shlexec.cpp:2194
static WCHAR * expand_environment(const WCHAR *str)
Definition: shlexec.cpp:2207
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:2139
HINSTANCE WINAPI ShellExecuteW(HWND hwnd, LPCWSTR lpVerb, LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd)
Definition: shlexec.cpp:2793
static BOOL SHELL_translate_idlist(LPSHELLEXECUTEINFOW sei, LPWSTR wszParameters, DWORD parametersLen, LPWSTR wszApplicationName, DWORD dwApplicationNameLen)
Definition: shlexec.cpp:1995
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:2103
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
#define strncmpiW(s1, s2, n)
Definition: unicode.h:40
#define strcatW(d, s)
Definition: unicode.h:30
#define isspaceW(n)
Definition: unicode.h:52
#define HRESULT_FACILITY(hr)
Definition: winerror.h:191
#define FACILITY_WIN32
Definition: winerror.h:29
#define HRESULT_CODE(hr)
Definition: winerror.h:188

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

1937{
1938 WCHAR execCmd[1024], classname[1024];
1939 /* launch a document by fileclass like 'WordPad.Document.1' */
1940 /* the Commandline contains 'c:\Path\wordpad.exe "%1"' */
1941 /* FIXME: wcmd should not be of a fixed size. Fixed to 1024, MAX_PATH is way too short! */
1942 ULONG cmask = (psei->fMask & SEE_MASK_CLASSALL);
1943 DWORD resultLen;
1944 BOOL done;
1945 UINT_PTR rslt;
1946
1947 /* FIXME: remove following block when SHELL_quote_and_execute supports hkeyClass parameter */
1948 if (cmask != SEE_MASK_CLASSNAME)
1949 {
1950 WCHAR wcmd[1024];
1952 (cmask == SEE_MASK_CLASSNAME) ? psei->lpClass : NULL,
1953 psei->lpVerb,
1954 execCmd, sizeof(execCmd));
1955
1956 /* FIXME: get the extension of lpFile, check if it fits to the lpClass */
1957 TRACE("SEE_MASK_CLASSNAME->%s, doc->%s\n", debugstr_w(execCmd), debugstr_w(wszApplicationName));
1958
1959 wcmd[0] = '\0';
1960 done = SHELL_ArgifyW(wcmd, ARRAY_SIZE(wcmd), execCmd, wszApplicationName, (LPITEMIDLIST)psei->lpIDList, psei->lpParameters,
1961 &resultLen, (psei->lpDirectory && *psei->lpDirectory) ? psei->lpDirectory : NULL);
1962 if (!done && wszApplicationName[0])
1963 {
1964#if 0 // Given HKCR\.test=SZ:"test" and HKCR\test\shell\open\command=SZ:"cmd.exe /K echo.Hello", no filename is
1965 // appended on Windows when there is no %1 nor %L when executed with: shlextdbg.exe /shellexec=c:\file.test /INVOKE
1966 strcatW(wcmd, L" ");
1967 if (*wszApplicationName != '"')
1968 {
1969 strcatW(wcmd, L"\"");
1970 strcatW(wcmd, wszApplicationName);
1971 strcatW(wcmd, L"\"");
1972 }
1973 else
1974 strcatW(wcmd, wszApplicationName);
1975#endif
1976 }
1977 if (resultLen > ARRAY_SIZE(wcmd))
1978 ERR("Argify buffer not large enough... truncating\n");
1979 return execfunc(wcmd, NULL, FALSE, psei, psei_out);
1980 }
1981
1982 strcpyW(classname, psei->lpClass);
1983 rslt = SHELL_FindExecutableByVerb(psei->lpVerb, NULL, classname, execCmd, sizeof(execCmd));
1984
1985 TRACE("SHELL_FindExecutableByVerb returned %u (%s, %s)\n", (unsigned int)rslt, debugstr_w(classname), debugstr_w(execCmd));
1986 if (33 > rslt)
1987 return rslt;
1988 rslt = SHELL_quote_and_execute( execCmd, L"", classname,
1989 wszApplicationName, NULL, psei,
1990 psei_out, execfunc );
1991 return rslt;
1992
1993}
WCHAR classname[128]
Definition: startup.c:15
BOOL HCR_GetExecuteCommandW(HKEY hkeyClass, LPCWSTR szClass, LPCWSTR szVerb, LPWSTR szDest, DWORD len)
Definition: classes.c:224
#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:966
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 2139 of file shlexec.cpp.

2140{
2143 LPCWSTR lpstrRes;
2144 INT iSize;
2145 DWORD len;
2146
2147 lpstrRes = strchrW(lpFile, ':');
2148 if (lpstrRes)
2149 iSize = lpstrRes - lpFile;
2150 else
2151 iSize = strlenW(lpFile);
2152
2153 TRACE("Got URL: %s\n", debugstr_w(lpFile));
2154 /* Looking for ...<protocol>\shell<lpVerb>\command */
2155 len = iSize + lstrlenW(L"\\shell\\") + lstrlenW(L"\\command") + 1;
2156 if (psei->lpVerb && *psei->lpVerb)
2157 len += lstrlenW(psei->lpVerb);
2158 else
2159 len += lstrlenW(L"open"); // FIXME: Use HCR_GetExecuteCommandW or AssocAPI
2160 lpstrProtocol.Allocate(len);
2161 memcpy(lpstrProtocol, lpFile, iSize * sizeof(WCHAR));
2162 lpstrProtocol[iSize] = '\0';
2163 strcatW(lpstrProtocol, L"\\shell\\");
2164 strcatW(lpstrProtocol, psei->lpVerb && *psei->lpVerb ? psei->lpVerb : L"open");
2165 strcatW(lpstrProtocol, L"\\command");
2166
2167 retval = execute_from_key(lpstrProtocol, lpFile, NULL, psei->lpParameters,
2168 wcmd, execfunc, psei, psei_out);
2169
2170 return retval;
2171}
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:1485

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

727{
731 UINT gcdret = 0, lasterror = 0;
732 WCHAR curdir[MAX_PATH];
733 DWORD dwCreationFlags = CREATE_UNICODE_ENVIRONMENT;
734 const WCHAR *lpDirectory = NULL;
735
736 TRACE("Execute %s from directory %s\n", debugstr_w(lpCmd), debugstr_w(psei->lpDirectory));
737
738 /* make sure we don't fail the CreateProcess if the calling app passes in
739 * a bad working directory */
740 if (!StrIsNullOrEmpty(psei->lpDirectory))
741 {
744 lpDirectory = psei->lpDirectory;
745 }
746
747 /* ShellExecute specifies the command from psei->lpDirectory
748 * if present. Not from the current dir as CreateProcess does */
749 if (lpDirectory)
750 if ((gcdret = GetCurrentDirectoryW( MAX_PATH, curdir)))
752 ERR("cannot set directory %s\n", debugstr_w(lpDirectory));
753
755 startup.cb = sizeof(STARTUPINFOW);
757 startup.wShowWindow = psei->nShow;
758 if (!(psei->fMask & SEE_MASK_NO_CONSOLE))
759 dwCreationFlags |= CREATE_NEW_CONSOLE;
760 if (psei->fMask & SEE_MASK_FLAG_SEPVDM)
761 dwCreationFlags |= CREATE_SEPARATE_WOW_VDM;
762 startup.lpTitle = (LPWSTR)(psei->fMask & (SEE_MASK_HASLINKNAME | SEE_MASK_HASTITLE) ? psei->lpClass : NULL);
763
764 if (psei->fMask & SEE_MASK_HASLINKNAME)
765 startup.dwFlags |= STARTF_TITLEISLINKNAME;
766
767 if (psei->fMask & SEE_MASK_HOTKEY)
768 {
769 startup.hStdInput = UlongToHandle(psei->dwHotKey);
770 startup.dwFlags |= STARTF_USEHOTKEY;
771 }
772
773 if (psei->fMask & SEE_MASK_ICON) // hIcon has higher precedence than hMonitor
774 {
775 startup.hStdOutput = psei->hIcon;
776 startup.dwFlags |= STARTF_SHELLPRIVATE;
777 }
778 else if ((psei->fMask & SEE_MASK_HMONITOR) || psei->hwnd)
779 {
780 if (psei->fMask & SEE_MASK_HMONITOR)
781 startup.hStdOutput = psei->hMonitor;
782 else if (psei->hwnd)
783 startup.hStdOutput = MonitorFromWindow(psei->hwnd, MONITOR_DEFAULTTONEAREST);
784 if (startup.hStdOutput)
785 startup.dwFlags |= STARTF_SHELLPRIVATE;
786 }
787
788 BOOL createdProcess;
789 if (psei->lpVerb && !StrCmpIW(L"runas", psei->lpVerb))
790 {
791 HRESULT hr = PromptAndRunProcessAs(psei->hwnd, (LPWSTR)lpCmd, dwCreationFlags,
793 createdProcess = hr == S_OK;
794 if (hr == S_FALSE)
795 {
796 retval = 33; // Pretend cancel is success.
797 goto done;
798 }
799 }
800 else
801 {
802 createdProcess = CreateProcessW(NULL, (LPWSTR)lpCmd, NULL, NULL, FALSE,
803 dwCreationFlags, env, lpDirectory, &startup, &info);
804 }
805
806 if (createdProcess)
807 {
808 /* Give 30 seconds to the app to come up, if desired. Probably only needed
809 when starting app immediately before making a DDE connection. */
810 if (shWait)
811 if (WaitForInputIdle(info.hProcess, 30000) == WAIT_FAILED)
812 WARN("WaitForInputIdle failed: Error %d\n", GetLastError() );
813 retval = 33;
814
815 if (psei->fMask & SEE_MASK_NOCLOSEPROCESS)
816 psei_out->hProcess = info.hProcess;
817 else
818 CloseHandle( info.hProcess );
819 CloseHandle( info.hThread );
820 }
821 else if ((retval = lasterror = GetLastError()) >= 32)
822 {
823 WARN("CreateProcess returned error %ld\n", retval);
825 }
826
827done:
828 TRACE("returning %lu\n", retval);
829 psei_out->hInstApp = (HINSTANCE)retval;
830
831 if (gcdret)
832 {
833 if (!SetCurrentDirectoryW(curdir))
834 ERR("cannot return to directory %s\n", debugstr_w(curdir));
835 if (lasterror)
836 RestoreLastError(lasterror);
837 }
838 return retval;
839}
static void startup(void)
#define CloseHandle
Definition: compat.h:739
int WINAPI StrCmpIW(const WCHAR *str, const WCHAR *comp)
Definition: string.c:464
HMONITOR WINAPI MonitorFromWindow(HWND, DWORD)
#define STARTF_USEHOTKEY
Definition: pch.h:41
struct _STARTUPINFOW STARTUPINFOW
DWORD WINAPI WaitForInputIdle(_In_ HANDLE, _In_ DWORD)
#define SEE_MASK_HOTKEY
Definition: shellapi.h:32
#define SEE_MASK_HMONITOR
Definition: shellapi.h:45
static HRESULT PromptAndRunProcessAs(_In_opt_ HWND hwnd, _In_ LPWSTR Cmd, _In_ DWORD CreationFlags, _In_opt_ LPWSTR Env, _In_opt_ LPCWSTR Dir, _In_ STARTUPINFOW *pSI, _Out_ PROCESS_INFORMATION *pPI)
Definition: shlexec.cpp:661
Definition: cookie.c:202
#define SEE_MASK_HASLINKNAME
Definition: undocshell.h:737
#define STARTF_USESHOWWINDOW
Definition: winbase.h:468
#define CREATE_UNICODE_ENVIRONMENT
Definition: winbase.h:191
#define CREATE_SEPARATE_WOW_VDM
Definition: winbase.h:192
#define WAIT_FAILED
Definition: winbase.h:390
#define CREATE_NEW_CONSOLE
Definition: winbase.h:185
#define ERROR_BAD_FORMAT
Definition: winerror.h:236

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

1036{
1037 WCHAR *extension = NULL; /* pointer to file extension */
1038 WCHAR classname[256]; /* registry name for this file type */
1039 LONG classnamelen = sizeof(classname); /* length of above */
1040 WCHAR command[1024]; /* command from registry */
1041 WCHAR wBuffer[256]; /* Used to GetProfileString */
1043 WCHAR *tok; /* token pointer */
1044 WCHAR xlpFile[MAX_PATH]; /* result of PathResolve */
1045 DWORD attribs; /* file attributes */
1046 WCHAR curdir[MAX_PATH];
1047 const WCHAR *search_paths[3] = {0};
1048
1049 TRACE("%s\n", debugstr_w(lpFile));
1050
1051 if (!lpResult)
1053
1054 xlpFile[0] = '\0';
1055 lpResult[0] = '\0'; /* Start off with an empty return string */
1056 if (key) *key = '\0';
1057
1058 /* trap NULL parameters on entry */
1059 if (!lpFile)
1060 {
1061 WARN("(lpFile=%s,lpResult=%s): NULL parameter\n",
1062 debugstr_w(lpFile), debugstr_w(lpResult));
1063 return ERROR_FILE_NOT_FOUND; /* File not found. Close enough, I guess. */
1064 }
1065
1066 if (SHELL_TryAppPathW( lpFile, lpResult, env ))
1067 {
1068 TRACE("found %s via App Paths\n", debugstr_w(lpResult));
1069 return 33;
1070 }
1071
1072 GetCurrentDirectoryW(ARRAY_SIZE(curdir), curdir);
1073 if (lpPath && *lpPath)
1074 {
1075 search_paths[0] = lpPath;
1076 search_paths[1] = curdir;
1077 }
1078 else
1079 {
1080 search_paths[0] = curdir;
1081 }
1082
1083 lstrcpyW(xlpFile, lpFile);
1084 if (PathResolveW(xlpFile, search_paths, PRF_TRYPROGRAMEXTENSIONS | PRF_VERIFYEXISTS) ||
1085 PathFindOnPathW(xlpFile, search_paths))
1086 {
1087 TRACE("PathResolveW returned non-zero\n");
1088 lpFile = xlpFile;
1089 PathRemoveBlanksW(xlpFile);
1090
1091 /* Clear any trailing periods */
1092 SIZE_T i = wcslen(xlpFile);
1093 while (i > 0 && xlpFile[i - 1] == '.')
1094 {
1095 xlpFile[--i] = '\0';
1096 }
1097
1098 lstrcpyW(lpResult, xlpFile);
1099 /* The file was found in lpPath or one of the directories in the system-wide search path */
1100 }
1101 /* Handle cases like CORE-20508 */
1102 else if (SearchPathW(lpPath, lpFile, NULL, ARRAY_SIZE(xlpFile), xlpFile, NULL))
1103 {
1104 TRACE("SearchPathW returned non-zero\n");
1105 lpFile = xlpFile;
1106 }
1107 else
1108 {
1109 xlpFile[0] = '\0';
1110 }
1111
1112 attribs = GetFileAttributesW(lpFile);
1114 {
1115 wcscpy(classname, L"Folder");
1116 }
1117 else
1118 {
1119 /* Did we get something? Anything? */
1120 if (xlpFile[0] == 0)
1121 {
1122 TRACE("Returning SE_ERR_FNF\n");
1123 return SE_ERR_FNF;
1124 }
1125 /* First thing we need is the file's extension */
1126 extension = wcsrchr(xlpFile, '.'); /* Assume last "." is the one; */
1127 /* File->Run in progman uses */
1128 /* .\FILE.EXE :( */
1129 TRACE("xlpFile=%s,extension=%s\n", debugstr_w(xlpFile), debugstr_w(extension));
1130
1131 if (extension == NULL || extension[1] == 0)
1132 {
1133 WARN("Returning SE_ERR_NOASSOC\n");
1134 return SE_ERR_NOASSOC;
1135 }
1136
1137 /* Three places to check: */
1138 /* 1. win.ini, [windows], programs (NB no leading '.') */
1139 /* 2. Registry, HKEY_CLASS_ROOT<classname>\shell\open\command */
1140 /* 3. win.ini, [extensions], extension (NB no leading '.' */
1141 /* All I know of the order is that registry is checked before */
1142 /* extensions; however, it'd make sense to check the programs */
1143 /* section first, so that's what happens here. */
1144
1145 /* See if it's a program - if GetProfileString fails, we skip this
1146 * section. Actually, if GetProfileString fails, we've probably
1147 * got a lot more to worry about than running a program... */
1148 if (GetProfileStringW(L"windows", L"programs", L"exe pif bat cmd com", wBuffer, ARRAY_SIZE(wBuffer)) > 0)
1149 {
1150 CharLowerW(wBuffer);
1151 tok = wBuffer;
1152 while (*tok)
1153 {
1154 WCHAR *p = tok;
1155 while (*p && *p != ' ' && *p != '\t') p++;
1156 if (*p)
1157 {
1158 *p++ = 0;
1159 while (*p == ' ' || *p == '\t') p++;
1160 }
1161
1162 if (_wcsicmp(tok, &extension[1]) == 0) /* have to skip the leading "." */
1163 {
1164 wcscpy(lpResult, xlpFile);
1165 /* Need to perhaps check that the file has a path
1166 * attached */
1167 TRACE("found %s\n", debugstr_w(lpResult));
1168 return 33;
1169 /* Greater than 32 to indicate success */
1170 }
1171 tok = p;
1172 }
1173 }
1174
1175 /* Check registry */
1177 &classnamelen) == ERROR_SUCCESS)
1178 {
1179 classnamelen /= sizeof(WCHAR);
1180 if (classnamelen == ARRAY_SIZE(classname))
1181 classnamelen--;
1182
1183 classname[classnamelen] = '\0';
1184 TRACE("File type: %s\n", debugstr_w(classname));
1185 }
1186 else
1187 {
1188 *classname = '\0';
1189 }
1190 }
1191
1192 if (*classname)
1193 {
1194 /* pass the verb string to SHELL_FindExecutableByVerb() */
1196
1197 if (retval > 32)
1198 {
1199 DWORD finishedLen;
1200 SHELL_ArgifyW(lpResult, resultLen, command, xlpFile, pidl, args, &finishedLen, lpPath);
1201 if (finishedLen > resultLen)
1202 ERR("Argify buffer not large enough.. truncated\n");
1203 /* Remove double quotation marks and command line arguments */
1204 if (*lpResult == '"')
1205 {
1206 WCHAR *p = lpResult;
1207 while (*(p + 1) != '"')
1208 {
1209 *p = *(p + 1);
1210 p++;
1211 }
1212 *p = '\0';
1213 }
1214 else
1215 {
1216 /* Truncate on first space */
1217 WCHAR *p = lpResult;
1218 while (*p != ' ' && *p != '\0')
1219 p++;
1220 *p = '\0';
1221 }
1222 }
1223 }
1224 else /* Check win.ini */
1225 {
1226 /* Toss the leading dot */
1227 extension++;
1228 if (GetProfileStringW(L"extensions", extension, L"", command, ARRAY_SIZE(command)) > 0)
1229 {
1230 if (wcslen(command) != 0)
1231 {
1232 wcscpy(lpResult, command);
1233 tok = wcschr(lpResult, '^'); /* should be ^.extension? */
1234 if (tok != NULL)
1235 {
1236 tok[0] = '\0';
1237 wcscat(lpResult, xlpFile); /* what if no dir in xlpFile? */
1238 tok = wcschr(command, '^'); /* see above */
1239 if ((tok != NULL) && (wcslen(tok) > 5))
1240 {
1241 wcscat(lpResult, &tok[5]);
1242 }
1243 }
1244 retval = 33; /* FIXME - see above */
1245 }
1246 }
1247 }
1248
1249 TRACE("returning path %s, retval %d\n", debugstr_w(lpResult), retval);
1250 return retval;
1251}
#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:1886
LPWSTR WINAPI CharLowerW(WCHAR *str)
Definition: string.c:1136
_ACRTIMP int __cdecl _wcsicmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:164
BOOL WINAPI PathFindOnPathW(LPWSTR lpszFile, LPCWSTR *lppszOtherDirs)
Definition: path.c:456
const GLint * attribs
Definition: glext.h:10538
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
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static BOOL SHELL_TryAppPathW(LPCWSTR szName, LPWSTR lpResult, WCHAR **env)
Definition: shlexec.cpp:906

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

967{
968 HKEY hkeyClass;
969 WCHAR verb[MAX_PATH];
970
972 return SE_ERR_NOASSOC;
973 if (!HCR_GetDefaultVerbW(hkeyClass, lpVerb, verb, ARRAY_SIZE(verb)))
974 return SE_ERR_NOASSOC;
975 RegCloseKey(hkeyClass);
976
977 /* Looking for ...buffer\shell<verb>\command */
978 wcscat(classname, L"\\shell\\"); // FIXME: Use HCR_GetExecuteCommandW or AssocAPI
979 wcscat(classname, verb);
980 wcscat(classname, L"\\command");
981
983 &commandlen) == ERROR_SUCCESS)
984 {
985 commandlen /= sizeof(WCHAR);
986 if (key) wcscpy(key, classname);
987#if 0
988 LPWSTR tmp;
989 WCHAR param[256];
990 LONG paramlen = sizeof(param);
991
992 /* FIXME: it seems all Windows version don't behave the same here.
993 * the doc states that this ddeexec information can be found after
994 * the exec names.
995 * on Win98, it doesn't appear, but I think it does on Win2k
996 */
997 /* Get the parameters needed by the application
998 from the associated ddeexec key */
999 tmp = strstrW(classname, L"\\command");
1000 tmp[0] = '\0';
1001 wcscat(classname, wDdeexec);
1003 &paramlen) == ERROR_SUCCESS)
1004 {
1005 paramlen /= sizeof(WCHAR);
1006 wcscat(command, L" ");
1008 commandlen += paramlen;
1009 }
1010#endif
1011
1012 command[commandlen] = '\0';
1013
1014 return 33; /* FIXME see SHELL_FindExecutable() */
1015 }
1016
1017 return SE_ERR_NOASSOC;
1018}
#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:1026
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_GetUsableDialogOwner()

static HWND SHELL_GetUsableDialogOwner ( HWND  hWnd)
static

Definition at line 569 of file shlexec.cpp.

570{
571 // Explicitly block the shell desktop listview from becoming the owner (IContextMenu calling ShellExecute)
572 HWND hProgman = GetShellWindow();
574 hWnd != hProgman && !IsChild(hProgman, hWnd))
575 {
576 return hWnd;
577 }
578 return NULL;
579}
HWND hWnd
Definition: settings.c:17
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:628
BOOL WINAPI IsChild(_In_ HWND, _In_ HWND)
BOOL WINAPI IsWindowVisible(_In_ HWND)
HWND WINAPI GetShellWindow(void)
Definition: input.c:974

Referenced by PromptAndRunProcessAs().

◆ 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:1677

Referenced by ShellExec_RunDLL_Helper(), and ShellExecuteExW().

◆ SHELL_InvokePidl()

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

Definition at line 2051 of file shlexec.cpp.

2054{
2055 // Bind pidl
2056 CComPtr<IShellFolder> psfFolder;
2057 LPCITEMIDLIST pidlLast;
2058 HRESULT hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &psfFolder), &pidlLast);
2060 return FALSE;
2061
2062 // Get the context menu to invoke a command
2064 hr = psfFolder->GetUIObjectOf(NULL, 1, &pidlLast, IID_NULL_PPV_ARG(IContextMenu, &pCM));
2066 return FALSE;
2067
2068 // Invoke a command
2069 CMINVOKECOMMANDINFO ici = { sizeof(ici) };
2070 ici.fMask = (sei->fMask & SEE_CMIC_COMMON_BASICFLAGS) & ~CMIC_MASK_UNICODE; // FIXME: Unicode?
2071 ici.nShow = sei->nShow;
2072 ici.hwnd = sei->hwnd;
2073 char szVerb[VERBKEY_CCHMAX];
2074 if (sei->lpVerb && sei->lpVerb[0])
2075 {
2076 WideCharToMultiByte(CP_ACP, 0, sei->lpVerb, -1, szVerb, _countof(szVerb), NULL, NULL);
2077 szVerb[_countof(szVerb) - 1] = ANSI_NULL; // Avoid buffer overrun
2078 ici.lpVerb = szVerb;
2079 }
2080 else // The default verb?
2081 {
2082 HMENU hMenu = CreatePopupMenu();
2083 const INT idCmdFirst = 1, idCmdLast = 0x7FFF;
2084 hr = pCM->QueryContextMenu(hMenu, 0, idCmdFirst, idCmdLast, CMF_DEFAULTONLY);
2086 {
2087 DestroyMenu(hMenu);
2088 return FALSE;
2089 }
2090
2091 INT nDefaultID = GetMenuDefaultItem(hMenu, FALSE, 0);
2092 DestroyMenu(hMenu);
2093 if (nDefaultID == -1)
2094 nDefaultID = idCmdFirst;
2095
2096 ici.lpVerb = MAKEINTRESOURCEA(nDefaultID - idCmdFirst);
2097 }
2098 hr = pCM->InvokeCommand(&ici);
2099
2100 return !FAILED_UNEXPECTEDLY(hr);
2101}
#define VERBKEY_CCHMAX
Definition: precomp.h:135
#define FAILED_UNEXPECTEDLY
Definition: utils.cpp:33
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:60
#define ANSI_NULL
HRESULT WINAPI SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCITEMIDLIST *ppidlLast)
Definition: pidl.c:1504
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 2103 of file shlexec.cpp.

2104{
2106 DWORD len;
2108
2109 /* Length of quotes plus length of command plus NULL terminator */
2110 len = 2 + lstrlenW(wcmd) + 1;
2111 if (wszParameters[0])
2112 {
2113 /* Length of space plus length of parameters */
2114 len += 1 + lstrlenW(wszParameters);
2115 }
2116 wszQuotedCmd.Allocate(len);
2117 /* Must quote to handle case where cmd contains spaces,
2118 * else security hole if malicious user creates executable file "C:\\Program"
2119 */
2120 strcpyW(wszQuotedCmd, L"\"");
2121 strcatW(wszQuotedCmd, wcmd);
2122 strcatW(wszQuotedCmd, L"\"");
2123 if (wszParameters[0])
2124 {
2125 strcatW(wszQuotedCmd, L" ");
2126 strcatW(wszQuotedCmd, wszParameters);
2127 }
2128
2129 TRACE("%s/%s => %s/%s\n", debugstr_w(wszApplicationName), debugstr_w(psei->lpVerb), debugstr_w(wszQuotedCmd), debugstr_w(wszKeyname));
2130
2131 if (*wszKeyname)
2132 retval = execute_from_key(wszKeyname, wszApplicationName, env, psei->lpParameters, wcmd, execfunc, psei, psei_out);
2133 else
2134 retval = execfunc(wszQuotedCmd, env, FALSE, psei, psei_out);
2135
2136 return retval;
2137}

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

1996{
1998 BOOL appKnownSingular = FALSE;
1999
2000 /* last chance to translate IDList: now also allow CLSID paths */
2002 if (buffer[0] == ':' && buffer[1] == ':') {
2003 /* open shell folder for the specified class GUID */
2004 if (strlenW(buffer) + 1 > parametersLen)
2005 ERR("parameters len exceeds buffer size (%i > %i), truncating\n",
2006 lstrlenW(buffer) + 1, parametersLen);
2007 lstrcpynW(wszParameters, buffer, parametersLen);
2008 if (strlenW(L"explorer.exe") > dwApplicationNameLen)
2009 ERR("application len exceeds buffer size (%i), truncating\n",
2010 dwApplicationNameLen);
2011 lstrcpynW(wszApplicationName, L"explorer.exe", dwApplicationNameLen);
2012 appKnownSingular = TRUE;
2013
2014 sei->fMask &= ~SEE_MASK_INVOKEIDLIST;
2015 } else {
2017 DWORD attribs;
2018 DWORD resultLen;
2019 /* Check if we're executing a directory and if so use the
2020 handler for the Folder class */
2025 HCR_GetExecuteCommandW(0, L"Folder",
2026 sei->lpVerb,
2027 buffer, sizeof(buffer))) {
2028 SHELL_ArgifyW(wszApplicationName, dwApplicationNameLen,
2029 buffer, target, (LPITEMIDLIST)sei->lpIDList, NULL, &resultLen,
2030 !StrIsNullOrEmpty(sei->lpDirectory) ? sei->lpDirectory : NULL);
2031 if (resultLen > dwApplicationNameLen)
2032 ERR("Argify buffer not large enough... truncating\n"); // FIXME: Report this to the caller?
2033 appKnownSingular = FALSE;
2034 // HACKFIX: We really want the !appKnownSingular code in SHELL_execute to split the
2035 // parameters for us but we cannot guarantee that the exe in the registry is quoted.
2036 // We have now turned 'explorer.exe "%1" into 'explorer.exe "c:\path\from\pidl"' and
2037 // need to split to application and parameters.
2038 LPCWSTR params = PathGetArgsW(wszApplicationName);
2039 lstrcpynW(wszParameters, params, parametersLen);
2040 PathRemoveArgsW(wszApplicationName);
2041 PathUnquoteSpacesW(wszApplicationName);
2042 appKnownSingular = TRUE;
2043 }
2044 sei->fMask &= ~SEE_MASK_INVOKEIDLIST;
2045 }
2046 }
2047 return appKnownSingular;
2048}
#define lstrcpynW
Definition: compat.h:738
GLenum const GLfloat * params
Definition: glext.h:5645
static HRESULT SHELL_GetPathFromIDListForExecuteW(LPCITEMIDLIST pidl, LPWSTR pszPath, UINT uOutSize)
Definition: shlexec.cpp:551
Definition: tools.h:99
#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 906 of file shlexec.cpp.

907{
908 HKEY hkApp = NULL;
909 WCHAR buffer[1024];
910 DWORD len, dwType;
911 LONG res;
912 BOOL found = FALSE;
913
914 if (env) *env = NULL;
915 wcscpy(buffer, L"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\");
918 if (res)
919 {
920 // Add ".exe" extension, if extension does not exists
921 if (PathAddExtensionW(buffer, L".exe"))
922 {
924 }
925 if (res) goto end;
926 }
927
928 len = MAX_PATH * sizeof(WCHAR);
929 res = SHRegQueryValueExW(hkApp, NULL, NULL, &dwType, (LPBYTE)lpResult, &len);
930 if (res != ERROR_SUCCESS || dwType != REG_SZ)
931 goto end;
932
933 found = TRUE;
934
935 if (env)
936 {
937 len = sizeof(buffer);
938 res = SHRegQueryValueExW(hkApp, L"Path", NULL, &dwType, (LPBYTE)buffer, &len);
939 if (res == ERROR_SUCCESS && dwType == REG_SZ && buffer[0])
941 }
942
943end:
944 if (hkApp) RegCloseKey(hkApp);
945 return found;
946}
#define REG_SZ
Definition: layer.c:22
GLuint GLuint end
Definition: gl.h:1545
#define PathAddExtensionW
Definition: pathcch.h:306
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:848
#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 1786 of file shlexec.cpp.

1787{
1788 CComHeapPtr<ITEMIDLIST> allocatedPidl;
1789 LPITEMIDLIST pidl = NULL;
1790
1791 if (sei->lpIDList)
1792 {
1793 pidl = (LPITEMIDLIST)sei->lpIDList;
1794 }
1795 else
1796 {
1797 SFGAOF sfga = 0;
1798 HRESULT hr = SHParseDisplayName(sei->lpFile, NULL, &allocatedPidl, SFGAO_STORAGECAPMASK, &sfga);
1799 if (FAILED(hr))
1800 {
1801 WCHAR Buffer[MAX_PATH] = {};
1802 // FIXME: MAX_PATH.....
1804 if (retval <= 32)
1805 return HRESULT_FROM_WIN32(retval);
1806
1807 hr = SHParseDisplayName(Buffer, NULL, &allocatedPidl, SFGAO_STORAGECAPMASK, &sfga);
1808 // This should not happen, we found it...
1810 return hr;
1811 }
1812
1813 pidl = allocatedPidl;
1814 }
1815
1817 LPCITEMIDLIST pidllast = NULL;
1818 HRESULT hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &shf), &pidllast);
1819 if (FAILED(hr))
1820 return hr;
1821
1822 return shf->GetUIObjectOf(NULL, 1, &pidllast, IID_NULL_PPV_ARG(IContextMenu, &cm));
1823}
Definition: bufpool.h:45
static IShellFolder IShellItem **static IBindCtx LPITEMIDLIST SFGAOF
Definition: ebrowser.c:83

Referenced by ShellExecute_ContextMenuVerb().

◆ shellex_get_dataobj()

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

Definition at line 1658 of file shlexec.cpp.

1659{
1660 CComHeapPtr<ITEMIDLIST> allocatedPidl;
1661 LPITEMIDLIST pidl = NULL;
1662
1663 if (sei->fMask & SEE_MASK_CLASSALL) // FIXME: This makes no sense? SEE_MASK_IDLIST?
1664 {
1665 pidl = (LPITEMIDLIST)sei->lpIDList;
1666 }
1667 else
1668 {
1669 WCHAR fullpath[MAX_PATH];
1670 BOOL ret;
1671
1672 fullpath[0] = 0;
1673 ret = GetFullPathNameW(sei->lpFile, MAX_PATH, fullpath, NULL);
1674 if (!ret)
1676
1677 pidl = ILCreateFromPathW(fullpath);
1678 allocatedPidl.Attach(pidl);
1679 }
1681}
DWORD WINAPI GetFullPathNameW(IN LPCWSTR lpFileName, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart)
Definition: path.c:1164
EXTERN_C HRESULT SHELL_GetUIObjectOfAbsoluteItem(_In_opt_ HWND hWnd, _In_ PCIDLIST_ABSOLUTE pidl, _In_ REFIID riid, _Out_ void **ppvObj)
Definition: utils.cpp:428
LPITEMIDLIST WINAPI ILCreateFromPathW(LPCWSTR path)
Definition: pidl.c:1108

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

1753{
1754 TRACE("%p %s %p\n", hkey, debugstr_guid(guid), sei);
1755
1756 CCoInit coInit;
1757
1758 if (FAILED_UNEXPECTEDLY(coInit.hr))
1759 return coInit.hr;
1760
1762 HRESULT hr = CoCreateInstance(*guid, NULL, CLSCTX_INPROC_SERVER,
1765 return hr;
1766
1767 CComPtr<IDataObject> dataobj;
1768 hr = shellex_get_dataobj(sei, dataobj);
1770 return hr;
1771
1772 hr = obj->Initialize(NULL, dataobj, hkey);
1774 return hr;
1775
1777 hr = obj->QueryInterface(IID_PPV_ARG(IObjectWithSite, &ows));
1779 return hr;
1780
1781 ows->SetSite(NULL);
1782
1784}
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, IUnknown *outer, DWORD cls_context, REFIID riid, void **obj)
Definition: combase.c:1685
GUID guid
Definition: version.c:147
#define debugstr_guid
Definition: kernel32.h:35
static HRESULT shellex_run_context_menu_default(IShellExtInit *obj, LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:1683
static HRESULT shellex_get_dataobj(LPSHELLEXECUTEINFOW sei, CComPtr< IDataObject > &dataObj)
Definition: shlexec.cpp:1658

Referenced by ShellExecute_FromContextMenuHandlers().

◆ shellex_run_context_menu_default()

static HRESULT shellex_run_context_menu_default ( IShellExtInit *  obj,
LPSHELLEXECUTEINFOW  sei 
)
static

Definition at line 1683 of file shlexec.cpp.

1685{
1687 CMINVOKECOMMANDINFOEX ici;
1689 WCHAR string[0x80];
1690 INT i, n, def = -1;
1691 HMENU hmenu = 0;
1692 HRESULT r;
1693
1694 TRACE("%p %p\n", obj, sei);
1695
1696 r = obj->QueryInterface(IID_PPV_ARG(IContextMenu, &cm));
1697 if (FAILED(r))
1698 return r;
1699
1700 hmenu = CreateMenu();
1701 if (!hmenu)
1702 goto end;
1703
1704 /* the number of the last menu added is returned in r */
1705 r = cm->QueryContextMenu(hmenu, 0, 0x20, 0x7fff, CMF_DEFAULTONLY);
1706 if (FAILED(r))
1707 goto end;
1708
1710 for (i = 0; i < n; i++)
1711 {
1712 memset(&info, 0, sizeof(info));
1713 info.cbSize = sizeof info;
1715 info.dwTypeData = string;
1716 info.cch = sizeof string;
1717 string[0] = 0;
1719
1720 TRACE("menu %d %s %08x %08lx %08x %08x\n", i, debugstr_w(string),
1721 info.fState, info.dwItemData, info.fType, info.wID);
1722 if ((!sei->lpVerb && (info.fState & MFS_DEFAULT)) ||
1723 (sei->lpVerb && !lstrcmpiW(sei->lpVerb, string)))
1724 {
1725 def = i;
1726 break;
1727 }
1728 }
1729
1730 r = E_FAIL;
1731 if (def == -1)
1732 goto end;
1733
1734 memset(&ici, 0, sizeof ici);
1735 ici.cbSize = sizeof ici;
1736 ici.fMask = (sei->fMask & SEE_CMIC_COMMON_BASICFLAGS) | CMIC_MASK_UNICODE;
1737 ici.nShow = sei->nShow;
1738 ici.lpVerb = MAKEINTRESOURCEA(def);
1739 ici.hwnd = sei->hwnd;
1740 ici.lpParametersW = sei->lpParameters;
1741
1742 r = cm->InvokeCommand((LPCMINVOKECOMMANDINFO)&ici);
1743
1744 TRACE("invoke command returned %08x\n", r);
1745
1746end:
1747 if (hmenu)
1748 DestroyMenu( hmenu );
1749 return r;
1750}
int WINAPI lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4171
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLdouble n
Definition: glext.h:7729
static HMENU hmenu
Definition: win.c:78
#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
#define memset(x, y, z)
Definition: compat.h:39

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

3375{
3376 TRACE("(%p, %p, %s, 0x%X)\n", hwnd, hInstance, wine_dbgstr_w(pszCmdLine), nCmdShow);
3377
3378 if (!pszCmdLine || !*pszCmdLine)
3379 return;
3380
3381 // '?' enables us to specify the additional mask value
3382 ULONG fNewMask = SEE_MASK_NOASYNC;
3383 if (*pszCmdLine == L'?') // 1st question
3384 {
3385 INT MaskValue;
3386 if (StrToIntExW(pszCmdLine + 1, STIF_SUPPORT_HEX, &MaskValue))
3387 fNewMask |= MaskValue;
3388
3389 PCWSTR pch2ndQuestion = StrChrW(pszCmdLine + 1, L'?'); // 2nd question
3390 if (pch2ndQuestion)
3391 pszCmdLine = pch2ndQuestion + 1;
3392 }
3393
3394 WCHAR szPath[2 * MAX_PATH];
3396 if (PathProcessCommandW(pszCmdLine, szPath, _countof(szPath), dwFlags) == -1)
3397 StrCpyNW(szPath, pszCmdLine, _countof(szPath));
3398
3399 // Split arguments from the path
3401 if (*Args)
3402 *(Args - 1) = UNICODE_NULL;
3403
3405
3406 // Execute
3407 SHELLEXECUTEINFOW execInfo = { sizeof(execInfo) };
3408 execInfo.fMask = fNewMask;
3409 execInfo.hwnd = hwnd;
3410 execInfo.lpFile = szPath;
3411 execInfo.lpParameters = Args;
3412 execInfo.nShow = nCmdShow;
3413 if (!ShellExecuteExW(&execInfo))
3414 {
3415 DWORD dwError = GetLastError();
3416 if (SHELL_InRunDllProcess()) // Is it a RUNDLL process?
3417 ExitProcess(dwError); // Terminate it now
3418 }
3419}
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:1382
BOOL WINAPI StrToIntExW(const WCHAR *str, DWORD flags, INT *ret)
Definition: string.c:1012
WCHAR *WINAPI StrCpyNW(WCHAR *dst, const WCHAR *src, int count)
Definition: string.c:470
#define STIF_SUPPORT_HEX
Definition: shlwapi.h:1069
#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:3254
static BOOL SHELL_InRunDllProcess(VOID)
Definition: shlexec.cpp:73
#define PPCF_INCLUDEARGS
Definition: shlobj.h:2464

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

3433{
3434 CStringW strCmdLine = pszCmdLine; // Keep
3435 ShellExec_RunDLL_Helper(hwnd, hInstance, strCmdLine, nCmdShow);
3436}
static VOID ShellExec_RunDLL_Helper(_In_opt_ HWND hwnd, _In_opt_ HINSTANCE hInstance, _In_ PCWSTR pszCmdLine, _In_ INT nCmdShow)
Definition: shlexec.cpp:3370

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

3450{
3451 ShellExec_RunDLL_Helper(hwnd, hInstance, pszCmdLine, nCmdShow);
3452}

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

2937{
2940 LPCWSTR pszVerb = NULL;
2941 WCHAR szFile[MAX_PATH], szFile2[MAX_PATH];
2942 HRESULT hr;
2943 LPCWSTR pchParams;
2944 LPWSTR lpCommand = NULL;
2945
2946 if (pwszCommand == NULL)
2948 1, (ULONG_PTR*)pwszCommand);
2949
2950 __SHCloneStrW(&lpCommand, pwszCommand);
2951 StrTrimW(lpCommand, L" \t");
2952
2953 if (dwSeclFlags & SECL_NO_UI)
2955 if (dwSeclFlags & SECL_LOG_USAGE)
2957 if (dwSeclFlags & SECL_USE_IDLIST)
2959
2960 if (dwSeclFlags & SECL_RUNAS)
2961 {
2962 dwSize = 0;
2963 hr = AssocQueryStringW(ASSOCF_NONE, ASSOCSTR_COMMAND, lpCommand, L"runas", NULL, &dwSize);
2964 if (SUCCEEDED(hr) && dwSize != 0)
2965 {
2966 pszVerb = L"runas";
2967 }
2968 }
2969
2970 if (PathIsURLW(lpCommand) || UrlIsW(lpCommand, URLIS_APPLIABLE))
2971 {
2972 StringCchCopyW(szFile, _countof(szFile), lpCommand);
2973 pchParams = NULL;
2974 }
2975 else
2976 {
2977 PCWSTR apPathList[2];
2978
2979 pchParams = SplitParams(lpCommand, szFile, _countof(szFile));
2980 if (szFile[0] != UNICODE_NULL && szFile[1] == L':' &&
2981 szFile[2] == UNICODE_NULL)
2982 {
2983 PathAddBackslashW(szFile);
2984 }
2985
2986 WCHAR szCurDir[MAX_PATH];
2987 GetCurrentDirectoryW(_countof(szCurDir), szCurDir);
2988 if (pwszStartDir)
2989 {
2990 SetCurrentDirectoryW(pwszStartDir);
2991 }
2992
2993 if ((PathIsRelativeW(szFile) &&
2994 GetFullPathNameW(szFile, _countof(szFile2), szFile2, NULL) &&
2995 PathFileExistsW(szFile2)) ||
2996 SearchPathW(NULL, szFile, NULL, _countof(szFile2), szFile2, NULL))
2997 {
2998 StringCchCopyW(szFile, _countof(szFile), szFile2);
2999 }
3000
3001 apPathList[0] = pwszStartDir;
3002 apPathList[1] = NULL;
3003 PathFindOnPathExW(szFile, apPathList, WHICH_DEFAULT);
3004
3005 if (!(dwSeclFlags & SECL_ALLOW_NONEXE))
3006 {
3007 if (!GetBinaryTypeW(szFile, &dwType))
3008 {
3009 SHFree(lpCommand);
3010
3011 if (!(dwSeclFlags & SECL_NO_UI))
3012 {
3013 WCHAR szText[128 + MAX_PATH], szFormat[128];
3015 StringCchPrintfW(szText, _countof(szText), szFormat, szFile);
3016 MessageBoxW(hwnd, szText, NULL, MB_ICONERROR);
3017 }
3018 return CO_E_APPNOTFOUND;
3019 }
3020 }
3021 else
3022 {
3024 {
3025 SHFree(lpCommand);
3026
3027 if (!(dwSeclFlags & SECL_NO_UI))
3028 {
3029 WCHAR szText[128 + MAX_PATH], szFormat[128];
3031 StringCchPrintfW(szText, _countof(szText), szFormat, szFile);
3032 MessageBoxW(hwnd, szText, NULL, MB_ICONERROR);
3033 }
3035 }
3036 }
3037 }
3038
3039 ZeroMemory(&info, sizeof(info));
3040 info.cbSize = sizeof(info);
3041 info.fMask = dwFlags;
3042 info.hwnd = hwnd;
3043 info.lpVerb = pszVerb;
3044 info.lpFile = szFile;
3045 info.lpParameters = (pchParams && *pchParams) ? pchParams : NULL;
3046 info.lpDirectory = pwszStartDir;
3047 info.nShow = nShow;
3049 SHFree(lpCommand);
3050 return HRESULT_FROM_WIN32(error);
3051}
#define SECL_USE_IDLIST
#define SECL_LOG_USAGE
#define SECL_ALLOW_NONEXE
#define SECL_RUNAS
#define SECL_NO_UI
#define IDS_FILE_NOT_FOUND
Definition: resource.h:21
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:4788
BOOL WINAPI PathFileExistsW(const WCHAR *path)
Definition: path.c:2583
BOOL WINAPI StrTrimW(WCHAR *str, const WCHAR *trim)
Definition: string.c:804
BOOL WINAPI PathFindOnPathExW(LPWSTR lpszFile, LPCWSTR *lppszOtherDirs, DWORD dwWhich)
Definition: path.c:404
#define EXCEPTION_ACCESS_VIOLATION
Definition: minwinbase.h:44
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
@ URLIS_APPLIABLE
Definition: shlwapi.h:601
@ ASSOCSTR_COMMAND
Definition: shlwapi.h:886
#define SEE_MASK_FLAG_LOG_USAGE
Definition: shellapi.h:55
static LPCWSTR SplitParams(LPCWSTR psz, LPWSTR pszArg0, size_t cchArg0)
Definition: shlexec.cpp:2884
#define WHICH_DEFAULT
#define EXCEPTION_NONCONTINUABLE
Definition: stubs.h:23
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define CO_E_APPNOTFOUND
Definition: winerror.h:3921

◆ ShellExecute_ContextMenuVerb()

static HRESULT ShellExecute_ContextMenuVerb ( LPSHELLEXECUTEINFOW  sei)
static

Definition at line 1825 of file shlexec.cpp.

1826{
1827 TRACE("%p\n", sei);
1828
1829 CCoInit coInit;
1830
1831 if (FAILED_UNEXPECTEDLY(coInit.hr))
1832 return coInit.hr;
1833
1837 return hr;
1838
1842
1843 BOOL fDefault = StrIsNullOrEmpty(sei->lpVerb);
1844 CMINVOKECOMMANDINFOEX ici = { sizeof(ici) };
1845 ici.fMask = SeeFlagsToCmicFlags(sei->fMask) | CMIC_MASK_UNICODE;
1846 ici.nShow = sei->nShow;
1847 if (!fDefault)
1848 {
1849 __SHCloneStrWtoA(&verb, sei->lpVerb);
1850 ici.lpVerb = verb;
1851 ici.lpVerbW = sei->lpVerb;
1852 }
1853 ici.hwnd = sei->hwnd;
1854 ici.lpParameters = parameters;
1855 ici.lpParametersW = sei->lpParameters;
1856 ici.lpDirectory = dir;
1857 ici.lpDirectoryW = sei->lpDirectory;
1858 ici.dwHotKey = sei->dwHotKey;
1859 ici.hIcon = sei->hIcon;
1860 if (ici.fMask & (CMIC_MASK_HASLINKNAME | CMIC_MASK_HASTITLE))
1861 ici.lpTitleW = sei->lpClass;
1862
1863 enum { idFirst = 1, idLast = 0x7fff };
1864 HMENU hMenu = CreatePopupMenu();
1865 // Note: Windows does not pass CMF_EXTENDEDVERBS so "hidden" verbs cannot be executed
1866 hr = cm->QueryContextMenu(hMenu, 0, idFirst, idLast, fDefault ? CMF_DEFAULTONLY : 0);
1867 if (!FAILED_UNEXPECTEDLY(hr))
1868 {
1869 if (fDefault)
1870 {
1871 INT uDefault = GetMenuDefaultItem(hMenu, FALSE, 0);
1872 uDefault = (uDefault != -1) ? uDefault - idFirst : 0;
1873 ici.lpVerb = MAKEINTRESOURCEA(uDefault);
1874 ici.lpVerbW = MAKEINTRESOURCEW(uDefault);
1875 }
1876
1877 hr = cm->InvokeCommand((LPCMINVOKECOMMANDINFO)&ici);
1878 if (!FAILED_UNEXPECTEDLY(hr))
1879 hr = S_OK;
1880 }
1881
1882 DestroyMenu(hMenu);
1883
1884 return hr;
1885}
unsigned int dir
Definition: maze.c:112
static BYTE parameters[]
Definition: asn.c:558
static __inline void __SHCloneStrWtoA(char **target, const WCHAR *source)
Definition: shell32_main.h:214
static HRESULT shellex_get_contextmenu(LPSHELLEXECUTEINFOW sei, CComPtr< IContextMenu > &cm)
Definition: shlexec.cpp:1786

Referenced by SHELL_execute().

◆ ShellExecute_FromContextMenuHandlers()

static LONG ShellExecute_FromContextMenuHandlers ( LPSHELLEXECUTEINFOW  sei)
static

Definition at line 1891 of file shlexec.cpp.

1892{
1893 HKEY hkey, hkeycm = 0;
1894 WCHAR szguid[39];
1895 HRESULT hr;
1896 GUID guid;
1897 DWORD i;
1898 LONG r;
1899
1900 TRACE("%s\n", debugstr_w(sei->lpFile));
1901
1902 hkey = ShellExecute_GetClassKey(sei);
1903 if (!hkey)
1904 return ERROR_FUNCTION_FAILED;
1905
1906 // FIXME: Words cannot describe how broken this is, all of it needs to die
1907 r = RegOpenKeyW(hkey, L"shellex\\ContextMenuHandlers", &hkeycm);
1908 if (r == ERROR_SUCCESS)
1909 {
1910 i = 0;
1911 while (1)
1912 {
1913 r = RegEnumKeyW(hkeycm, i++, szguid, ARRAY_SIZE(szguid));
1914 if (r != ERROR_SUCCESS)
1915 break;
1916
1917 hr = CLSIDFromString(szguid, &guid);
1918 if (SUCCEEDED(hr))
1919 {
1920 /* stop at the first one that succeeds in running */
1921 hr = shellex_load_object_and_run(hkey, &guid, sei);
1922 if (SUCCEEDED(hr))
1923 break;
1924 }
1925 }
1926 RegCloseKey(hkeycm);
1927 }
1928
1929 if (hkey != sei->hkeyClass)
1930 RegCloseKey(hkey);
1931 return r;
1932}
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 str, LPCLSID clsid)
Definition: combase.c:1470
static HRESULT shellex_load_object_and_run(HKEY hkey, LPCGUID guid, LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:1752
static HKEY ShellExecute_GetClassKey(const SHELLEXECUTEINFOW *sei)
Definition: shlexec.cpp:1639
#define ERROR_FUNCTION_FAILED
Definition: winerror.h:1333

Referenced by SHELL_execute().

◆ ShellExecute_GetClassKey()

static HKEY ShellExecute_GetClassKey ( const SHELLEXECUTEINFOW *  sei)
static

Definition at line 1639 of file shlexec.cpp.

1640{
1642 return sei->hkeyClass;
1643
1644 HKEY hKey = NULL;
1645 if (sei->fMask & SEE_MASK_CLASSNAME)
1646 {
1647 TRACE("class = %s\n", debugstr_w(sei->lpClass));
1649 return hKey;
1650 }
1652 TRACE("ext = %s\n", debugstr_w(ext));
1653 if (!StrIsNullOrEmpty(ext) && SUCCEEDED(HCR_GetProgIdKeyOfExtension(ext, &hKey, FALSE)))
1654 return hKey;
1655 return NULL;
1656}
static const WCHAR *const ext[]
Definition: module.c:53
LPWSTR WINAPI PathFindExtensionW(const WCHAR *path)
Definition: path.c:1250
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 2652 of file shlexec.cpp.

2653{
2654 // FIXME
2655 if (SHELL_execute(sei, SHELL_ExecuteW))
2656 return ERROR_SUCCESS;
2658#if DBG
2659 if (!err)
2660 DbgPrint("FIXME: Failed with error 0 on '%ls'\n", sei->lpFile);
2661#endif
2662 return err ? err : ERROR_FILE_NOT_FOUND;
2663}
#define DbgPrint
Definition: hal.h:12
static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
Definition: shlexec.cpp:2228
static UINT_PTR SHELL_ExecuteW(const WCHAR *lpCmd, WCHAR *env, BOOL shWait, const SHELLEXECUTEINFOW *psei, LPSHELLEXECUTEINFOW psei_out)
Definition: shlexec.cpp:725

Referenced by ShellExecuteExW().

◆ ShellExecute_ShowError()

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

Definition at line 2666 of file shlexec.cpp.

2670{
2671 // FIXME: Show error message
2672}

Referenced by ShellExecuteExW().

◆ ShellExecuteA()

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

Definition at line 2622 of file shlexec.cpp.

2624{
2626
2627 TRACE("%p,%s,%s,%s,%s,%d\n",
2628 hWnd, debugstr_a(lpVerb), debugstr_a(lpFile),
2629 debugstr_a(lpParameters), debugstr_a(lpDirectory), iShowCmd);
2630
2631 sei.cbSize = sizeof(sei);
2633 sei.hwnd = hWnd;
2634 sei.lpVerb = lpVerb;
2635 sei.lpFile = lpFile;
2636 sei.lpParameters = lpParameters;
2638 sei.nShow = iShowCmd;
2639 sei.lpIDList = 0;
2640 sei.lpClass = 0;
2641 sei.hkeyClass = 0;
2642 sei.dwHotKey = 0;
2643 sei.hProcess = 0;
2644
2646 sei.fMask |= SEE_MASK_NOASYNC;
2647 ShellExecuteExA(&sei);
2648 return sei.hInstApp;
2649}
DWORD WINAPI SHGetAppCompatFlags(_In_ DWORD dwMask)
Definition: appcompat.c:433
#define SHACF_WIN95SHLEXEC

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

◆ ShellExecuteExA()

Definition at line 2680 of file shlexec.cpp.

2681{
2682 SHELLEXECUTEINFOW seiW;
2683 BOOL ret;
2684 WCHAR *wVerb = NULL, *wFile = NULL, *wParameters = NULL, *wDirectory = NULL, *wClass = NULL;
2685
2686 TRACE("%p\n", sei);
2687
2688 if (sei->cbSize != sizeof(SHELLEXECUTEINFOA))
2689 {
2692 return FALSE;
2693 }
2694
2695 memcpy(&seiW, sei, sizeof(SHELLEXECUTEINFOW));
2696
2697 seiW.cbSize = sizeof(SHELLEXECUTEINFOW);
2698
2699 if (sei->lpVerb)
2700 seiW.lpVerb = __SHCloneStrAtoW(&wVerb, sei->lpVerb);
2701
2702 if (sei->lpFile)
2703 seiW.lpFile = __SHCloneStrAtoW(&wFile, sei->lpFile);
2704
2705 if (sei->lpParameters)
2706 seiW.lpParameters = __SHCloneStrAtoW(&wParameters, sei->lpParameters);
2707
2708 if (sei->lpDirectory)
2709 seiW.lpDirectory = __SHCloneStrAtoW(&wDirectory, sei->lpDirectory);
2710
2711 if ((sei->fMask & SEE_MASK_CLASSALL) == SEE_MASK_CLASSNAME && sei->lpClass)
2712 seiW.lpClass = __SHCloneStrAtoW(&wClass, sei->lpClass);
2713 else
2714 seiW.lpClass = NULL;
2715
2716 ret = ShellExecuteExW(&seiW);
2717
2718 sei->hInstApp = seiW.hInstApp;
2719
2720 if (sei->fMask & SEE_MASK_NOCLOSEPROCESS)
2721 sei->hProcess = seiW.hProcess;
2722
2723 SHFree(wVerb);
2724 SHFree(wFile);
2725 SHFree(wParameters);
2726 SHFree(wDirectory);
2727 SHFree(wClass);
2728
2729 return ret;
2730}
struct _SHELLEXECUTEINFOW SHELLEXECUTEINFOW

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

◆ ShellExecuteExW()

Definition at line 2738 of file shlexec.cpp.

2739{
2740 HRESULT hrCoInit;
2741 DWORD dwError;
2742 ULONG fOldMask;
2743
2744 if (sei->cbSize != sizeof(SHELLEXECUTEINFOW))
2745 {
2748 return FALSE;
2749 }
2750
2751 hrCoInit = SHCoInitializeAnyApartment();
2752
2753 if (SHRegGetBoolUSValueW(L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer",
2754 L"MaximizeApps", FALSE, FALSE))
2755 {
2756 switch (sei->nShow)
2757 {
2758 case SW_SHOW:
2759 case SW_SHOWDEFAULT:
2760 case SW_SHOWNORMAL:
2761 case SW_RESTORE:
2762 sei->nShow = SW_SHOWMAXIMIZED;
2763 break;
2764 default:
2765 break;
2766 }
2767 }
2768
2769 fOldMask = sei->fMask;
2770
2771 if (!(fOldMask & SEE_MASK_NOASYNC) && SHELL_InRunDllProcess())
2773
2774 dwError = ShellExecute_Normal(sei);
2775
2776 if (dwError && dwError != ERROR_DLL_NOT_FOUND && dwError != ERROR_CANCELLED)
2777 ShellExecute_ShowError(sei, NULL, dwError);
2778
2779 sei->fMask = fOldMask;
2780
2781 if (SUCCEEDED(hrCoInit))
2783
2784 if (dwError)
2785 SetLastError(dwError);
2786
2787 return dwError == ERROR_SUCCESS;
2788}
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: combase.c:2842
BOOL WINAPI SHRegGetBoolUSValueW(const WCHAR *subkey, const WCHAR *value, BOOL ignore_hkcu, BOOL default_value)
Definition: registry.c:4139
HRESULT SHCoInitializeAnyApartment(VOID)
Definition: utils.cpp:542
#define SW_SHOWNORMAL
Definition: winuser.h:781
#define SW_SHOWMAXIMIZED
Definition: winuser.h:784
#define SW_SHOWDEFAULT
Definition: winuser.h:791
#define SW_RESTORE
Definition: winuser.h:790
#define 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:2652
static VOID ShellExecute_ShowError(_In_ const SHELLEXECUTEINFOW *ExecInfo, _In_opt_ LPCWSTR pszCaption, _In_ DWORD dwError)
Definition: shlexec.cpp:2666
#define ERROR_DLL_NOT_FOUND
Definition: winerror.h:1003

Referenced by AutoStartupApplications(), BtrfsVolPropSheet::DeviceDlgProc(), CShellLink::DoOpen(), RunOnceExEntry::Exec(), COpenWithList::Execute(), CAddressEditBox::ExecuteCommandLine(), ExtractAndInstallThread(), HandleRosMscLaunch(), HlinkSimpleNavigateToString(), CFontBackgroundMenu::InvokeCommand(), 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(), CTrayWindow::ShowFolder(), CRecycleBinCleaner::ShowProperties(), BtrfsVolPropSheet::ShowScrub(), BtrfsBalance::StartBalance(), BtrfsBalance::StopBalance(), test_DoInvalidDir(), TEST_DoTestEntryStruct(), Test_InvokeIdList(), test_properties(), test_sei_lpIDList(), try_application_url(), UniformResourceLocatorW_InvokeCommand(), UsersRunDllW(), wmain(), and WshShell3_Run().

◆ ShellExecuteW()

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

Definition at line 2793 of file shlexec.cpp.

2795{
2797
2798 TRACE("\n");
2799 sei.cbSize = sizeof(sei);
2801 sei.hwnd = hwnd;
2802 sei.lpVerb = lpVerb;
2803 sei.lpFile = lpFile;
2804 sei.lpParameters = lpParameters;
2806 sei.nShow = nShowCmd;
2807 sei.lpIDList = 0;
2808 sei.lpClass = 0;
2809 sei.hkeyClass = 0;
2810 sei.dwHotKey = 0;
2811 sei.hProcess = 0;
2812
2814 sei.fMask |= SEE_MASK_NOASYNC;
2815 ShellExecuteExW(&sei);
2816 return sei.hInstApp;
2817}

Referenced by _RunVolume(), Control_StartApplet(), CShellDispatch::ControlPanelItem(), 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(), CTaskSwitchWnd::OnActivateTaskIndex(), 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(), START_TEST(), StartRecDlgProc(), and TEST_Init().

◆ SplitParams()

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

Definition at line 2884 of file shlexec.cpp.

2885{
2886 LPCWSTR pch;
2887 size_t ich = 0;
2888 if (*psz == L'"')
2889 {
2890 // 1st argument is quoted. the string in quotes is quoted 1st argument.
2891 // [pch] --> [pszArg0+ich]
2892 for (pch = psz + 1; *pch && ich + 1 < cchArg0; ++ich, ++pch)
2893 {
2894 if (*pch == L'"' && pch[1] == L'"')
2895 {
2896 // doubled double quotations found!
2897 pszArg0[ich] = L'"';
2898 }
2899 else if (*pch == L'"')
2900 {
2901 // single double quotation found!
2902 ++pch;
2903 break;
2904 }
2905 else
2906 {
2907 // otherwise
2908 pszArg0[ich] = *pch;
2909 }
2910 }
2911 }
2912 else
2913 {
2914 // 1st argument is unquoted. non-space sequence is 1st argument.
2915 // [pch] --> [pszArg0+ich]
2916 for (pch = psz; *pch && !iswspace(*pch) && ich + 1 < cchArg0; ++ich, ++pch)
2917 {
2918 pszArg0[ich] = *pch;
2919 }
2920 }
2921 pszArg0[ich] = 0;
2922
2923 // skip space
2924 while (iswspace(*pch))
2925 ++pch;
2926
2927 return pch;
2928}
#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
LONG_PTR LRESULT
Definition: minwindef.h:176
#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:736

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:997
#define ERROR_SHARING_VIOLATION
Definition: winerror.h:257
#define ERROR_RMODE_APP
Definition: winerror.h:999
#define ERROR_INVALID_DLL
Definition: winerror.h:1000
#define ERROR_SINGLE_INSTANCE_APP
Definition: winerror.h:998
#define ERROR_OLD_WIN_VERSION
Definition: winerror.h:996

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

2826{
2827 SHELLEXECUTEINFOW seiW;
2828 WCHAR *wVerb = NULL, *wFile = NULL, *wParameters = NULL, *wDirectory = NULL;
2829 HANDLE hProcess = 0;
2830
2831 seiW.lpVerb = lpVerb ? __SHCloneStrAtoW(&wVerb, lpVerb) : NULL;
2832 seiW.lpFile = lpFile ? __SHCloneStrAtoW(&wFile, lpFile) : NULL;
2833 seiW.lpParameters = lpParameters ? __SHCloneStrAtoW(&wParameters, lpParameters) : NULL;
2834 seiW.lpDirectory = lpDirectory ? __SHCloneStrAtoW(&wDirectory, lpDirectory) : NULL;
2835
2836 seiW.cbSize = sizeof(seiW);
2837 seiW.fMask = 0;
2838 seiW.hwnd = hWnd;
2839 seiW.nShow = iShowCmd;
2840 seiW.lpIDList = 0;
2841 seiW.lpClass = 0;
2842 seiW.hkeyClass = 0;
2843 seiW.dwHotKey = 0;
2844 seiW.hProcess = hProcess;
2845
2847
2848 SHFree(wVerb);
2849 SHFree(wFile);
2850 SHFree(wParameters);
2851 SHFree(wDirectory);
2852 return seiW.hInstApp;
2853}
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:71
static IPrintDialogCallback callback
Definition: printdlg.c:325
UINT_PTR(* SHELL_ExecuteW32)(const WCHAR *lpCmd, WCHAR *env, BOOL shWait, const SHELLEXECUTEINFOW *sei, LPSHELLEXECUTEINFOW sei_out)
Definition: shlexec.cpp:33