ReactOS 0.4.16-dev-1946-g52006dd
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 WCHARexpand_environment (const WCHAR *str)
 
static BOOL SHELL_execute (LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
 
HINSTANCE WINAPI ShellExecuteA (HWND hWnd, LPCSTR lpVerb, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, INT iShowCmd)
 
static DWORD ShellExecute_Normal (_Inout_ LPSHELLEXECUTEINFOW sei)
 
static VOID ShellExecute_ShowError (_In_ const SHELLEXECUTEINFOW *ExecInfo, _In_opt_ LPCWSTR pszCaption, _In_ DWORD dwError)
 
BOOL WINAPI DECLSPEC_HOTPATCH ShellExecuteExA (LPSHELLEXECUTEINFOA sei)
 
BOOL WINAPI DECLSPEC_HOTPATCH ShellExecuteExW (LPSHELLEXECUTEINFOW sei)
 
HINSTANCE WINAPI ShellExecuteW (HWND hwnd, LPCWSTR lpVerb, LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd)
 
EXTERN_C HINSTANCE WINAPI WOWShellExecute (HWND hWnd, LPCSTR lpVerb, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, INT iShowCmd, void *callback)
 
EXTERN_C void WINAPI OpenAs_RunDLLW (HWND hwnd, HINSTANCE hinst, LPCWSTR cmdline, int cmdshow)
 
EXTERN_C void WINAPI OpenAs_RunDLLA (HWND hwnd, HINSTANCE hinst, LPCSTR cmdline, int cmdshow)
 
static LPCWSTR SplitParams (LPCWSTR psz, LPWSTR pszArg0, size_t cchArg0)
 
HRESULT WINAPI ShellExecCmdLine (HWND hwnd, LPCWSTR pwszCommand, LPCWSTR pwszStartDir, int nShow, LPVOID pUnused, DWORD dwSeclFlags)
 
EXTERN_C HINSTANCE WINAPI RealShellExecuteExA (_In_opt_ HWND hwnd, _In_opt_ LPCSTR lpOperation, _In_opt_ LPCSTR lpFile, _In_opt_ LPCSTR lpParameters, _In_opt_ LPCSTR lpDirectory, _In_opt_ LPSTR lpReturn, _In_opt_ LPCSTR lpTitle, _In_opt_ LPVOID lpReserved, _In_ INT nCmdShow, _Out_opt_ PHANDLE lphProcess, _In_ DWORD dwFlags)
 
EXTERN_C HINSTANCE WINAPI RealShellExecuteExW (_In_opt_ HWND hwnd, _In_opt_ LPCWSTR lpOperation, _In_opt_ LPCWSTR lpFile, _In_opt_ LPCWSTR lpParameters, _In_opt_ LPCWSTR lpDirectory, _In_opt_ LPWSTR lpReturn, _In_opt_ LPCWSTR lpTitle, _In_opt_ LPVOID lpReserved, _In_ INT nCmdShow, _Out_opt_ PHANDLE lphProcess, _In_ DWORD dwFlags)
 
EXTERN_C HINSTANCE WINAPI RealShellExecuteA (_In_opt_ HWND hwnd, _In_opt_ LPCSTR lpOperation, _In_opt_ LPCSTR lpFile, _In_opt_ LPCSTR lpParameters, _In_opt_ LPCSTR lpDirectory, _In_opt_ LPSTR lpReturn, _In_opt_ LPCSTR lpTitle, _In_opt_ LPVOID lpReserved, _In_ INT nCmdShow, _Out_opt_ PHANDLE lphProcess)
 
EXTERN_C HINSTANCE WINAPI RealShellExecuteW (_In_opt_ HWND hwnd, _In_opt_ LPCWSTR lpOperation, _In_opt_ LPCWSTR lpFile, _In_opt_ LPCWSTR lpParameters, _In_opt_ LPCWSTR lpDirectory, _In_opt_ LPWSTR lpReturn, _In_opt_ LPCWSTR lpTitle, _In_opt_ LPVOID lpReserved, _In_ INT nCmdShow, _Out_opt_ PHANDLE lphProcess)
 
EXTERN_C LONG PathProcessCommandW (_In_ PCWSTR pszSrc, _Out_writes_opt_(dwBuffSize) PWSTR pszDest, _In_ INT cchDest, _In_ DWORD dwFlags)
 
static VOID ShellExec_RunDLL_Helper (_In_opt_ HWND hwnd, _In_opt_ HINSTANCE hInstance, _In_ PCWSTR pszCmdLine, _In_ INT nCmdShow)
 
EXTERN_C VOID WINAPI ShellExec_RunDLLA (_In_opt_ HWND hwnd, _In_opt_ HINSTANCE hInstance, _In_ PCSTR pszCmdLine, _In_ INT nCmdShow)
 
EXTERN_C VOID WINAPI ShellExec_RunDLLW (_In_opt_ HWND hwnd, _In_opt_ HINSTANCE hInstance, _In_ PCWSTR pszCmdLine, _In_ INT nCmdShow)
 

Macro Definition Documentation

◆ SEE_MASK_CLASSALL

#define SEE_MASK_CLASSALL   (SEE_MASK_CLASSNAME | SEE_MASK_CLASSKEY)

Definition at line 31 of file shlexec.cpp.

Typedef Documentation

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

1255{
1256 TRACE("dde_cb: %04x, %04x, %p, %p, %p, %p, %08lx, %08lx\n",
1257 uType, uFmt, hConv, hsz1, hsz2, hData, dwData1, dwData2);
1258 return NULL;
1259}
#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 1270 of file shlexec.cpp.

1274{
1275 WCHAR regkey[256];
1276 WCHAR * endkey = regkey + wcslen(key);
1277 WCHAR app[256], topic[256], ifexec[256], static_res[256];
1279 WCHAR * res;
1280 LONG applen, topiclen, ifexeclen;
1281 WCHAR * exec;
1282 DWORD ddeInst = 0;
1283 DWORD tid;
1284 DWORD resultLen, endkeyLen;
1285 HSZ hszApp, hszTopic;
1286 HCONV hConv;
1287 HDDEDATA hDdeData;
1288 unsigned ret = SE_ERR_NOASSOC;
1289 BOOL unicode = !(GetVersion() & 0x80000000);
1290
1291 if (strlenW(key) + 1 > ARRAY_SIZE(regkey))
1292 {
1293 FIXME("input parameter %s larger than buffer\n", debugstr_w(key));
1294 return 2;
1295 }
1296 wcscpy(regkey, key);
1297 endkeyLen = ARRAY_SIZE(regkey) - (endkey - regkey);
1298 if (strlenW(L"\\application") + 1 > endkeyLen)
1299 {
1300 FIXME("endkey %s overruns buffer\n", debugstr_w(L"\\application"));
1301 return 2;
1302 }
1303 wcscpy(endkey, L"\\application");
1304 applen = sizeof(app);
1305 if (RegQueryValueW(HKEY_CLASSES_ROOT, regkey, app, &applen) != ERROR_SUCCESS)
1306 {
1307 WCHAR command[1024], fullpath[MAX_PATH];
1308 LPWSTR ptr = NULL;
1309 DWORD ret = 0;
1310
1311 /* Get application command from start string and find filename of application */
1312 if (*start == '"')
1313 {
1314 if (strlenW(start + 1) + 1 > ARRAY_SIZE(command))
1315 {
1316 FIXME("size of input parameter %s larger than buffer\n",
1317 debugstr_w(start + 1));
1318 return 2;
1319 }
1320 wcscpy(command, start + 1);
1321 if ((ptr = wcschr(command, '"')))
1322 * ptr = 0;
1323 ret = SearchPathW(NULL, command, L".exe", ARRAY_SIZE(fullpath), fullpath, &ptr);
1324 }
1325 else
1326 {
1327 LPCWSTR p;
1328 LPWSTR space;
1329 for (p = start; (space = const_cast<LPWSTR>(strchrW(p, ' '))); p = space + 1)
1330 {
1331 int idx = space - start;
1332 memcpy(command, start, idx * sizeof(WCHAR));
1333 command[idx] = '\0';
1334 if ((ret = SearchPathW(NULL, command, L".exe", ARRAY_SIZE(fullpath), fullpath, &ptr)))
1335 break;
1336 }
1337 if (!ret)
1338 ret = SearchPathW(NULL, start, L".exe", ARRAY_SIZE(fullpath), fullpath, &ptr);
1339 }
1340
1341 if (!ret)
1342 {
1343 ERR("Unable to find application path for command %s\n", debugstr_w(start));
1344 return ERROR_ACCESS_DENIED;
1345 }
1346 if (strlenW(ptr) + 1 > ARRAY_SIZE(app))
1347 {
1348 FIXME("size of found path %s larger than buffer\n", debugstr_w(ptr));
1349 return 2;
1350 }
1351 wcscpy(app, ptr);
1352
1353 /* Remove extensions (including .so) */
1354 ptr = app + wcslen(app) - 3;
1355 if (ptr > app && !wcscmp(ptr, L".so"))
1356 *ptr = 0;
1357
1358 ptr = const_cast<LPWSTR>(strrchrW(app, '.'));
1359 assert(ptr);
1360 *ptr = 0;
1361 }
1362
1363 if (strlenW(L"\\topic") + 1 > endkeyLen)
1364 {
1365 FIXME("endkey %s overruns buffer\n", debugstr_w(L"\\topic"));
1366 return 2;
1367 }
1368 wcscpy(endkey, L"\\topic");
1369 topiclen = sizeof(topic);
1370 if (RegQueryValueW(HKEY_CLASSES_ROOT, regkey, topic, &topiclen) != ERROR_SUCCESS)
1371 {
1372 wcscpy(topic, L"System");
1373 }
1374
1375 if (unicode)
1376 {
1378 return 2;
1379 }
1380 else
1381 {
1383 return 2;
1384 }
1385
1388
1389 hConv = DdeConnect(ddeInst, hszApp, hszTopic, NULL);
1390 exec = ddeexec;
1391 if (!hConv)
1392 {
1393 TRACE("Launching %s\n", debugstr_w(start));
1394 ret = execfunc(start, env, TRUE, psei, psei_out);
1395 if (ret <= 32)
1396 {
1397 TRACE("Couldn't launch\n");
1398 goto error;
1399 }
1400 /* if ddeexec is NULL, then we just need to exit here */
1401 if (ddeexec == NULL)
1402 {
1403 TRACE("Exiting because ddeexec is NULL. ret=42.\n");
1404 /* See https://docs.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shellexecutew */
1405 /* for reason why we use 42 here and also "Shell32_apitest ShellExecuteW" regression test */
1406 return 42;
1407 }
1408 /* if ddeexec is 'empty string', then we just need to exit here */
1409 if (wcscmp(ddeexec, L"") == 0)
1410 {
1411 TRACE("Exiting because ddeexec is 'empty string'. ret=42.\n");
1412 /* See https://docs.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shellexecutew */
1413 /* for reason why we use 42 here and also "Shell32_apitest ShellExecuteW" regression test */
1414 return 42;
1415 }
1416 hConv = DdeConnect(ddeInst, hszApp, hszTopic, NULL);
1417 if (!hConv)
1418 {
1419 TRACE("Couldn't connect. ret=%d\n", ret);
1422 return 30; /* whatever */
1423 }
1424 if (strlenW(L"\\ifexec") + 1 > endkeyLen)
1425 {
1426 FIXME("endkey %s overruns buffer\n", debugstr_w(L"\\ifexec"));
1427 return 2;
1428 }
1429 strcpyW(endkey, L"\\ifexec");
1430 ifexeclen = sizeof(ifexec);
1431 if (RegQueryValueW(HKEY_CLASSES_ROOT, regkey, ifexec, &ifexeclen) == ERROR_SUCCESS)
1432 {
1433 exec = ifexec;
1434 }
1435 }
1436
1437 SHELL_ArgifyW(static_res, ARRAY_SIZE(static_res), exec, lpFile, pidl, szCommandline, &resultLen, NULL);
1438 if (resultLen > ARRAY_SIZE(static_res))
1439 {
1440 dynamic_res.Allocate(resultLen);
1441 res = dynamic_res;
1442 SHELL_ArgifyW(dynamic_res, resultLen, exec, lpFile, pidl, szCommandline, NULL, NULL);
1443 }
1444 else
1445 res = static_res;
1446 TRACE("%s %s => %s\n", debugstr_w(exec), debugstr_w(lpFile), debugstr_w(res));
1447
1448 /* It's documented in the KB 330337 that IE has a bug and returns
1449 * error DMLERR_NOTPROCESSED on XTYP_EXECUTE request.
1450 */
1451 if (unicode)
1452 hDdeData = DdeClientTransaction((LPBYTE)res, (strlenW(res) + 1) * sizeof(WCHAR), hConv, 0L, 0, XTYP_EXECUTE, 30000, &tid);
1453 else
1454 {
1455 DWORD lenA = WideCharToMultiByte(CP_ACP, 0, res, -1, NULL, 0, NULL, NULL);
1457 resA.Allocate(lenA);
1458 WideCharToMultiByte(CP_ACP, 0, res, -1, resA, lenA, NULL, NULL);
1459 hDdeData = DdeClientTransaction( (LPBYTE)(LPSTR)resA, lenA, hConv, 0L, 0,
1460 XTYP_EXECUTE, 10000, &tid );
1461 }
1462 if (hDdeData)
1463 DdeFreeDataHandle(hDdeData);
1464 else
1465 WARN("DdeClientTransaction failed with error %04x\n", DdeGetLastError(ddeInst));
1466 ret = 33;
1467
1468 DdeDisconnect(hConv);
1469
1470error:
1472
1473 return ret;
1474}
#define ARRAY_SIZE(A)
Definition: main.h:20
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
bool Allocate(_In_ size_t nElements=1)
Definition: atlalloc.h:143
wcscpy
static LPCWSTR LPCWSTR LPCWSTR env
Definition: db.cpp: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:41
LSTATUS WINAPI RegQueryValueW(HKEY hkey, LPCWSTR name, LPWSTR data, LPLONG count)
Definition: reg.c:4241
#define wcschr
Definition: compat.h:17
#define CP_ACP
Definition: compat.h:109
#define SetLastError(x)
Definition: compat.h:752
#define MAX_PATH
Definition: compat.h:34
#define WideCharToMultiByte
Definition: compat.h:111
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
DWORD WINAPI SearchPathW(IN LPCWSTR lpPath OPTIONAL, IN LPCWSTR lpFileName, IN LPCWSTR lpExtension OPTIONAL, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart OPTIONAL)
Definition: path.c:1298
DWORD WINAPI GetVersion(void)
Definition: version.c:1458
#define assert(x)
Definition: debug.h:53
return ret
Definition: mutex.c:146
#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
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
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
long LONG
Definition: pedump.c:60
static const char topic[]
Definition: propsys.c:45
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define SE_ERR_NOASSOC
Definition: shellapi.h:135
static DWORD ddeInst
Definition: shlexec.c:147
static HSZ hszTopic
Definition: shlexec.c:148
static HDDEDATA CALLBACK dde_cb(UINT uType, UINT uFmt, HCONV hConv, HSZ hsz1, HSZ hsz2, HDDEDATA hData, ULONG_PTR dwData1, ULONG_PTR dwData2)
Definition: shlexec.cpp:1252
static BOOL SHELL_ArgifyW(WCHAR *out, DWORD len, const WCHAR *fmt, const WCHAR *lpFile, LPITEMIDLIST pidl, LPCWSTR args, DWORD *out_len, const WCHAR *lpDir)
Definition: shlexec.cpp:299
Definition: copy.c:22
unsigned char * LPBYTE
Definition: typedefs.h:53
#define strchrW(s, c)
Definition: unicode.h:40
#define strlenW(s)
Definition: unicode.h:34
#define strrchrW(s, c)
Definition: unicode.h:41
#define strcpyW(d, s)
Definition: unicode.h:35
#define ERROR_DDE_FAIL
Definition: winerror.h:1002
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
char * LPSTR
Definition: xmlstorage.h:182

Referenced by execute_from_key().

◆ do_error_dialog()

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

Definition at line 2167 of file shlexec.cpp.

2168{
2169 WCHAR msg[2048];
2170 DWORD_PTR msgArguments[3] = { (DWORD_PTR)filename, 0, 0 };
2171 const DWORD error_code = GetLastError();
2172
2173 if (retval == SE_ERR_NOASSOC)
2175 else
2177 NULL,
2178 error_code,
2180 msg,
2181 ARRAY_SIZE(msg),
2182 (va_list*)msgArguments);
2183
2185 SetLastError(error_code); // Restore
2186}
#define shell32_hInstance
char * va_list
Definition: acmsvcex.h:78
#define msg(x)
Definition: auth_time.c:54
DWORD WINAPI FormatMessageW(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPWSTR lpBuffer, DWORD nSize, __ms_va_list *args)
Definition: format_msg.c:583
INT WINAPI DECLSPEC_HOTPATCH LoadStringW(HINSTANCE instance, UINT resource_id, LPWSTR buffer, INT buflen)
Definition: string.c:1220
const char * filename
Definition: ioapi.h:137
#define IDS_SHLEXEC_NOASSOC
Definition: shresdef.h:187
#define LANG_USER_DEFAULT
Definition: tnerror.cpp:50
#define DWORD_PTR
Definition: treelist.c:76
uint32_t DWORD_PTR
Definition: typedefs.h:65
int retval
Definition: wcstombs.cpp:91
static int error_code[8]
Definition: odbccp32.c:61
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define FORMAT_MESSAGE_FROM_SYSTEM
Definition: winbase.h:400
#define FORMAT_MESSAGE_ARGUMENT_ARRAY
Definition: winbase.h:401
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
int WINAPI MessageBoxW(_In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType)
#define MB_ICONERROR
Definition: winuser.h:798

