ReactOS 0.4.17-dev-683-g0dafdc5
shlexec.cpp File Reference
#include "precomp.h"
#include <winbase_undoc.h>
#include <undocshell.h>
Include dependency graph for shlexec.cpp:

Go to the source code of this file.

Classes

struct  _RUNASDLGDATA
 

Macros

#define SEE_MASK_CLASSALL   (SEE_MASK_CLASSNAME | SEE_MASK_CLASSKEY)
 

Typedefs

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

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (exec)
 
EXTERN_C BOOL PathIsExeW (LPCWSTR lpszPath)
 
static int Win32ErrFromHInst (HINSTANCE hInst)
 
static BOOL SHELL_InRunDllProcess (VOID)
 
static UINT_PTR InvokeOpenWith (HWND hWndOwner, SHELLEXECUTEINFOW &sei)
 
static HRESULT InvokeShellExecuteHook (PCWSTR pszClsid, LPSHELLEXECUTEINFOW pSEI)
 
static HRESULT TryShellExecuteHooks (LPSHELLEXECUTEINFOW pSEI)
 
static void ParseNoTildeEffect (PWSTR &res, LPCWSTR &args, DWORD &len, DWORD &used, int argNum)
 
static void ParseTildeEffect (PWSTR &res, LPCWSTR &args, DWORD &len, DWORD &used, int argNum)
 
static BOOL SHELL_ArgifyW (WCHAR *out, DWORD len, const WCHAR *fmt, const WCHAR *lpFile, LPITEMIDLIST pidl, LPCWSTR args, DWORD *out_len, const WCHAR *lpDir)
 
static HRESULT SHELL_GetPathFromIDListForExecuteW (LPCITEMIDLIST pidl, LPWSTR pszPath, UINT uOutSize)
 
static HWND SHELL_GetUsableDialogOwner (HWND hWnd)
 
static INT_PTR CALLBACK RunAsDlgProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 
static HRESULT PromptAndRunProcessAs (_In_opt_ HWND hwnd, _In_ LPWSTR Cmd, _In_ DWORD CreationFlags, _In_opt_ LPWSTR Env, _In_opt_ LPCWSTR Dir, _In_ STARTUPINFOW *pSI, _Out_ PROCESS_INFORMATION *pPI)
 
static UINT_PTR SHELL_ExecuteW (const WCHAR *lpCmd, WCHAR *env, BOOL shWait, const SHELLEXECUTEINFOW *psei, LPSHELLEXECUTEINFOW psei_out)
 
static LPWSTR SHELL_BuildEnvW (const WCHAR *path)
 
static BOOL SHELL_TryAppPathW (LPCWSTR szName, LPWSTR lpResult, WCHAR **env)
 
static UINT SHELL_FindExecutableByVerb (LPCWSTR lpVerb, LPWSTR key, LPWSTR classname, LPWSTR command, LONG commandlen)
 
static UINT SHELL_FindExecutable (LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpVerb, LPWSTR lpResult, DWORD resultLen, LPWSTR key, WCHAR **env, LPITEMIDLIST pidl, LPCWSTR args)
 
static HDDEDATA CALLBACK dde_cb (UINT uType, UINT uFmt, HCONV hConv, HSZ hsz1, HSZ hsz2, HDDEDATA hData, ULONG_PTR dwData1, ULONG_PTR dwData2)
 
static unsigned dde_connect (const WCHAR *key, const WCHAR *start, WCHAR *ddeexec, const WCHAR *lpFile, WCHAR *env, LPCWSTR szCommandline, LPITEMIDLIST pidl, SHELL_ExecuteW32 execfunc, const SHELLEXECUTEINFOW *psei, LPSHELLEXECUTEINFOW psei_out)
 
static UINT_PTR execute_from_key (LPCWSTR key, LPCWSTR lpFile, WCHAR *env, LPCWSTR szCommandline, LPCWSTR executable_name, SHELL_ExecuteW32 execfunc, LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out)
 
HINSTANCE WINAPI FindExecutableA (LPCSTR lpFile, LPCSTR lpDirectory, LPSTR lpResult)
 
HINSTANCE WINAPI FindExecutableW (LPCWSTR lpFile, LPCWSTR lpDirectory, LPWSTR lpResult)
 
static HKEY ShellExecute_GetClassKey (const SHELLEXECUTEINFOW *sei)
 
static HRESULT shellex_get_dataobj (LPSHELLEXECUTEINFOW sei, CComPtr< IDataObject > &dataObj)
 
static HRESULT shellex_run_context_menu_default (IShellExtInit *obj, LPSHELLEXECUTEINFOW sei)
 