Referenced by SHELL_execute().

◆ execute_from_key()

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

Definition at line 1479 of file shlexec.cpp.

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

Referenced by SHELL_execute_url(), and SHELL_quote_and_execute().

◆ expand_environment()

static WCHAR * expand_environment ( const WCHAR str)
static

Definition at line 2188 of file shlexec.cpp.

2189{
2191 DWORD len;
2192
2194 if (!len) return NULL;
2195
2196 if (!buf.Allocate(len))
2197 return NULL;
2198
2200 if (!len)
2201 return NULL;
2202
2203 return buf.Detach();
2204}
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:519
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLsizei len
Definition: glext.h:6722
const WCHAR * str

Referenced by SHELL_execute().

◆ FindExecutableA()

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

Definition at line 1538 of file shlexec.cpp.

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

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

◆ FindExecutableW()

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

Definition at line 1581 of file shlexec.cpp.

1582{
1584 WCHAR old_dir[MAX_PATH], res[MAX_PATH];
1585 DWORD cch = _countof(res);
1586 LPCWSTR dirs[2];
1587
1588 TRACE("File %s, Dir %s\n", debugstr_w(lpFile), debugstr_w(lpDirectory));
1589
1590 *lpResult = UNICODE_NULL;
1591
1592 GetCurrentDirectoryW(_countof(old_dir), old_dir);
1593
1594 if (lpDirectory && *lpDirectory)
1595 {
1597 dirs[0] = lpDirectory;
1598 }
1599 else
1600 {
1601 dirs[0] = old_dir;
1602 }
1603 dirs[1] = NULL;
1604
1605 if (!GetShortPathNameW(lpFile, res, _countof(res)))
1606 StringCchCopyW(res, _countof(res), lpFile);
1607
1609 {
1610 // NOTE: The last parameter of this AssocQueryStringW call is "strange" in Windows.
1611 if (PathIsExeW(res) ||
1613 {
1614 StringCchCopyW(lpResult, MAX_PATH, res);
1615 retval = 42;
1616 }
1617 else
1618 {
1620 }
1621 }
1622 else
1623 {
1625 }
1626
1627 TRACE("returning %s\n", debugstr_w(lpResult));
1628 SetCurrentDirectoryW(old_dir);
1629 return (HINSTANCE)retval;
1630}
#define PRF_TRYPROGRAMEXTENSIONS
Definition: PathResolve.cpp:40
#define PRF_FIRSTDIRDEF
Definition: PathResolve.cpp:41
#define GetCurrentDirectoryW(x, y)
Definition: compat.h:756
BOOL WINAPI SetCurrentDirectoryW(IN LPCWSTR lpPathName)
Definition: path.c:2249
DWORD WINAPI GetShortPathNameW(IN LPCWSTR lpszLongPath, OUT LPWSTR lpszShortPath, IN DWORD cchBuffer)
Definition: path.c:1833
BOOL WINAPI PathResolveW(_Inout_ LPWSTR path, _Inout_opt_ LPCWSTR *dirs, _In_ DWORD flags)
Definition: shellpath.c:1032
HRESULT WINAPI AssocQueryStringW(ASSOCF cfFlags, ASSOCSTR str, LPCWSTR pszAssoc, LPCWSTR pszExtra, LPWSTR pszOut, DWORD *pcchOut)
Definition: assoc.c:441
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define UNICODE_NULL
@ ASSOCF_NONE
Definition: shlwapi.h:858
@ ASSOCSTR_EXECUTABLE
Definition: shlwapi.h:887
_In_ UINT _In_ UINT cch
Definition: shellapi.h:432
#define SE_ERR_FNF
Definition: shellapi.h:125
EXTERN_C BOOL PathIsExeW(LPCWSTR lpszPath)
Definition: shellpath.c:539
#define _countof(array)
Definition: sndvol32.h:70
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149

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

◆ InvokeOpenWith()

static UINT_PTR InvokeOpenWith ( HWND  hWndOwner,
SHELLEXECUTEINFOW sei 
)
static

Definition at line 86 of file shlexec.cpp.

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

Referenced by SHELL_execute().

◆ InvokeShellExecuteHook()

static HRESULT InvokeShellExecuteHook ( PCWSTR  pszClsid,
LPSHELLEXECUTEINFOW  pSEI 
)
static

Definition at line 99 of file shlexec.cpp.

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

Referenced by TryShellExecuteHooks().

◆ OpenAs_RunDLLA()

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

Definition at line 2855 of file shlexec.cpp.

2856{
2857 LPWSTR pszCmdLineW = NULL;
2858 TRACE("%p, %p, %s, %d\n", hwnd, hinst, debugstr_a(cmdline), cmdshow);
2859
2860 if (cmdline)
2861 __SHCloneStrAtoW(&pszCmdLineW, cmdline);
2862 OpenAs_RunDLLW(hwnd, hinst, pszCmdLineW, cmdshow);
2863 SHFree(pszCmdLineW);
2864}
#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:2844
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 2844 of file shlexec.cpp.

2845{
2847 TRACE("%p, %p, %s, %d\n", hwnd, hinst, debugstr_w(cmdline), cmdshow);
2849}
HRESULT WINAPI SHOpenWithDialog(HWND hwndParent, const OPENASINFO *poainfo)
@ OAIF_EXEC
Definition: shlobj.h:2688
@ OAIF_REGISTER_EXT
Definition: shlobj.h:2687
@ OAIF_ALLOW_REGISTRATION
Definition: shlobj.h:2686

Referenced by OpenAs_RunDLLA().

◆ ParseNoTildeEffect()

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

Definition at line 150 of file shlexec.cpp.

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

Referenced by SHELL_ArgifyW().

◆ ParseTildeEffect()

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

Definition at line 217 of file shlexec.cpp.

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

Referenced by SHELL_ArgifyW().

◆ PathIsExeW()

EXTERN_C BOOL PathIsExeW ( LPCWSTR  lpszPath)

Definition at line 539 of file shellpath.c.

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

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

◆ PathProcessCommandW()

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

Definition at line 3239 of file shlexec.cpp.

3244{
3245 TRACE("%s, %p, %d, 0x%X\n", wine_dbgstr_w(pszSrc), pszDest, cchDest, dwFlags);
3246
3247 if (!pszSrc)
3248 return -1;
3249
3251 PCWSTR pchArg = NULL;
3252
3253 if (*pszSrc == L'"') // Quoted?
3254 {
3255 ++pszSrc;
3256
3257 PCWSTR pch = wcschr(pszSrc, L'"');
3258 if (pch)
3259 {
3260 szPath.SetString(pszSrc, pch - pszSrc);
3261 pchArg = pch + 1;
3262 }
3263 else
3264 {
3265 szPath = pszSrc;
3266 }
3267
3269 {
3271 szPath.ReleaseBuffer();
3272 if (!ret)
3273 return -1;
3274 }
3275 }
3276 else // Not quoted?
3277 {
3278 BOOL resolved = FALSE;
3279 BOOL resolveRelative = PathIsRelativeW(pszSrc) || (dwFlags & PPCF_FORCEQUALIFY);
3280 INT cchPath = 0;
3281
3282 for (INT ich = 0; ; ++ich)
3283 {
3284 szPath += pszSrc[ich];
3285
3286 if (pszSrc[ich] && pszSrc[ich] != L' ')
3287 continue;
3288
3289 szPath = szPath.Left(ich);
3290
3291 if (resolveRelative &&
3293 {
3294 szPath.ReleaseBuffer();
3295 szPath += pszSrc[ich];
3296 }
3297 else
3298 {
3299 szPath.ReleaseBuffer();
3300
3302 if (attrs != INVALID_FILE_ATTRIBUTES &&
3304 {
3305 resolved = TRUE;
3306 pchArg = pszSrc + ich;
3307
3309 break;
3310
3311 cchPath = ich;
3312 break;
3313 }
3314 else if (!resolveRelative)
3315 {
3316 szPath += pszSrc[ich];
3317 }
3318 }
3319
3320 if (!szPath[ich])
3321 {
3322 szPath.ReleaseBuffer(); // Remove excessive '\0'
3323 break;
3324 }
3325 }
3326
3327 if (!resolved)
3328 return -1;
3329
3330 if (cchPath && (dwFlags & PPCF_LONGESTPOSSIBLE))
3331 {
3332 szPath = szPath.Left(cchPath);
3333 pchArg = pszSrc + cchPath;
3334 }
3335 }
3336
3337 BOOL needsQuoting = (dwFlags & PPCF_ADDQUOTES) && wcschr(szPath, L' ');
3338 CStringW result = needsQuoting ? (L"\"" + szPath + L"\"") : szPath;
3339
3340 if (pchArg && (dwFlags & PPCF_ADDARGUMENTS))
3341 result += pchArg;
3342
3343 LONG requiredSize = result.GetLength() + 1;
3344 if (!pszDest)
3345 return requiredSize;
3346
3347 if (requiredSize > cchDest || StringCchCopyW(pszDest, cchDest, result) != S_OK)
3348 return -1;
3349
3350 return requiredSize;
3351}
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:652
BOOL WINAPI PathIsRelativeW(const WCHAR *path)
Definition: path.c:1030
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:1151
#define PPCF_FORCEQUALIFY
Definition: shlobj.h:2427
#define PPCF_LONGESTPOSSIBLE
Definition: shlobj.h:2428
#define PPCF_ADDQUOTES
Definition: shlobj.h:2422
#define PPCF_ADDARGUMENTS
Definition: shlobj.h:2424
#define PPCF_NODIRECTORIES
Definition: shlobj.h:2425
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:4600
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
LONG_PTR LPARAM
Definition: minwindef.h:175
@ 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:403
int32_t INT_PTR
Definition: typedefs.h:64
#define SecureZeroMemory
Definition: winbase.h:1465
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
#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)

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

3188{
3190 lpOperation,
3191 lpFile,
3192 lpParameters,
3194 lpReturn,
3195 lpTitle,
3196 lpReserved,
3197 nCmdShow,
3198 lphProcess,
3199 0);
3200}
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:3043
_In_ DWORD _In_ int _In_ int _In_opt_ LPNLSVERSIONINFO _In_opt_ LPVOID lpReserved
Definition: winnls.h:1268

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

3055{
3056 SHELLEXECUTEINFOA ExecInfo;
3057
3058 TRACE("(%p, %s, %s, %s, %s, %p, %s, %p, %u, %p, %lu)\n",
3059 hwnd, debugstr_a(lpOperation), debugstr_a(lpFile), debugstr_a(lpParameters),
3061 lpReserved, nCmdShow, lphProcess, dwFlags);
3062
3063 ZeroMemory(&ExecInfo, sizeof(ExecInfo));
3064 ExecInfo.cbSize = sizeof(ExecInfo);
3066 ExecInfo.hwnd = hwnd;
3067 ExecInfo.lpVerb = lpOperation;
3068 ExecInfo.lpFile = lpFile;
3069 ExecInfo.lpParameters = lpParameters;
3070 ExecInfo.lpDirectory = lpDirectory;
3071 ExecInfo.nShow = (WORD)nCmdShow;
3072
3073 if (lpReserved)
3074 {
3075 ExecInfo.fMask |= SEE_MASK_USE_RESERVED;
3076 ExecInfo.hInstApp = (HINSTANCE)lpReserved;
3077 }
3078
3079 if (lpTitle)
3080 {
3081 ExecInfo.fMask |= SEE_MASK_HASTITLE;
3082 ExecInfo.lpClass = lpTitle;
3083 }
3084
3085 if (dwFlags & 1)
3086 ExecInfo.fMask |= SEE_MASK_FLAG_SEPVDM;
3087
3088 if (dwFlags & 2)
3089 ExecInfo.fMask |= SEE_MASK_NO_CONSOLE;
3090
3091 if (lphProcess == NULL)
3092 {
3093 ShellExecuteExA(&ExecInfo);
3094 }
3095 else
3096 {
3097 ExecInfo.fMask |= SEE_MASK_NOCLOSEPROCESS;
3098 ShellExecuteExA(&ExecInfo);
3099 *lphProcess = ExecInfo.hProcess;
3100 }
3101
3102 return ExecInfo.hInstApp;
3103}
unsigned short WORD
Definition: ntddk_ex.h:93
#define ZeroMemory
Definition: minwinbase.h:31
#define SEE_MASK_FLAG_NO_UI
Definition: shellapi.h:38
#define SEE_MASK_NO_CONSOLE
Definition: shellapi.h:41
BOOL WINAPI DECLSPEC_HOTPATCH ShellExecuteExA(LPSHELLEXECUTEINFOA sei)
Definition: shlexec.cpp:2665
LPCSTR lpParameters
Definition: shellapi.h:316
LPCSTR lpDirectory
Definition: shellapi.h:317
HANDLE HINSTANCE
Definition: typedefs.h:77
#define SEE_MASK_USE_RESERVED
Definition: undocshell.h:694
#define SEE_MASK_FLAG_SEPVDM
Definition: undocshell.h:693
#define SEE_MASK_HASTITLE
Definition: undocshell.h:695
#define SEE_MASK_UNKNOWN_0x1000
Definition: undocshell.h:690

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

3122{
3123 SHELLEXECUTEINFOW ExecInfo;
3124
3125 TRACE("(%p, %s, %s, %s, %s, %p, %s, %p, %u, %p, %lu)\n",
3126 hwnd, debugstr_w(lpOperation), debugstr_w(lpFile), debugstr_w(lpParameters),
3128 lpReserved, nCmdShow, lphProcess, dwFlags);
3129
3130 ZeroMemory(&ExecInfo, sizeof(ExecInfo));
3131 ExecInfo.cbSize = sizeof(ExecInfo);
3133 ExecInfo.hwnd = hwnd;
3134 ExecInfo.lpVerb = lpOperation;
3135 ExecInfo.lpFile = lpFile;
3136 ExecInfo.lpParameters = lpParameters;
3137 ExecInfo.lpDirectory = lpDirectory;
3138 ExecInfo.nShow = (WORD)nCmdShow;
3139
3140 if (lpReserved)
3141 {
3142 ExecInfo.fMask |= SEE_MASK_USE_RESERVED;
3143 ExecInfo.hInstApp = (HINSTANCE)lpReserved;
3144 }
3145
3146 if (lpTitle)
3147 {
3148 ExecInfo.fMask |= SEE_MASK_HASTITLE;
3149 ExecInfo.lpClass = lpTitle;
3150 }
3151
3152 if (dwFlags & 1)
3153 ExecInfo.fMask |= SEE_MASK_FLAG_SEPVDM;
3154
3155 if (dwFlags & 2)
3156 ExecInfo.fMask |= SEE_MASK_NO_CONSOLE;
3157
3158 if (lphProcess == NULL)
3159 {
3160 ShellExecuteExW(&ExecInfo);
3161 }
3162 else
3163 {
3164 ExecInfo.fMask |= SEE_MASK_NOCLOSEPROCESS;
3165 ShellExecuteExW(&ExecInfo);
3166 *lphProcess = ExecInfo.hProcess;
3167 }
3168
3169 return ExecInfo.hInstApp;
3170}
BOOL WINAPI DECLSPEC_HOTPATCH ShellExecuteExW(LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:2723
LPCWSTR lpParameters
Definition: shellapi.h:339

Referenced by RealShellExecuteW().

◆ RealShellExecuteW()

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

Definition at line 3207 of file shlexec.cpp.

3218{
3220 lpOperation,
3221 lpFile,
3222 lpParameters,
3224 lpReturn,
3225 lpTitle,
3226 lpReserved,
3227 nCmdShow,
3228 lphProcess,
3229 0);
3230}
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:3110

◆ 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
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
#define LOWORD(l)
Definition: pedump.c:82
#define IDC_RUNAS_PWD
Definition: shresdef.h:409
#define IDC_RUNAS_CURRENT
Definition: shresdef.h:404
#define IDC_RUNAS_OTHER
Definition: shresdef.h:405
#define IDC_RUNAS_SAFER
Definition: shresdef.h:406
#define IDC_RUNAS_NAME
Definition: shresdef.h:407
#define IDC_RUNAS_BROWSE
Definition: shresdef.h:408
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:598
#define LOGON_NETCREDENTIALS_ONLY
Definition: winbase.h:599
#define EM_LIMITTEXT
Definition: winuser.h:2029
#define DWLP_USER
Definition: winuser.h:883
#define GetWindowLongPtrW
Definition: winuser.h:4931
#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:5457
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
SHORT WINAPI GetKeyState(_In_ int)
BOOL WINAPI EndDialog(_In_ HWND, _In_ INT_PTR)

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:169
PVOID WINAPI SHLockShared(HANDLE hShared, DWORD dwProcId)
Definition: ordinal.c:259
BOOL WINAPI SHUnlockShared(LPVOID lpView)
Definition: ordinal.c:295
#define swprintf
Definition: precomp.h:40
#define ILGetSize
Definition: shellclasses.h:638
static void ParseNoTildeEffect(PWSTR &res, LPCWSTR &args, DWORD &len, DWORD &used, int argNum)
Definition: shlexec.cpp:150
static void ParseTildeEffect(PWSTR &res, LPCWSTR &args, DWORD &len, DWORD &used, int argNum)
Definition: shlexec.cpp:217
Definition: dsound.c:943
uint16_t * PWSTR
Definition: typedefs.h:56
ULONG_PTR SIZE_T
Definition: typedefs.h:80
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383

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

◆ SHELL_BuildEnvW()

static LPWSTR SHELL_BuildEnvW ( const WCHAR path)
static

Definition at line 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
wcscat
BOOL WINAPI FreeEnvironmentStringsW(IN LPWSTR EnvironmentStrings)
Definition: environ.c:389
LPWSTR WINAPI DECLSPEC_HOTPATCH GetEnvironmentStringsW(void)
Definition: process.c:1538
size_t total
GLsizei const GLchar *const * strings
Definition: glext.h:7622
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)

Referenced by SHELL_TryAppPathW().

◆ SHELL_execute()

static BOOL SHELL_execute ( LPSHELLEXECUTEINFOW  sei,
SHELL_ExecuteW32  execfunc 
)
static

Definition at line 2209 of file shlexec.cpp.

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

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

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

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

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:456
HMONITOR WINAPI MonitorFromWindow(HWND, DWORD)
#define STARTF_USEHOTKEY
Definition: pch.h:41
struct _STARTUPINFOW STARTUPINFOW
#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:692
#define STARTF_USESHOWWINDOW
Definition: winbase.h:468
#define CREATE_UNICODE_ENVIRONMENT
Definition: winbase.h:190
#define CREATE_SEPARATE_WOW_VDM
Definition: winbase.h:191
#define WAIT_FAILED
Definition: winbase.h:390
#define CREATE_NEW_CONSOLE
Definition: winbase.h:184
#define ERROR_BAD_FORMAT
Definition: winerror.h:236
DWORD WINAPI WaitForInputIdle(_In_ HANDLE, _In_ DWORD)

Referenced by ShellExecute_Normal().

◆ SHELL_FindExecutable()

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

Definition at line 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 else
1102 {
1103 xlpFile[0] = '\0';
1104 }
1105
1106 attribs = GetFileAttributesW(lpFile);
1108 {
1109 wcscpy(classname, L"Folder");
1110 }
1111 else
1112 {
1113 /* Did we get something? Anything? */
1114 if (xlpFile[0] == 0)
1115 {
1116 TRACE("Returning SE_ERR_FNF\n");
1117 return SE_ERR_FNF;
1118 }
1119 /* First thing we need is the file's extension */
1120 extension = wcsrchr(xlpFile, '.'); /* Assume last "." is the one; */
1121 /* File->Run in progman uses */
1122 /* .\FILE.EXE :( */
1123 TRACE("xlpFile=%s,extension=%s\n", debugstr_w(xlpFile), debugstr_w(extension));
1124
1125 if (extension == NULL || extension[1] == 0)
1126 {
1127 WARN("Returning SE_ERR_NOASSOC\n");
1128 return SE_ERR_NOASSOC;
1129 }
1130
1131 /* Three places to check: */
1132 /* 1. win.ini, [windows], programs (NB no leading '.') */
1133 /* 2. Registry, HKEY_CLASS_ROOT<classname>\shell\open\command */
1134 /* 3. win.ini, [extensions], extension (NB no leading '.' */
1135 /* All I know of the order is that registry is checked before */
1136 /* extensions; however, it'd make sense to check the programs */
1137 /* section first, so that's what happens here. */
1138
1139 /* See if it's a program - if GetProfileString fails, we skip this
1140 * section. Actually, if GetProfileString fails, we've probably
1141 * got a lot more to worry about than running a program... */
1142 if (GetProfileStringW(L"windows", L"programs", L"exe pif bat cmd com", wBuffer, ARRAY_SIZE(wBuffer)) > 0)
1143 {
1144 CharLowerW(wBuffer);
1145 tok = wBuffer;
1146 while (*tok)
1147 {
1148 WCHAR *p = tok;
1149 while (*p && *p != ' ' && *p != '\t') p++;
1150 if (*p)
1151 {
1152 *p++ = 0;
1153 while (*p == ' ' || *p == '\t') p++;
1154 }
1155
1156 if (_wcsicmp(tok, &extension[1]) == 0) /* have to skip the leading "." */
1157 {
1158 wcscpy(lpResult, xlpFile);
1159 /* Need to perhaps check that the file has a path
1160 * attached */
1161 TRACE("found %s\n", debugstr_w(lpResult));
1162 return 33;
1163 /* Greater than 32 to indicate success */
1164 }
1165 tok = p;
1166 }
1167 }
1168
1169 /* Check registry */
1171 &classnamelen) == ERROR_SUCCESS)
1172 {
1173 classnamelen /= sizeof(WCHAR);
1174 if (classnamelen == ARRAY_SIZE(classname))
1175 classnamelen--;
1176
1177 classname[classnamelen] = '\0';
1178 TRACE("File type: %s\n", debugstr_w(classname));
1179 }
1180 else
1181 {
1182 *classname = '\0';
1183 }
1184 }
1185
1186 if (*classname)
1187 {
1188 /* pass the verb string to SHELL_FindExecutableByVerb() */
1190
1191 if (retval > 32)
1192 {
1193 DWORD finishedLen;
1194 SHELL_ArgifyW(lpResult, resultLen, command, xlpFile, pidl, args, &finishedLen, lpPath);
1195 if (finishedLen > resultLen)
1196 ERR("Argify buffer not large enough.. truncated\n");
1197 /* Remove double quotation marks and command line arguments */
1198 if (*lpResult == '"')
1199 {
1200 WCHAR *p = lpResult;
1201 while (*(p + 1) != '"')
1202 {
1203 *p = *(p + 1);
1204 p++;
1205 }
1206 *p = '\0';
1207 }
1208 else
1209 {
1210 /* Truncate on first space */
1211 WCHAR *p = lpResult;
1212 while (*p != ' ' && *p != '\0')
1213 p++;
1214 *p = '\0';
1215 }
1216 }
1217 }
1218 else /* Check win.ini */
1219 {
1220 /* Toss the leading dot */
1221 extension++;
1222 if (GetProfileStringW(L"extensions", extension, L"", command, ARRAY_SIZE(command)) > 0)
1223 {
1224 if (wcslen(command) != 0)
1225 {
1226 wcscpy(lpResult, command);
1227 tok = wcschr(lpResult, '^'); /* should be ^.extension? */
1228 if (tok != NULL)
1229 {
1230 tok[0] = '\0';
1231 wcscat(lpResult, xlpFile); /* what if no dir in xlpFile? */
1232 tok = wcschr(command, '^'); /* see above */
1233 if ((tok != NULL) && (wcslen(tok) > 5))
1234 {
1235 wcscat(lpResult, &tok[5]);
1236 }
1237 }
1238 retval = 33; /* FIXME - see above */
1239 }
1240 }
1241 }
1242
1243 TRACE("returning path %s, retval %d\n", debugstr_w(lpResult), retval);
1244 return retval;
1245}
#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:1910
LPWSTR WINAPI CharLowerW(WCHAR *str)
Definition: string.c:1092
BOOL WINAPI PathFindOnPathW(LPWSTR lpszFile, LPCWSTR *lppszOtherDirs)
Definition: path.c:1409
const GLint * attribs
Definition: glext.h:10538
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
static BOOL SHELL_TryAppPathW(LPCWSTR szName, LPWSTR lpResult, WCHAR **env)
Definition: shlexec.cpp: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 GetShellWindow(void)
Definition: input.c:974
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:628
BOOL WINAPI IsChild(_In_ HWND, _In_ HWND)
BOOL WINAPI IsWindowVisible(_In_ HWND)

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:1701

Referenced by ShellExec_RunDLL_Helper(), and ShellExecuteExW().

◆ SHELL_InvokePidl()

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

Definition at line 2045 of file shlexec.cpp.

2048{
2049 // Bind pidl
2050 CComPtr<IShellFolder> psfFolder;
2051 LPCITEMIDLIST pidlLast;
2052 HRESULT hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &psfFolder), &pidlLast);
2054 return FALSE;
2055
2056 // Get the context menu to invoke a command
2058 hr = psfFolder->GetUIObjectOf(NULL, 1, &pidlLast, IID_NULL_PPV_ARG(IContextMenu, &pCM));
2060 return FALSE;
2061
2062 // Invoke a command
2063 CMINVOKECOMMANDINFO ici = { sizeof(ici) };
2064 ici.fMask = (sei->fMask & SEE_CMIC_COMMON_BASICFLAGS) & ~CMIC_MASK_UNICODE; // FIXME: Unicode?
2065 ici.nShow = sei->nShow;
2066 ici.hwnd = sei->hwnd;
2067 char szVerb[VERBKEY_CCHMAX];
2068 if (sei->lpVerb && sei->lpVerb[0])
2069 {
2070 WideCharToMultiByte(CP_ACP, 0, sei->lpVerb, -1, szVerb, _countof(szVerb), NULL, NULL);
2071 szVerb[_countof(szVerb) - 1] = ANSI_NULL; // Avoid buffer overrun
2072 ici.lpVerb = szVerb;
2073 }
2074 else // The default verb?
2075 {
2076 HMENU hMenu = CreatePopupMenu();
2077 const INT idCmdFirst = 1, idCmdLast = 0x7FFF;
2078 hr = pCM->QueryContextMenu(hMenu, 0, idCmdFirst, idCmdLast, CMF_DEFAULTONLY);
2080 {
2081 DestroyMenu(hMenu);
2082 return FALSE;
2083 }
2084
2085 INT nDefaultID = GetMenuDefaultItem(hMenu, FALSE, 0);
2086 DestroyMenu(hMenu);
2087 if (nDefaultID == -1)
2088 nDefaultID = idCmdFirst;
2089
2090 ici.lpVerb = MAKEINTRESOURCEA(nDefaultID - idCmdFirst);
2091 }
2092 hr = pCM->InvokeCommand(&ici);
2093
2094 return !FAILED_UNEXPECTEDLY(hr);
2095}
#define VERBKEY_CCHMAX
Definition: precomp.h:130
#define FAILED_UNEXPECTEDLY
Definition: utils.cpp:30
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:60
#define ANSI_NULL
HRESULT WINAPI SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCITEMIDLIST *ppidlLast)
Definition: pidl.c:1498
HMENU WINAPI CreatePopupMenu(void)
Definition: menu.c:838
UINT WINAPI GetMenuDefaultItem(_In_ HMENU hMenu, _In_ UINT fByPos, _In_ UINT gmdiFlags)
#define MAKEINTRESOURCEA(i)
Definition: winuser.h:581
BOOL WINAPI DestroyMenu(_In_ HMENU)
#define IID_NULL_PPV_ARG(Itype, ppType)