static HRESULT shellex_load_object_and_run (HKEY hkey, LPCGUID guid, LPSHELLEXECUTEINFOW sei)
 
static HRESULT shellex_get_contextmenu (LPSHELLEXECUTEINFOW sei, CComPtr< IContextMenu > &cm)
 
static HRESULT ShellExecute_ContextMenuVerb (LPSHELLEXECUTEINFOW sei)
 
static LONG ShellExecute_FromContextMenuHandlers (LPSHELLEXECUTEINFOW sei)
 
static UINT_PTR SHELL_quote_and_execute (LPCWSTR wcmd, LPCWSTR wszParameters, LPCWSTR wszKeyname, LPCWSTR wszApplicationName, LPWSTR env, LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out, SHELL_ExecuteW32 execfunc)
 
static UINT_PTR SHELL_execute_class (LPCWSTR wszApplicationName, LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out, SHELL_ExecuteW32 execfunc)
 
static BOOL SHELL_translate_idlist (LPSHELLEXECUTEINFOW sei, LPWSTR wszParameters, DWORD parametersLen, LPWSTR wszApplicationName, DWORD dwApplicationNameLen)
 
static BOOL SHELL_InvokePidl (_In_ LPSHELLEXECUTEINFOW sei, _In_ LPCITEMIDLIST pidl)
 
static UINT_PTR SHELL_execute_url (LPCWSTR lpFile, LPCWSTR wcmd, LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out, SHELL_ExecuteW32 execfunc)
 
static void do_error_dialog (UINT_PTR retval, HWND hwnd, PCWSTR filename)
 
static UINT_PTR ExecuteFailed (UINT_PTR retval, SHELLEXECUTEINFOW &sei, LPCWSTR lpFile, BOOL AllowOpenWith=TRUE)
 
static 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
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(_expr)
Definition: assert.h:32
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2988
_ACRTIMP int __cdecl wcscmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:1977
return ret
Definition: mutex.c:147
#define L(x)
Definition: resources.c:13
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint start
Definition: gl.h:1545
GLuint res
Definition: glext.h:9613
GLfloat GLfloat p
Definition: glext.h:8902
static TfClientId tid
#define debugstr_w
Definition: kernel32.h:32
#define error(str)
Definition: mkdosfs.c:1605
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static PVOID ptr
Definition: dispmode.c:27
short WCHAR
Definition: pedump.c:58
long LONG
Definition: pedump.c:60
static const char topic[]
Definition: propsys.c:45
wcscpy
#define SE_ERR_NOASSOC
Definition: shellapi.h:135
static DWORD ddeInst
Definition: shlexec.c:147
static HSZ hszTopic
Definition: shlexec.c:148
static HDDEDATA CALLBACK dde_cb(UINT uType, UINT uFmt, HCONV hConv, HSZ hsz1, HSZ hsz2, HDDEDATA hData, ULONG_PTR dwData1, ULONG_PTR dwData2)
Definition: shlexec.cpp: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
const uint16_t * LPCWSTR
Definition: typedefs.h:57
unsigned char * LPBYTE
Definition: typedefs.h:53
uint16_t * LPWSTR
Definition: typedefs.h:56
char * LPSTR
Definition: typedefs.h:51
#define strchrW(s, c)
Definition: unicode.h:34
#define strlenW(s)
Definition: unicode.h:28
#define strrchrW(s, c)
Definition: unicode.h:35
#define strcpyW(d, s)
Definition: unicode.h:29
#define ERROR_DDE_FAIL
Definition: winerror.h:1002
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10

Referenced by execute_from_key().

◆ do_error_dialog()

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

Definition at line 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
#define msg(x)
Definition: auth_time.c:54
DWORD WINAPI FormatMessageW(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPWSTR lpBuffer, DWORD nSize, __ms_va_list *args)
Definition: format_msg.c:583
char * va_list
Definition: vadefs.h:50
const char * filename
Definition: ioapi.h:137
#define LoadStringW
Definition: utils.h:64
#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 ExecuteFailed(), and SHELL_execute().

◆ execute_from_key()

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

Definition at line 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:32

Referenced by SHELL_execute_url(), and SHELL_quote_and_execute().

◆ ExecuteFailed()

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

Definition at line 2188 of file shlexec.cpp.