Referenced by SHELL_execute().

◆ SHELL_quote_and_execute()

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

Definition at line 2097 of file shlexec.cpp.

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

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

1990{
1992 BOOL appKnownSingular = FALSE;
1993
1994 /* last chance to translate IDList: now also allow CLSID paths */
1996 if (buffer[0] == ':' && buffer[1] == ':') {
1997 /* open shell folder for the specified class GUID */
1998 if (strlenW(buffer) + 1 > parametersLen)
1999 ERR("parameters len exceeds buffer size (%i > %i), truncating\n",
2000 lstrlenW(buffer) + 1, parametersLen);
2001 lstrcpynW(wszParameters, buffer, parametersLen);
2002 if (strlenW(L"explorer.exe") > dwApplicationNameLen)
2003 ERR("application len exceeds buffer size (%i), truncating\n",
2004 dwApplicationNameLen);
2005 lstrcpynW(wszApplicationName, L"explorer.exe", dwApplicationNameLen);
2006 appKnownSingular = TRUE;
2007
2008 sei->fMask &= ~SEE_MASK_INVOKEIDLIST;
2009 } else {
2011 DWORD attribs;
2012 DWORD resultLen;
2013 /* Check if we're executing a directory and if so use the
2014 handler for the Folder class */
2019 HCR_GetExecuteCommandW(0, L"Folder",
2020 sei->lpVerb,
2021 buffer, sizeof(buffer))) {
2022 SHELL_ArgifyW(wszApplicationName, dwApplicationNameLen,
2023 buffer, target, (LPITEMIDLIST)sei->lpIDList, NULL, &resultLen,
2024 !StrIsNullOrEmpty(sei->lpDirectory) ? sei->lpDirectory : NULL);
2025 if (resultLen > dwApplicationNameLen)
2026 ERR("Argify buffer not large enough... truncating\n"); // FIXME: Report this to the caller?
2027 appKnownSingular = FALSE;
2028 // HACKFIX: We really want the !appKnownSingular code in SHELL_execute to split the
2029 // parameters for us but we cannot guarantee that the exe in the registry is quoted.
2030 // We have now turned 'explorer.exe "%1" into 'explorer.exe "c:\path\from\pidl"' and
2031 // need to split to application and parameters.
2032 LPCWSTR params = PathGetArgsW(wszApplicationName);
2033 lstrcpynW(wszParameters, params, parametersLen);
2034 PathRemoveArgsW(wszApplicationName);
2035 PathUnquoteSpacesW(wszApplicationName);
2036 appKnownSingular = TRUE;
2037 }
2038 sei->fMask &= ~SEE_MASK_INVOKEIDLIST;
2039 }
2040 }
2041 return appKnownSingular;
2042}
#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}
GLuint GLuint end
Definition: gl.h:1545
#define REG_SZ
Definition: layer.c:22
#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 1780 of file shlexec.cpp.