2189{
2190 if (retval <= 32 && !(sei.fMask & SEE_MASK_FLAG_NO_UI))
2191 {
2192 if (retval == SE_ERR_NOASSOC && !(sei.fMask & SEE_MASK_CLASSALL) && AllowOpenWith)
2193 retval = InvokeOpenWith(sei.hwnd, sei);
2194 if (retval <= 32)
2195 do_error_dialog(retval, sei.hwnd, lpFile);
2196 }
2197 sei.hInstApp = (HINSTANCE)UlongToHandle(retval > 32 ? 33 : retval);
2198 return retval;
2199}
#define UlongToHandle(ul)
Definition: basetsd.h:91
#define SEE_MASK_FLAG_NO_UI
Definition: shellapi.h:38
static UINT_PTR InvokeOpenWith(HWND hWndOwner, SHELLEXECUTEINFOW &sei)
Definition: shlexec.cpp:86
static void do_error_dialog(UINT_PTR retval, HWND hwnd, PCWSTR filename)
Definition: shlexec.cpp:2167
#define SEE_MASK_CLASSALL
Definition: shlexec.cpp:31
HINSTANCE hInstApp
Definition: shellapi.h:342
HANDLE HINSTANCE
Definition: typedefs.h:77

Referenced by SHELL_execute().

◆ expand_environment()

static WCHAR * expand_environment ( const WCHAR str)
static

Definition at line 2201 of file shlexec.cpp.

2202{
2204 DWORD len;
2205
2207 if (!len) return NULL;
2208
2209 if (!buf.Allocate(len))
2210 return NULL;
2211
2213 if (!len)
2214 return NULL;
2215
2216 return buf.Detach();
2217}
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:492
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLsizei len
Definition: glext.h:6722
const WCHAR * str

Referenced by SHELL_execute().

◆ FindExecutableA()

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

Definition at line 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:227
_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:2168
DWORD WINAPI GetShortPathNameW(IN LPCWSTR lpszLongPath, OUT LPWSTR lpszShortPath, IN DWORD cchBuffer)
Definition: path.c:1752
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:569
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define UNICODE_NULL
@ ASSOCSTR_EXECUTABLE
Definition: shlwapi.h:887
@ ASSOCF_NONE
Definition: shlwapi.h:858
_In_ UINT _In_ UINT cch
Definition: shellapi.h: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)
HRESULT hr
Definition: delayimp.cpp:582
unsigned int UINT
Definition: sysinfo.c:13
#define SEE_MASK_NOCLOSEPROCESS
Definition: shellapi.h:33
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 ExecuteFailed().

◆ InvokeShellExecuteHook()

static HRESULT InvokeShellExecuteHook ( PCWSTR  pszClsid,
LPSHELLEXECUTEINFOW  pSEI 
)
static

Definition at line 99 of file shlexec.cpp.

100{
103 return S_FALSE;
106 return pWide->Execute(pSEI);
108#if 0 // TODO
111 {
113 // TODO: Convert the strings
114 hr = pAnsi->Execute(sei);
115 pSEI->hProcess = sei.hProcess;
116 pSEI->hInstApp = sei.hInstApp;
117 }
118#endif
119 return hr;
120}
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
#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 2864 of file shlexec.cpp.

2865{
2866 LPWSTR pszCmdLineW = NULL;
2867 TRACE("%p, %p, %s, %d\n", hwnd, hinst, debugstr_a(cmdline), cmdshow);
2868
2869 if (cmdline)
2870 __SHCloneStrAtoW(&pszCmdLineW, cmdline);
2871 OpenAs_RunDLLW(hwnd, hinst, pszCmdLineW, cmdshow);
2872 SHFree(pszCmdLineW);
2873}
#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:2853
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 2853 of file shlexec.cpp.

2854{
2856 TRACE("%p, %p, %s, %d\n", hwnd, hinst, debugstr_w(cmdline), cmdshow);
2858}
HRESULT WINAPI SHOpenWithDialog(HWND hwndParent, const OPENASINFO *poainfo)
@ OAIF_EXEC
Definition: shlobj.h:2700
@ OAIF_REGISTER_EXT
Definition: shlobj.h:2699
@ OAIF_ALLOW_REGISTRATION
Definition: shlobj.h:2698

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