1781{
1782 CComHeapPtr<ITEMIDLIST> allocatedPidl;
1783 LPITEMIDLIST pidl = NULL;
1784
1785 if (sei->lpIDList)
1786 {
1787 pidl = (LPITEMIDLIST)sei->lpIDList;
1788 }
1789 else
1790 {
1791 SFGAOF sfga = 0;
1792 HRESULT hr = SHParseDisplayName(sei->lpFile, NULL, &allocatedPidl, SFGAO_STORAGECAPMASK, &sfga);
1793 if (FAILED(hr))
1794 {
1795 WCHAR Buffer[MAX_PATH] = {};
1796 // FIXME: MAX_PATH.....
1798 if (retval <= 32)
1799 return HRESULT_FROM_WIN32(retval);
1800
1801 hr = SHParseDisplayName(Buffer, NULL, &allocatedPidl, SFGAO_STORAGECAPMASK, &sfga);
1802 // This should not happen, we found it...
1804 return hr;
1805 }
1806
1807 pidl = allocatedPidl;
1808 }
1809
1811 LPCITEMIDLIST pidllast = NULL;
1812 HRESULT hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &shf), &pidllast);
1813 if (FAILED(hr))
1814 return hr;
1815
1816 return shf->GetUIObjectOf(NULL, 1, &pidllast, IID_NULL_PPV_ARG(IContextMenu, &cm));
1817}
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 1652 of file shlexec.cpp.

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