3253{
3254 TRACE("%s, %p, %d, 0x%X\n", wine_dbgstr_w(pszSrc), pszDest, cchDest, dwFlags);
3255
3256 if (!pszSrc)
3257 return -1;
3258
3260 PCWSTR pchArg = NULL;
3261
3262 if (*pszSrc == L'"') // Quoted?
3263 {
3264 ++pszSrc;
3265
3266 PCWSTR pch = wcschr(pszSrc, L'"');
3267 if (pch)
3268 {
3269 szPath.SetString(pszSrc, pch - pszSrc);
3270 pchArg = pch + 1;
3271 }
3272 else
3273 {
3274 szPath = pszSrc;
3275 }
3276
3278 {
3280 szPath.ReleaseBuffer();
3281 if (!ret)
3282 return -1;
3283 }
3284 }
3285 else // Not quoted?
3286 {
3287 BOOL resolved = FALSE;
3288 BOOL resolveRelative = PathIsRelativeW(pszSrc) || (dwFlags & PPCF_FORCEQUALIFY);
3289 INT cchPath = 0;
3290
3291 for (INT ich = 0; ; ++ich)
3292 {
3293 szPath += pszSrc[ich];
3294
3295 if (pszSrc[ich] && pszSrc[ich] != L' ')
3296 continue;
3297
3298 szPath = szPath.Left(ich);
3299
3300 if (resolveRelative &&
3302 {
3303 szPath.ReleaseBuffer();
3304 szPath += pszSrc[ich];
3305 }
3306 else
3307 {
3308 szPath.ReleaseBuffer();
3309
3311 if (attrs != INVALID_FILE_ATTRIBUTES &&
3313 {
3314 resolved = TRUE;
3315 pchArg = pszSrc + ich;
3316
3318 break;
3319
3320 cchPath = ich;
3321 break;
3322 }
3323 else if (!resolveRelative)
3324 {
3325 szPath += pszSrc[ich];
3326 }
3327 }
3328
3329 if (!szPath[ich])
3330 {
3331 szPath.ReleaseBuffer(); // Remove excessive '\0'
3332 break;
3333 }
3334 }
3335
3336 if (!resolved)
3337 return -1;
3338
3339 if (cchPath && (dwFlags & PPCF_LONGESTPOSSIBLE))
3340 {
3341 szPath = szPath.Left(cchPath);
3342 pchArg = pszSrc + cchPath;
3343 }
3344 }
3345
3346 BOOL needsQuoting = (dwFlags & PPCF_ADDQUOTES) && wcschr(szPath, L' ');
3347 CStringW result = needsQuoting ? (L"\"" + szPath + L"\"") : szPath;
3348
3349 if (pchArg && (dwFlags & PPCF_ADDARGUMENTS))
3350 result += pchArg;
3351
3352 LONG requiredSize = result.GetLength() + 1;
3353 if (!pszDest)
3354 return requiredSize;
3355
3356 if (requiredSize > cchDest || StringCchCopyW(pszDest, cchDest, result) != S_OK)
3357 return -1;
3358
3359 return requiredSize;
3360}
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:636
BOOL WINAPI PathIsRelativeW(const WCHAR *path)
Definition: path.c:1006
GLuint64EXT * result
Definition: glext.h:11304
#define S_OK
Definition: intsafe.h:52
#define wine_dbgstr_w
Definition: kernel32.h:34
#define pch(ap)
Definition: match.c:418
LPCWSTR szPath
Definition: env.c:37
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
_In_ INT cchDest
Definition: shlwapi.h:1161
#define PPCF_FORCEQUALIFY
Definition: shlobj.h:2439
#define PPCF_LONGESTPOSSIBLE
Definition: shlobj.h:2440
#define PPCF_ADDQUOTES
Definition: shlobj.h:2434
#define PPCF_ADDARGUMENTS
Definition: shlobj.h:2436
#define PPCF_NODIRECTORIES
Definition: shlobj.h:2437
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:4441
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:1443
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 3186 of file shlexec.cpp.

3197{
3199 lpOperation,
3200 lpFile,
3201 lpParameters,
3203 lpReturn,
3204 lpTitle,
3205 lpReserved,
3206 nCmdShow,
3207 lphProcess,
3208 0);
3209}
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:3052
_In_ DWORD _In_ int _In_ int _In_opt_ LPNLSVERSIONINFO _In_opt_ LPVOID lpReserved
Definition: winnls.h:1279

◆ RealShellExecuteExA()

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

Definition at line 3052 of file shlexec.cpp.

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

Referenced by RealShellExecuteA().

◆ RealShellExecuteExW()

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

Definition at line 3119 of file shlexec.cpp.

3131{
3132 SHELLEXECUTEINFOW ExecInfo;
3133
3134 TRACE("(%p, %s, %s, %s, %s, %p, %s, %p, %u, %p, %lu)\n",
3135 hwnd, debugstr_w(lpOperation), debugstr_w(lpFile), debugstr_w(lpParameters),
3137 lpReserved, nCmdShow, lphProcess, dwFlags);
3138
3139 ZeroMemory(&ExecInfo, sizeof(ExecInfo));
3140 ExecInfo.cbSize = sizeof(ExecInfo);
3142 ExecInfo.hwnd = hwnd;
3143 ExecInfo.lpVerb = lpOperation;
3144 ExecInfo.lpFile = lpFile;
3145 ExecInfo.lpParameters = lpParameters;
3146 ExecInfo.lpDirectory = lpDirectory;
3147 ExecInfo.nShow = (WORD)nCmdShow;
3148
3149 if (lpReserved)
3150 {
3151 ExecInfo.fMask |= SEE_MASK_USE_RESERVED;
3152 ExecInfo.hInstApp = (HINSTANCE)lpReserved;
3153 }
3154
3155 if (lpTitle)
3156 {
3157 ExecInfo.fMask |= SEE_MASK_HASTITLE;
3158 ExecInfo.lpClass = lpTitle;
3159 }
3160
3161 if (dwFlags & 1)
3162 ExecInfo.fMask |= SEE_MASK_FLAG_SEPVDM;
3163
3164 if (dwFlags & 2)
3165 ExecInfo.fMask |= SEE_MASK_NO_CONSOLE;
3166
3167 if (lphProcess == NULL)
3168 {
3169 ShellExecuteExW(&ExecInfo);
3170 }
3171 else
3172 {
3173 ExecInfo.fMask |= SEE_MASK_NOCLOSEPROCESS;
3174 ShellExecuteExW(&ExecInfo);
3175 *lphProcess = ExecInfo.hProcess;
3176 }
3177
3178 return ExecInfo.hInstApp;
3179}
BOOL WINAPI DECLSPEC_HOTPATCH ShellExecuteExW(LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:2732
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 3216 of file shlexec.cpp.

3227{
3229 lpOperation,
3230 lpFile,
3231 lpParameters,
3233 lpReturn,
3234 lpTitle,
3235 lpReserved,
3236 nCmdShow,
3237 lphProcess,
3238 0);
3239}
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:3119

◆ RunAsDlgProc()

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

Definition at line 596 of file shlexec.cpp.

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

Referenced by PromptAndRunProcessAs().

◆ SHELL_ArgifyW()

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

Definition at line 299 of file shlexec.cpp.

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

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

◆ SHELL_BuildEnvW()

static LPWSTR SHELL_BuildEnvW ( const WCHAR path)
static

Definition at line 848 of file shlexec.cpp.

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

Referenced by SHELL_TryAppPathW().

◆ SHELL_execute()

static BOOL SHELL_execute ( LPSHELLEXECUTEINFOW  sei,
SHELL_ExecuteW32  execfunc 
)
static

Definition at line 2222 of file shlexec.cpp.

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

Referenced by ShellExecute_Normal(), and WOWShellExecute().

◆ SHELL_execute_class()

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

Definition at line 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:224
#define SEE_MASK_CLASSKEY
Definition: shellapi.h:26
static UINT SHELL_FindExecutableByVerb(LPCWSTR lpVerb, LPWSTR key, LPWSTR classname, LPWSTR command, LONG commandlen)
Definition: shlexec.cpp:966
uint32_t ULONG
Definition: typedefs.h:59

Referenced by SHELL_execute().

◆ SHELL_execute_url()

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

Definition at line 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:464
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:737
#define STARTF_USESHOWWINDOW
Definition: winbase.h:468
#define CREATE_UNICODE_ENVIRONMENT
Definition: winbase.h:191
#define CREATE_SEPARATE_WOW_VDM
Definition: winbase.h:192
#define WAIT_FAILED
Definition: winbase.h:390
#define CREATE_NEW_CONSOLE
Definition: winbase.h:185
#define ERROR_BAD_FORMAT
Definition: winerror.h:236
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:1886
LPWSTR WINAPI CharLowerW(WCHAR *str)
Definition: string.c:1136
_ACRTIMP int __cdecl _wcsicmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:164
BOOL WINAPI PathFindOnPathW(LPWSTR lpszFile, LPCWSTR *lppszOtherDirs)
Definition: path.c:456
const GLint * attribs
Definition: glext.h:10538
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static BOOL SHELL_TryAppPathW(LPCWSTR szName, LPWSTR lpResult, WCHAR **env)
Definition: shlexec.cpp:906

Referenced by SHELL_execute(), and shellex_get_contextmenu().

◆ SHELL_FindExecutableByVerb()

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

Definition at line 966 of file shlexec.cpp.

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

Referenced by SHELL_execute_class(), and SHELL_FindExecutable().

◆ SHELL_GetPathFromIDListForExecuteW()

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

Definition at line 551 of file shlexec.cpp.

552{
553 STRRET strret;
554 CComPtr<IShellFolder> desktop;
555
556 HRESULT hr = SHGetDesktopFolder(&desktop);
557
558 if (SUCCEEDED(hr))
559 {
560 hr = desktop->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &strret);
561
562 if (SUCCEEDED(hr))
563 StrRetToStrNW(pszPath, uOutSize, &strret, pidl);
564 }
565
566 return hr;
567}
HRESULT WINAPI SHGetDesktopFolder(IShellFolder **psf)
BOOL WINAPI StrRetToStrNW(LPWSTR dest, DWORD len, LPSTRRET src, const ITEMIDLIST *pidl)
Definition: shellstring.c:85

Referenced by SHELL_translate_idlist().

◆ SHELL_GetUsableDialogOwner()

static HWND SHELL_GetUsableDialogOwner ( HWND  hWnd)
static

Definition at line 569 of file shlexec.cpp.

570{
571 // Explicitly block the shell desktop listview from becoming the owner (IContextMenu calling ShellExecute)
572 HWND hProgman = GetShellWindow();
574 hWnd != hProgman && !IsChild(hProgman, hWnd))
575 {
576 return hWnd;
577 }
578 return NULL;
579}
HWND hWnd
Definition: settings.c:17
HWND WINAPI 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:1677

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:135
#define FAILED_UNEXPECTEDLY
Definition: utils.cpp:33
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:60
#define ANSI_NULL
HRESULT WINAPI SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCITEMIDLIST *ppidlLast)
Definition: pidl.c:1504
HMENU WINAPI CreatePopupMenu(void)
Definition: menu.c:838
UINT WINAPI GetMenuDefaultItem(_In_ HMENU hMenu, _In_ UINT fByPos, _In_ UINT gmdiFlags)
#define MAKEINTRESOURCEA(i)
Definition: winuser.h:581
BOOL WINAPI DestroyMenu(_In_ HMENU)
#define IID_NULL_PPV_ARG(Itype, ppType)