Referenced by shellex_load_object_and_run().

◆ shellex_load_object_and_run()

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

Definition at line 1746 of file shlexec.cpp.

1747{
1748 TRACE("%p %s %p\n", hkey, debugstr_guid(guid), sei);
1749
1750 CCoInit coInit;
1751
1752 if (FAILED_UNEXPECTEDLY(coInit.hr))
1753 return coInit.hr;
1754
1756 HRESULT hr = CoCreateInstance(*guid, NULL, CLSCTX_INPROC_SERVER,
1759 return hr;
1760
1761 CComPtr<IDataObject> dataobj;
1762 hr = shellex_get_dataobj(sei, dataobj);
1764 return hr;
1765
1766 hr = obj->Initialize(NULL, dataobj, hkey);
1768 return hr;
1769
1771 hr = obj->QueryInterface(IID_PPV_ARG(IObjectWithSite, &ows));
1773 return hr;
1774
1775 ows->SetSite(NULL);
1776
1778}
GUID guid
Definition: version.c:147
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
#define debugstr_guid
Definition: kernel32.h:35
static HRESULT shellex_run_context_menu_default(IShellExtInit *obj, LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:1677
static HRESULT shellex_get_dataobj(LPSHELLEXECUTEINFOW sei, CComPtr< IDataObject > &dataObj)
Definition: shlexec.cpp:1652

Referenced by ShellExecute_FromContextMenuHandlers().

◆ shellex_run_context_menu_default()

static HRESULT shellex_run_context_menu_default ( IShellExtInit obj,
LPSHELLEXECUTEINFOW  sei 
)
static

Definition at line 1677 of file shlexec.cpp.

1679{
1681 CMINVOKECOMMANDINFOEX ici;
1683 WCHAR string[0x80];
1684 INT i, n, def = -1;
1685 HMENU hmenu = 0;
1686 HRESULT r;
1687
1688 TRACE("%p %p\n", obj, sei);
1689
1690 r = obj->QueryInterface(IID_PPV_ARG(IContextMenu, &cm));
1691 if (FAILED(r))
1692 return r;
1693
1694 hmenu = CreateMenu();
1695 if (!hmenu)
1696 goto end;
1697
1698 /* the number of the last menu added is returned in r */
1699 r = cm->QueryContextMenu(hmenu, 0, 0x20, 0x7fff, CMF_DEFAULTONLY);
1700 if (FAILED(r))
1701 goto end;
1702
1704 for (i = 0; i < n; i++)
1705 {
1706 memset(&info, 0, sizeof(info));
1707 info.cbSize = sizeof info;
1709 info.dwTypeData = string;
1710 info.cch = sizeof string;
1711 string[0] = 0;
1713
1714 TRACE("menu %d %s %08x %08lx %08x %08x\n", i, debugstr_w(string),
1715 info.fState, info.dwItemData, info.fType, info.wID);
1716 if ((!sei->lpVerb && (info.fState & MFS_DEFAULT)) ||
1717 (sei->lpVerb && !lstrcmpiW(sei->lpVerb, string)))
1718 {
1719 def = i;
1720 break;
1721 }
1722 }
1723
1724 r = E_FAIL;
1725 if (def == -1)
1726 goto end;
1727
1728 memset(&ici, 0, sizeof ici);
1729 ici.cbSize = sizeof ici;
1730 ici.fMask = (sei->fMask & SEE_CMIC_COMMON_BASICFLAGS) | CMIC_MASK_UNICODE;
1731 ici.nShow = sei->nShow;
1732 ici.lpVerb = MAKEINTRESOURCEA(def);
1733 ici.hwnd = sei->hwnd;
1734 ici.lpParametersW = sei->lpParameters;
1735
1736 r = cm->InvokeCommand((LPCMINVOKECOMMANDINFO)&ici);
1737
1738 TRACE("invoke command returned %08x\n", r);
1739
1740end:
1741 if (hmenu)
1742 DestroyMenu( hmenu );
1743 return r;
1744}
int WINAPI lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4265
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLdouble n
Definition: glext.h:7729
static HMENU hmenu
Definition: win.c:66
#define memset(x, y, z)
Definition: compat.h:39
#define MIIM_STRING
Definition: winuser.h:738
#define MIIM_ID
Definition: winuser.h:733
int WINAPI GetMenuItemCount(_In_opt_ HMENU)
HMENU WINAPI CreateMenu(void)
Definition: menu.c:829
#define MIIM_FTYPE
Definition: winuser.h:740
#define MIIM_STATE
Definition: winuser.h:732
#define MFS_DEFAULT
Definition: winuser.h:759
BOOL WINAPI GetMenuItemInfoW(_In_ HMENU, _In_ UINT, _In_ BOOL, _Inout_ LPMENUITEMINFOW)
#define MIIM_DATA
Definition: winuser.h:737

Referenced by shellex_load_object_and_run().

◆ ShellExec_RunDLL_Helper()

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

Definition at line 3355 of file shlexec.cpp.

3360{
3361 TRACE("(%p, %p, %s, 0x%X)\n", hwnd, hInstance, wine_dbgstr_w(pszCmdLine), nCmdShow);
3362
3363 if (!pszCmdLine || !*pszCmdLine)
3364 return;
3365
3366 // '?' enables us to specify the additional mask value
3367 ULONG fNewMask = SEE_MASK_NOASYNC;
3368 if (*pszCmdLine == L'?') // 1st question
3369 {
3370 INT MaskValue;
3371 if (StrToIntExW(pszCmdLine + 1, STIF_SUPPORT_HEX, &MaskValue))
3372 fNewMask |= MaskValue;
3373
3374 PCWSTR pch2ndQuestion = StrChrW(pszCmdLine + 1, L'?'); // 2nd question
3375 if (pch2ndQuestion)
3376 pszCmdLine = pch2ndQuestion + 1;
3377 }
3378
3379 WCHAR szPath[2 * MAX_PATH];
3381 if (PathProcessCommandW(pszCmdLine, szPath, _countof(szPath), dwFlags) == -1)
3382 StrCpyNW(szPath, pszCmdLine, _countof(szPath));
3383
3384 // Split arguments from the path
3386 if (*Args)
3387 *(Args - 1) = UNICODE_NULL;
3388
3390
3391 // Execute
3392 SHELLEXECUTEINFOW execInfo = { sizeof(execInfo) };
3393 execInfo.fMask = fNewMask;
3394 execInfo.hwnd = hwnd;
3395 execInfo.lpFile = szPath;
3396 execInfo.lpParameters = Args;
3397 execInfo.nShow = nCmdShow;
3398 if (!ShellExecuteExW(&execInfo))
3399 {
3400 DWORD dwError = GetLastError();
3401 if (SHELL_InRunDllProcess()) // Is it a RUNDLL process?
3402 ExitProcess(dwError); // Terminate it now
3403 }
3404}
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:1489
BOOL WINAPI StrToIntExW(const WCHAR *str, DWORD flags, INT *ret)
Definition: string.c:972
WCHAR *WINAPI StrCpyNW(WCHAR *dst, const WCHAR *src, int count)
Definition: string.c:462
#define STIF_SUPPORT_HEX
Definition: shlwapi.h:1059
#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:3239
static BOOL SHELL_InRunDllProcess(VOID)
Definition: shlexec.cpp:73
#define PPCF_INCLUDEARGS
Definition: shlobj.h:2423

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

3418{
3419 CStringW strCmdLine = pszCmdLine; // Keep
3420 ShellExec_RunDLL_Helper(hwnd, hInstance, strCmdLine, nCmdShow);
3421}
static VOID ShellExec_RunDLL_Helper(_In_opt_ HWND hwnd, _In_opt_ HINSTANCE hInstance, _In_ PCWSTR pszCmdLine, _In_ INT nCmdShow)
Definition: shlexec.cpp:3355

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

3435{
3436 ShellExec_RunDLL_Helper(hwnd, hInstance, pszCmdLine, nCmdShow);
3437}

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

2922{
2925 LPCWSTR pszVerb = NULL;
2926 WCHAR szFile[MAX_PATH], szFile2[MAX_PATH];
2927 HRESULT hr;
2928 LPCWSTR pchParams;
2929 LPWSTR lpCommand = NULL;
2930
2931 if (pwszCommand == NULL)
2933 1, (ULONG_PTR*)pwszCommand);
2934
2935 __SHCloneStrW(&lpCommand, pwszCommand);
2936 StrTrimW(lpCommand, L" \t");
2937
2938 if (dwSeclFlags & SECL_NO_UI)
2940 if (dwSeclFlags & SECL_LOG_USAGE)
2942 if (dwSeclFlags & SECL_USE_IDLIST)
2944
2945 if (dwSeclFlags & SECL_RUNAS)
2946 {
2947 dwSize = 0;
2948 hr = AssocQueryStringW(ASSOCF_NONE, ASSOCSTR_COMMAND, lpCommand, L"runas", NULL, &dwSize);
2949 if (SUCCEEDED(hr) && dwSize != 0)
2950 {
2951 pszVerb = L"runas";
2952 }
2953 }
2954
2955 if (PathIsURLW(lpCommand) || UrlIsW(lpCommand, URLIS_APPLIABLE))
2956 {
2957 StringCchCopyW(szFile, _countof(szFile), lpCommand);
2958 pchParams = NULL;
2959 }
2960 else
2961 {
2962 PCWSTR apPathList[2];
2963
2964 pchParams = SplitParams(lpCommand, szFile, _countof(szFile));
2965 if (szFile[0] != UNICODE_NULL && szFile[1] == L':' &&
2966 szFile[2] == UNICODE_NULL)
2967 {
2968 PathAddBackslashW(szFile);
2969 }
2970
2971 WCHAR szCurDir[MAX_PATH];
2972 GetCurrentDirectoryW(_countof(szCurDir), szCurDir);
2973 if (pwszStartDir)
2974 {
2975 SetCurrentDirectoryW(pwszStartDir);
2976 }
2977
2978 if ((PathIsRelativeW(szFile) &&
2979 GetFullPathNameW(szFile, _countof(szFile2), szFile2, NULL) &&
2980 PathFileExistsW(szFile2)) ||
2981 SearchPathW(NULL, szFile, NULL, _countof(szFile2), szFile2, NULL))
2982 {
2983 StringCchCopyW(szFile, _countof(szFile), szFile2);
2984 }
2985
2986 apPathList[0] = pwszStartDir;
2987 apPathList[1] = NULL;
2988 PathFindOnPathExW(szFile, apPathList, WHICH_DEFAULT);
2989
2990 if (!(dwSeclFlags & SECL_ALLOW_NONEXE))
2991 {
2992 if (!GetBinaryTypeW(szFile, &dwType))
2993 {
2994 SHFree(lpCommand);
2995
2996 if (!(dwSeclFlags & SECL_NO_UI))
2997 {
2998 WCHAR szText[128 + MAX_PATH], szFormat[128];
3000 StringCchPrintfW(szText, _countof(szText), szFormat, szFile);
3001 MessageBoxW(hwnd, szText, NULL, MB_ICONERROR);
3002 }
3003 return CO_E_APPNOTFOUND;
3004 }
3005 }
3006 else
3007 {
3009 {
3010 SHFree(lpCommand);
3011
3012 if (!(dwSeclFlags & SECL_NO_UI))
3013 {
3014 WCHAR szText[128 + MAX_PATH], szFormat[128];
3016 StringCchPrintfW(szText, _countof(szText), szFormat, szFile);
3017 MessageBoxW(hwnd, szText, NULL, MB_ICONERROR);
3018 }
3020 }
3021 }
3022 }
3023
3024 ZeroMemory(&info, sizeof(info));
3025 info.cbSize = sizeof(info);
3026 info.fMask = dwFlags;
3027 info.hwnd = hwnd;
3028 info.lpVerb = pszVerb;
3029 info.lpFile = szFile;
3030 info.lpParameters = (pchParams && *pchParams) ? pchParams : NULL;
3031 info.lpDirectory = pwszStartDir;
3032 info.nShow = nShow;
3034 SHFree(lpCommand);
3035 return HRESULT_FROM_WIN32(error);
3036}
#define SECL_USE_IDLIST
#define SECL_LOG_USAGE
#define SECL_ALLOW_NONEXE
#define SECL_RUNAS
#define SECL_NO_UI
VOID WINAPI RaiseException(_In_ DWORD dwExceptionCode, _In_ DWORD dwExceptionFlags, _In_ DWORD nNumberOfArguments, _In_opt_ const ULONG_PTR *lpArguments)
Definition: except.c:700
BOOL WINAPI GetBinaryTypeW(LPCWSTR lpApplicationName, LPDWORD lpBinaryType)
Definition: vdm.c:1243
BOOL WINAPI UrlIsW(const WCHAR *url, URLIS Urlis)
Definition: path.c:4812
BOOL WINAPI PathFileExistsW(const WCHAR *path)
Definition: path.c:2607
BOOL WINAPI StrTrimW(WCHAR *str, const WCHAR *trim)
Definition: string.c:796
BOOL WINAPI PathFindOnPathExW(LPWSTR lpszFile, LPCWSTR *lppszOtherDirs, DWORD dwWhich)
Definition: path.c:1357
#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:2869
#define WHICH_DEFAULT
#define IDS_FILE_NOT_FOUND
Definition: shresdef.h:373
#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 1819 of file shlexec.cpp.

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

Referenced by SHELL_execute().

◆ ShellExecute_FromContextMenuHandlers()

static LONG ShellExecute_FromContextMenuHandlers ( LPSHELLEXECUTEINFOW  sei)
static

Definition at line 1885 of file shlexec.cpp.

1886{
1887 HKEY hkey, hkeycm = 0;
1888 WCHAR szguid[39];
1889 HRESULT hr;
1890 GUID guid;
1891 DWORD i;
1892 LONG r;
1893
1894 TRACE("%s\n", debugstr_w(sei->lpFile));
1895
1896 hkey = ShellExecute_GetClassKey(sei);
1897 if (!hkey)
1898 return ERROR_FUNCTION_FAILED;
1899
1900 // FIXME: Words cannot describe how broken this is, all of it needs to die
1901 r = RegOpenKeyW(hkey, L"shellex\\ContextMenuHandlers", &hkeycm);
1902 if (r == ERROR_SUCCESS)
1903 {
1904 i = 0;
1905 while (1)
1906 {
1907 r = RegEnumKeyW(hkeycm, i++, szguid, ARRAY_SIZE(szguid));
1908 if (r != ERROR_SUCCESS)
1909 break;
1910
1911 hr = CLSIDFromString(szguid, &guid);
1912 if (SUCCEEDED(hr))
1913 {
1914 /* stop at the first one that succeeds in running */
1915 hr = shellex_load_object_and_run(hkey, &guid, sei);
1916 if (SUCCEEDED(hr))
1917 break;
1918 }
1919 }
1920 RegCloseKey(hkeycm);
1921 }
1922
1923 if (hkey != sei->hkeyClass)
1924 RegCloseKey(hkey);
1925 return r;
1926}
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3268
LONG WINAPI RegEnumKeyW(HKEY hKey, DWORD dwIndex, LPWSTR lpName, DWORD cbName)
Definition: reg.c:2393
HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id)
Definition: compobj.c:2338
static HRESULT shellex_load_object_and_run(HKEY hkey, LPCGUID guid, LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:1746
static HKEY ShellExecute_GetClassKey(const SHELLEXECUTEINFOW *sei)
Definition: shlexec.cpp:1633
#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 1633 of file shlexec.cpp.

1634{
1636 return sei->hkeyClass;
1637
1638 HKEY hKey = NULL;
1639 if (sei->fMask & SEE_MASK_CLASSNAME)
1640 {
1641 TRACE("class = %s\n", debugstr_w(sei->lpClass));
1643 return hKey;
1644 }
1646 TRACE("ext = %s\n", debugstr_w(ext));
1647 if (!StrIsNullOrEmpty(ext) && SUCCEEDED(HCR_GetProgIdKeyOfExtension(ext, &hKey, FALSE)))
1648 return hKey;
1649 return NULL;
1650}
static const WCHAR *const ext[]
Definition: module.c:53
LPWSTR WINAPI PathFindExtensionW(const WCHAR *path)
Definition: path.c:1274
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 2637 of file shlexec.cpp.

2638{
2639 // FIXME
2640 if (SHELL_execute(sei, SHELL_ExecuteW))
2641 return ERROR_SUCCESS;
2643#if DBG
2644 if (!err)
2645 DbgPrint("FIXME: Failed with error 0 on '%ls'\n", sei->lpFile);
2646#endif
2647 return err ? err : ERROR_FILE_NOT_FOUND;
2648}
#define DbgPrint
Definition: hal.h:12
static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
Definition: shlexec.cpp:2209
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 2651 of file shlexec.cpp.

2655{
2656 // FIXME: Show error message
2657}

Referenced by ShellExecuteExW().

◆ ShellExecuteA()

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

Definition at line 2607 of file shlexec.cpp.

2609{
2611
2612 TRACE("%p,%s,%s,%s,%s,%d\n",
2613 hWnd, debugstr_a(lpVerb), debugstr_a(lpFile),
2614 debugstr_a(lpParameters), debugstr_a(lpDirectory), iShowCmd);
2615
2616 sei.cbSize = sizeof(sei);
2618 sei.hwnd = hWnd;
2619 sei.lpVerb = lpVerb;
2620 sei.lpFile = lpFile;
2621 sei.lpParameters = lpParameters;
2623 sei.nShow = iShowCmd;
2624 sei.lpIDList = 0;
2625 sei.lpClass = 0;
2626 sei.hkeyClass = 0;
2627 sei.dwHotKey = 0;
2628 sei.hProcess = 0;
2629
2631 sei.fMask |= SEE_MASK_NOASYNC;
2632 ShellExecuteExA(&sei);
2633 return sei.hInstApp;
2634}
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 2665 of file shlexec.cpp.

2666{
2667 SHELLEXECUTEINFOW seiW;
2668 BOOL ret;
2669 WCHAR *wVerb = NULL, *wFile = NULL, *wParameters = NULL, *wDirectory = NULL, *wClass = NULL;
2670
2671 TRACE("%p\n", sei);
2672
2673 if (sei->cbSize != sizeof(SHELLEXECUTEINFOA))
2674 {
2677 return FALSE;
2678 }
2679
2680 memcpy(&seiW, sei, sizeof(SHELLEXECUTEINFOW));
2681
2682 seiW.cbSize = sizeof(SHELLEXECUTEINFOW);
2683
2684 if (sei->lpVerb)
2685 seiW.lpVerb = __SHCloneStrAtoW(&wVerb, sei->lpVerb);
2686
2687 if (sei->lpFile)
2688 seiW.lpFile = __SHCloneStrAtoW(&wFile, sei->lpFile);
2689
2690 if (sei->lpParameters)
2691 seiW.lpParameters = __SHCloneStrAtoW(&wParameters, sei->lpParameters);
2692
2693 if (sei->lpDirectory)
2694 seiW.lpDirectory = __SHCloneStrAtoW(&wDirectory, sei->lpDirectory);
2695
2696 if ((sei->fMask & SEE_MASK_CLASSALL) == SEE_MASK_CLASSNAME && sei->lpClass)
2697 seiW.lpClass = __SHCloneStrAtoW(&wClass, sei->lpClass);
2698 else
2699 seiW.lpClass = NULL;
2700
2701 ret = ShellExecuteExW(&seiW);
2702
2703 sei->hInstApp = seiW.hInstApp;
2704
2705 if (sei->fMask & SEE_MASK_NOCLOSEPROCESS)
2706 sei->hProcess = seiW.hProcess;
2707
2708 SHFree(wVerb);
2709 SHFree(wFile);
2710 SHFree(wParameters);
2711 SHFree(wDirectory);
2712 SHFree(wClass);
2713
2714 return ret;
2715}
struct _SHELLEXECUTEINFOW SHELLEXECUTEINFOW

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

◆ ShellExecuteExW()

Definition at line 2723 of file shlexec.cpp.

2724{
2725 HRESULT hrCoInit;
2726 DWORD dwError;
2727 ULONG fOldMask;
2728
2729 if (sei->cbSize != sizeof(SHELLEXECUTEINFOW))
2730 {
2733 return FALSE;
2734 }
2735
2736 hrCoInit = SHCoInitializeAnyApartment();
2737
2738 if (SHRegGetBoolUSValueW(L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer",
2739 L"MaximizeApps", FALSE, FALSE))
2740 {
2741 switch (sei->nShow)
2742 {
2743 case SW_SHOW:
2744 case SW_SHOWDEFAULT:
2745 case SW_SHOWNORMAL:
2746 case SW_RESTORE:
2747 sei->nShow = SW_SHOWMAXIMIZED;
2748 break;
2749 default:
2750 break;
2751 }
2752 }
2753
2754 fOldMask = sei->fMask;
2755
2756 if (!(fOldMask & SEE_MASK_NOASYNC) && SHELL_InRunDllProcess())
2758
2759 dwError = ShellExecute_Normal(sei);
2760
2761 if (dwError && dwError != ERROR_DLL_NOT_FOUND && dwError != ERROR_CANCELLED)
2762 ShellExecute_ShowError(sei, NULL, dwError);
2763
2764 sei->fMask = fOldMask;
2765
2766 if (SUCCEEDED(hrCoInit))
2768
2769 if (dwError)
2770 SetLastError(dwError);
2771
2772 return dwError == ERROR_SUCCESS;
2773}
BOOL WINAPI SHRegGetBoolUSValueW(const WCHAR *subkey, const WCHAR *value, BOOL ignore_hkcu, BOOL default_value)
Definition: registry.c:4139
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
HRESULT SHCoInitializeAnyApartment(VOID)
Definition: utils.cpp:494
#define SE_ERR_ACCESSDENIED
Definition: shellapi.h:127
#define SEE_MASK_WAITFORINPUTIDLE
Definition: shellapi.h:52
static DWORD ShellExecute_Normal(_Inout_ LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:2637
static VOID ShellExecute_ShowError(_In_ const SHELLEXECUTEINFOW *ExecInfo, _In_opt_ LPCWSTR pszCaption, _In_ DWORD dwError)
Definition: shlexec.cpp:2651
#define ERROR_DLL_NOT_FOUND
Definition: winerror.h:1003
#define SW_SHOWNORMAL
Definition: winuser.h:781
#define SW_SHOWMAXIMIZED
Definition: winuser.h:784
#define SW_SHOWDEFAULT
Definition: winuser.h:791
#define SW_RESTORE
Definition: winuser.h:790

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

◆ ShellExecuteW()

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

Definition at line 2778 of file shlexec.cpp.

2780{
2782
2783 TRACE("\n");
2784 sei.cbSize = sizeof(sei);
2786 sei.hwnd = hwnd;
2787 sei.lpVerb = lpVerb;
2788 sei.lpFile = lpFile;
2789 sei.lpParameters = lpParameters;
2791 sei.nShow = nShowCmd;
2792 sei.lpIDList = 0;
2793 sei.lpClass = 0;
2794 sei.hkeyClass = 0;
2795 sei.dwHotKey = 0;
2796 sei.hProcess = 0;
2797
2799 sei.fMask |= SEE_MASK_NOASYNC;
2800 ShellExecuteExW(&sei);
2801 return sei.hInstApp;
2802}

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

◆ SplitParams()

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

Definition at line 2869 of file shlexec.cpp.

2870{
2871 LPCWSTR pch;
2872 size_t ich = 0;
2873 if (*psz == L'"')
2874 {
2875 // 1st argument is quoted. the string in quotes is quoted 1st argument.
2876 // [pch] --> [pszArg0+ich]
2877 for (pch = psz + 1; *pch && ich + 1 < cchArg0; ++ich, ++pch)
2878 {
2879 if (*pch == L'"' && pch[1] == L'"')
2880 {
2881 // doubled double quotations found!
2882 pszArg0[ich] = L'"';
2883 }
2884 else if (*pch == L'"')
2885 {
2886 // single double quotation found!
2887 ++pch;
2888 break;
2889 }
2890 else
2891 {
2892 // otherwise
2893 pszArg0[ich] = *pch;
2894 }
2895 }
2896 }
2897 else
2898 {
2899 // 1st argument is unquoted. non-space sequence is 1st argument.
2900 // [pch] --> [pszArg0+ich]
2901 for (pch = psz; *pch && !iswspace(*pch) && ich + 1 < cchArg0; ++ich, ++pch)
2902 {
2903 pszArg0[ich] = *pch;
2904 }
2905 }
2906 pszArg0[ich] = 0;
2907
2908 // skip space
2909 while (iswspace(*pch))
2910 ++pch;
2911
2912 return pch;
2913}
#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
DWORD SH32_InternalRestricted(DWORD rest)
Definition: shpolicy.c:180
@ REST_SH32_ENABLESHELLEXECUTEHOOKS
Definition: shell32_main.h:41
static HRESULT InvokeShellExecuteHook(PCWSTR pszClsid, LPSHELLEXECUTEINFOW pSEI)
Definition: shlexec.cpp:99
#define SEE_MASK_NO_HOOKS
Definition: undocshell.h:691

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

2811{
2812 SHELLEXECUTEINFOW seiW;
2813 WCHAR *wVerb = NULL, *wFile = NULL, *wParameters = NULL, *wDirectory = NULL;
2814 HANDLE hProcess = 0;
2815
2816 seiW.lpVerb = lpVerb ? __SHCloneStrAtoW(&wVerb, lpVerb) : NULL;
2817 seiW.lpFile = lpFile ? __SHCloneStrAtoW(&wFile, lpFile) : NULL;
2818 seiW.lpParameters = lpParameters ? __SHCloneStrAtoW(&wParameters, lpParameters) : NULL;
2819 seiW.lpDirectory = lpDirectory ? __SHCloneStrAtoW(&wDirectory, lpDirectory) : NULL;
2820
2821 seiW.cbSize = sizeof(seiW);
2822 seiW.fMask = 0;
2823 seiW.hwnd = hWnd;
2824 seiW.nShow = iShowCmd;
2825 seiW.lpIDList = 0;
2826 seiW.lpClass = 0;
2827 seiW.hkeyClass = 0;
2828 seiW.dwHotKey = 0;
2829 seiW.hProcess = hProcess;
2830
2832
2833 SHFree(wVerb);
2834 SHFree(wFile);
2835 SHFree(wParameters);
2836 SHFree(wDirectory);
2837 return seiW.hInstApp;
2838}
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:71
static IPrintDialogCallback callback
Definition: printdlg.c:326
UINT_PTR(* SHELL_ExecuteW32)(const WCHAR *lpCmd, WCHAR *env, BOOL shWait, const SHELLEXECUTEINFOW *sei, LPSHELLEXECUTEINFOW sei_out)
Definition: shlexec.cpp:33