Referenced by SHELL_execute().

◆ SHELL_quote_and_execute()

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

Definition at line 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:428
LPITEMIDLIST WINAPI ILCreateFromPathW(LPCWSTR path)
Definition: pidl.c:1108

Referenced by shellex_load_object_and_run().

◆ shellex_load_object_and_run()

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

Definition at line 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}
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, IUnknown *outer, DWORD cls_context, REFIID riid, void **obj)
Definition: combase.c:1685
GUID guid
Definition: version.c:147
#define debugstr_guid
Definition: kernel32.h:35
static HRESULT shellex_run_context_menu_default(IShellExtInit *obj, LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp: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:4171
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLdouble n
Definition: glext.h:7729
static HMENU hmenu
Definition: win.c:78
#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 3364 of file shlexec.cpp.

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

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

3427{
3428 CStringW strCmdLine = pszCmdLine; // Keep
3429 ShellExec_RunDLL_Helper(hwnd, hInstance, strCmdLine, nCmdShow);
3430}
static VOID ShellExec_RunDLL_Helper(_In_opt_ HWND hwnd, _In_opt_ HINSTANCE hInstance, _In_ PCWSTR pszCmdLine, _In_ INT nCmdShow)
Definition: shlexec.cpp:3364

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

3444{
3445 ShellExec_RunDLL_Helper(hwnd, hInstance, pszCmdLine, nCmdShow);
3446}

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

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

◆ ShellExecute_ContextMenuVerb()

static HRESULT ShellExecute_ContextMenuVerb ( LPSHELLEXECUTEINFOW  sei)
static

Definition at line 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
1836
1837 BOOL fDefault = StrIsNullOrEmpty(sei->lpVerb);
1838 CMINVOKECOMMANDINFOEX ici = { sizeof(ici) };
1839 ici.fMask = SeeFlagsToCmicFlags(sei->fMask) | CMIC_MASK_UNICODE;
1840 ici.nShow = sei->nShow;
1841 if (!fDefault)
1842 {
1843 __SHCloneStrWtoA(&verb, sei->lpVerb);
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 BYTE parameters[]
Definition: asn.c:558
static __inline void __SHCloneStrWtoA(char **target, const WCHAR *source)
Definition: shell32_main.h:214
static HRESULT shellex_get_contextmenu(LPSHELLEXECUTEINFOW sei, CComPtr< IContextMenu > &cm)
Definition: shlexec.cpp: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 str, LPCLSID clsid)
Definition: combase.c:1470
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:1250
FxAutoRegKey hKey
HRESULT HCR_GetProgIdKeyOfExtension(PCWSTR szExtension, PHKEY phKey, BOOL AllowFallback)
Definition: classes.c:55

Referenced by ShellExecute_FromContextMenuHandlers().

◆ ShellExecute_Normal()

static DWORD ShellExecute_Normal ( _Inout_ LPSHELLEXECUTEINFOW  sei)
static

Definition at line 2646 of file shlexec.cpp.

2647{
2648 // FIXME
2649 if (SHELL_execute(sei, SHELL_ExecuteW))
2650 return ERROR_SUCCESS;
2652#if DBG
2653 if (!err)
2654 DbgPrint("FIXME: Failed with error 0 on '%ls'\n", sei->lpFile);
2655#endif
2656 return err ? err : ERROR_FILE_NOT_FOUND;
2657}
#define DbgPrint
Definition: hal.h:12
static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
Definition: shlexec.cpp:2222
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 2660 of file shlexec.cpp.

2664{
2665 // FIXME: Show error message
2666}

Referenced by ShellExecuteExW().

◆ ShellExecuteA()

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

Definition at line 2616 of file shlexec.cpp.

2618{
2620
2621 TRACE("%p,%s,%s,%s,%s,%d\n",
2622 hWnd, debugstr_a(lpVerb), debugstr_a(lpFile),
2623 debugstr_a(lpParameters), debugstr_a(lpDirectory), iShowCmd);
2624
2625 sei.cbSize = sizeof(sei);
2627 sei.hwnd = hWnd;
2628 sei.lpVerb = lpVerb;
2629 sei.lpFile = lpFile;
2630 sei.lpParameters = lpParameters;
2632 sei.nShow = iShowCmd;
2633 sei.lpIDList = 0;
2634 sei.lpClass = 0;
2635 sei.hkeyClass = 0;
2636 sei.dwHotKey = 0;
2637 sei.hProcess = 0;
2638
2640 sei.fMask |= SEE_MASK_NOASYNC;
2641 ShellExecuteExA(&sei);
2642 return sei.hInstApp;
2643}
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 2674 of file shlexec.cpp.

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

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

◆ ShellExecuteExW()

Definition at line 2732 of file shlexec.cpp.

2733{
2734 HRESULT hrCoInit;
2735 DWORD dwError;
2736 ULONG fOldMask;
2737
2738 if (sei->cbSize != sizeof(SHELLEXECUTEINFOW))
2739 {
2742 return FALSE;
2743 }
2744
2745 hrCoInit = SHCoInitializeAnyApartment();
2746
2747 if (SHRegGetBoolUSValueW(L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer",
2748 L"MaximizeApps", FALSE, FALSE))
2749 {
2750 switch (sei->nShow)
2751 {
2752 case SW_SHOW:
2753 case SW_SHOWDEFAULT:
2754 case SW_SHOWNORMAL:
2755 case SW_RESTORE:
2756 sei->nShow = SW_SHOWMAXIMIZED;
2757 break;
2758 default:
2759 break;
2760 }
2761 }
2762
2763 fOldMask = sei->fMask;
2764
2765 if (!(fOldMask & SEE_MASK_NOASYNC) && SHELL_InRunDllProcess())
2767
2768 dwError = ShellExecute_Normal(sei);
2769
2770 if (dwError && dwError != ERROR_DLL_NOT_FOUND && dwError != ERROR_CANCELLED)
2771 ShellExecute_ShowError(sei, NULL, dwError);
2772
2773 sei->fMask = fOldMask;
2774
2775 if (SUCCEEDED(hrCoInit))
2777
2778 if (dwError)
2779 SetLastError(dwError);
2780
2781 return dwError == ERROR_SUCCESS;
2782}
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: combase.c:2842
BOOL WINAPI SHRegGetBoolUSValueW(const WCHAR *subkey, const WCHAR *value, BOOL ignore_hkcu, BOOL default_value)
Definition: registry.c:4139
HRESULT SHCoInitializeAnyApartment(VOID)
Definition: utils.cpp:542
#define 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:2646
static VOID ShellExecute_ShowError(_In_ const SHELLEXECUTEINFOW *ExecInfo, _In_opt_ LPCWSTR pszCaption, _In_ DWORD dwError)
Definition: shlexec.cpp:2660
#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(), CFontBackgroundMenu::InvokeCommand(), BtrfsContextMenu::InvokeCommand(), CISFBand::InvokeCommand(), CDefaultContextMenu::InvokePidl(), LanguagesPageProc(), COpenControlPanel::Open(), BtrfsPropSheet::open_as_admin(), BtrfsBalance::PauseBalance(), CDownloadManager::PerformDownloadAndInstall(), ProcessPage_OnProperties(), RealShellExecuteExW(), BtrfsVolPropSheet::ResetStats(), RunDlgProc(), RunFontViewer(), SH32_InvokeOpenWith(), SHELL_OpenFolder(), ShellExec_RunDLL_Helper(), ShellExecCmdLine(), ShellExecuteCommand(), ShellExecuteExA(), ShellExecuteExWrapW(), ShellExecuteVerb(), ShellExecuteW(), SHObjectProperties(), SHOpenFolderAndSelectItems(), BtrfsVolPropSheet::ShowChangeDriveLetter(), CTrayWindow::ShowFolder(), CRecycleBinCleaner::ShowProperties(), BtrfsVolPropSheet::ShowScrub(), BtrfsBalance::StartBalance(), BtrfsBalance::StopBalance(), test_DoInvalidDir(), TEST_DoTestEntryStruct(), Test_InvokeIdList(), test_properties(), test_sei_lpIDList(), try_application_url(), UniformResourceLocatorW_InvokeCommand(), wmain(), and WshShell3_Run().

◆ ShellExecuteW()

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

Definition at line 2787 of file shlexec.cpp.

2789{
2791
2792 TRACE("\n");
2793 sei.cbSize = sizeof(sei);
2795 sei.hwnd = hwnd;
2796 sei.lpVerb = lpVerb;
2797 sei.lpFile = lpFile;
2798 sei.lpParameters = lpParameters;
2800 sei.nShow = nShowCmd;
2801 sei.lpIDList = 0;
2802 sei.lpClass = 0;
2803 sei.hkeyClass = 0;
2804 sei.dwHotKey = 0;
2805 sei.hProcess = 0;
2806
2808 sei.fMask |= SEE_MASK_NOASYNC;
2809 ShellExecuteExW(&sei);
2810 return sei.hInstApp;
2811}

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

◆ SplitParams()

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

Definition at line 2878 of file shlexec.cpp.

2879{
2880 LPCWSTR pch;
2881 size_t ich = 0;
2882 if (*psz == L'"')
2883 {
2884 // 1st argument is quoted. the string in quotes is quoted 1st argument.
2885 // [pch] --> [pszArg0+ich]
2886 for (pch = psz + 1; *pch && ich + 1 < cchArg0; ++ich, ++pch)
2887 {
2888 if (*pch == L'"' && pch[1] == L'"')
2889 {
2890 // doubled double quotations found!
2891 pszArg0[ich] = L'"';
2892 }
2893 else if (*pch == L'"')
2894 {
2895 // single double quotation found!
2896 ++pch;
2897 break;
2898 }
2899 else
2900 {
2901 // otherwise
2902 pszArg0[ich] = *pch;
2903 }
2904 }
2905 }
2906 else
2907 {
2908 // 1st argument is unquoted. non-space sequence is 1st argument.
2909 // [pch] --> [pszArg0+ich]
2910 for (pch = psz; *pch && !iswspace(*pch) && ich + 1 < cchArg0; ++ich, ++pch)
2911 {
2912 pszArg0[ich] = *pch;
2913 }
2914 }
2915 pszArg0[ich] = 0;
2916
2917 // skip space
2918 while (iswspace(*pch))
2919 ++pch;
2920
2921 return pch;
2922}
#define iswspace(_c)
Definition: ctype.h:669

Referenced by ShellExecCmdLine().

◆ TryShellExecuteHooks()

static HRESULT TryShellExecuteHooks ( LPSHELLEXECUTEINFOW  pSEI)
static

Definition at line 122 of file shlexec.cpp.

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

Referenced by SHELL_execute().

◆ Win32ErrFromHInst()

static int Win32ErrFromHInst ( HINSTANCE  hInst)
static

Definition at line 36 of file shlexec.cpp.

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

Referenced by SHELL_execute().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( exec  )

◆ WOWShellExecute()

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

Definition at line 2818 of file shlexec.cpp.

2820{
2821 SHELLEXECUTEINFOW seiW;
2822 WCHAR *wVerb = NULL, *wFile = NULL, *wParameters = NULL, *wDirectory = NULL;
2823 HANDLE hProcess = 0;
2824
2825 seiW.lpVerb = lpVerb ? __SHCloneStrAtoW(&wVerb, lpVerb) : NULL;
2826 seiW.lpFile = lpFile ? __SHCloneStrAtoW(&wFile, lpFile) : NULL;
2827 seiW.lpParameters = lpParameters ? __SHCloneStrAtoW(&wParameters, lpParameters) : NULL;
2828 seiW.lpDirectory = lpDirectory ? __SHCloneStrAtoW(&wDirectory, lpDirectory) : NULL;
2829
2830 seiW.cbSize = sizeof(seiW);
2831 seiW.fMask = 0;
2832 seiW.hwnd = hWnd;
2833 seiW.nShow = iShowCmd;
2834 seiW.lpIDList = 0;
2835 seiW.lpClass = 0;
2836 seiW.hkeyClass = 0;
2837 seiW.dwHotKey = 0;
2838 seiW.hProcess = hProcess;
2839
2841
2842 SHFree(wVerb);
2843 SHFree(wFile);
2844 SHFree(wParameters);
2845 SHFree(wDirectory);
2846 return seiW.hInstApp;
2847}
_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