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

Go to the source code of this file.

Macros

#define SEE_MASK_CLASSALL   (SEE_MASK_CLASSNAME | SEE_MASK_CLASSKEY)
 

Typedefs

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

Functions

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

Typedef Documentation

◆ SHELL_ExecuteW32

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

Definition at line 32 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 959 of file shlexec.cpp.

962{
963 TRACE("dde_cb: %04x, %04x, %p, %p, %p, %p, %08lx, %08lx\n",
964 uType, uFmt, hConv, hsz1, hsz2, hData, dwData1, dwData2);
965 return NULL;
966}
#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 977 of file shlexec.cpp.

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

Referenced by execute_from_key().

◆ do_error_dialog()

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

Definition at line 1900 of file shlexec.cpp.

1901{
1902 WCHAR msg[2048];
1903 DWORD_PTR msgArguments[3] = { (DWORD_PTR)filename, 0, 0 };
1905
1907 if (retval == SE_ERR_NOASSOC)
1909 else
1911 NULL,
1912 error_code,
1914 msg,
1915 ARRAY_SIZE(msg),
1916 (va_list*)msgArguments);
1917
1919}
#define shell32_hInstance
char * va_list
Definition: acmsvcex.h:78
#define msg(x)
Definition: auth_time.c:54
DWORD WINAPI FormatMessageW(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPWSTR lpBuffer, DWORD nSize, __ms_va_list *args)
Definition: format_msg.c:583
const char * filename
Definition: ioapi.h:137
#define IDS_SHLEXEC_NOASSOC
Definition: shresdef.h:187
#define LANG_USER_DEFAULT
Definition: tnerror.cpp:50
#define DWORD_PTR
Definition: treelist.c:76
uint32_t DWORD_PTR
Definition: typedefs.h:65
int retval
Definition: wcstombs.cpp:91
static int error_code[8]
Definition: odbccp32.c:61
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define FORMAT_MESSAGE_FROM_SYSTEM
Definition: winbase.h:449
#define FORMAT_MESSAGE_ARGUMENT_ARRAY
Definition: winbase.h:450
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
int WINAPI MessageBoxW(_In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType)
#define MB_ICONERROR
Definition: winuser.h:790

Referenced by SHELL_execute().

◆ execute_from_key()

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

Definition at line 1186 of file shlexec.cpp.

1190{
1191 WCHAR cmd[256], param[1024], ddeexec[256];
1192 DWORD cmdlen = sizeof(cmd), ddeexeclen = sizeof(ddeexec);
1194 DWORD resultLen;
1195 LPWSTR tmp;
1196
1197 TRACE("%s %s %s %s %s\n", debugstr_w(key), debugstr_w(lpFile), debugstr_w(env),
1198 debugstr_w(szCommandline), debugstr_w(executable_name));
1199
1200 cmd[0] = '\0';
1201 param[0] = '\0';
1202
1203 /* Get the application from the registry */
1205 {
1206 TRACE("got cmd: %s\n", debugstr_w(cmd));
1207
1208 /* Is there a replace() function anywhere? */
1209 cmdlen /= sizeof(WCHAR);
1210 if (cmdlen >= ARRAY_SIZE(cmd))
1211 cmdlen = ARRAY_SIZE(cmd) - 1;
1212 cmd[cmdlen] = '\0';
1213 SHELL_ArgifyW(param, ARRAY_SIZE(param), cmd, lpFile, (LPITEMIDLIST)psei->lpIDList, szCommandline, &resultLen,
1214 (psei->lpDirectory && *psei->lpDirectory) ? psei->lpDirectory : NULL);
1215 if (resultLen > ARRAY_SIZE(param))
1216 ERR("Argify buffer not large enough, truncating\n");
1217 }
1218
1219 /* Get the parameters needed by the application
1220 from the associated ddeexec key */
1221 tmp = const_cast<LPWSTR>(strstrW(key, L"command"));
1222 assert(tmp);
1223 wcscpy(tmp, L"ddeexec");
1224
1225 if (RegQueryValueW(HKEY_CLASSES_ROOT, key, ddeexec, (LONG *)&ddeexeclen) == ERROR_SUCCESS)
1226 {
1227 TRACE("Got ddeexec %s => %s\n", debugstr_w(key), debugstr_w(ddeexec));
1228 if (!param[0]) strcpyW(param, executable_name);
1229 retval = dde_connect(key, param, ddeexec, lpFile, env, szCommandline, (LPITEMIDLIST)psei->lpIDList, execfunc, psei, psei_out);
1230 }
1231 else if (param[0])
1232 {
1233 TRACE("executing: %s\n", debugstr_w(param));
1234 retval = execfunc(param, env, FALSE, psei, psei_out);
1235 }
1236 else
1237 WARN("Nothing appropriate found for %s\n", debugstr_w(key));
1238
1239 return retval;
1240}
#define FALSE
Definition: types.h:117
GLfloat param
Definition: glext.h:5796
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
#define strstrW(d, s)
Definition: unicode.h:38
static unsigned dde_connect(const WCHAR *key, const WCHAR *start, WCHAR *ddeexec, const WCHAR *lpFile, WCHAR *env, LPCWSTR szCommandline, LPITEMIDLIST pidl, SHELL_ExecuteW32 execfunc, const SHELLEXECUTEINFOW *psei, LPSHELLEXECUTEINFOW psei_out)
Definition: shlexec.cpp:977
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
LPCWSTR lpDirectory
Definition: shellapi.h:335
Definition: ftp_var.h:139

Referenced by SHELL_execute_url(), and SHELL_quote_and_execute().

◆ expand_environment()

static WCHAR * expand_environment ( const WCHAR str)
static

Definition at line 1921 of file shlexec.cpp.

1922{
1924 DWORD len;
1925
1927 if (!len) return NULL;
1928
1929 if (!buf.Allocate(len))
1930 return NULL;
1931
1933 if (!len)
1934 return NULL;
1935
1936 return buf.Detach();
1937}
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:519
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLsizei len
Definition: glext.h:6722
const WCHAR * str

Referenced by SHELL_execute().

◆ FindExecutableA()

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

Definition at line 1245 of file shlexec.cpp.

1246{
1248 WCHAR *wFile = NULL, *wDirectory = NULL;
1249 WCHAR wResult[MAX_PATH];
1250
1251 if (lpFile) __SHCloneStrAtoW(&wFile, lpFile);
1252 if (lpDirectory) __SHCloneStrAtoW(&wDirectory, lpDirectory);
1253
1254 retval = FindExecutableW(wFile, wDirectory, wResult);
1255 WideCharToMultiByte(CP_ACP, 0, wResult, -1, lpResult, MAX_PATH, NULL, NULL);
1256 SHFree(wFile);
1257 SHFree(wDirectory);
1258
1259 TRACE("returning %s\n", lpResult);
1260 return retval;
1261}
void WINAPI SHFree(LPVOID pv)
Definition: shellole.c:326
static __inline LPWSTR __SHCloneStrAtoW(WCHAR **target, const char *source)
Definition: shell32_main.h:178
_In_opt_ LPCSTR lpDirectory
Definition: shellapi.h:485
HINSTANCE WINAPI FindExecutableW(LPCWSTR lpFile, LPCWSTR lpDirectory, LPWSTR lpResult)
Definition: shlexec.cpp:1288

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

◆ FindExecutableW()

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

Definition at line 1288 of file shlexec.cpp.

1289{
1291 WCHAR old_dir[MAX_PATH], res[MAX_PATH];
1292 DWORD cch = _countof(res);
1293 LPCWSTR dirs[2];
1294
1295 TRACE("File %s, Dir %s\n", debugstr_w(lpFile), debugstr_w(lpDirectory));
1296
1297 *lpResult = UNICODE_NULL;
1298
1299 GetCurrentDirectoryW(_countof(old_dir), old_dir);
1300
1301 if (lpDirectory && *lpDirectory)
1302 {
1304 dirs[0] = lpDirectory;
1305 }
1306 else
1307 {
1308 dirs[0] = old_dir;
1309 }
1310 dirs[1] = NULL;
1311
1312 if (!GetShortPathNameW(lpFile, res, _countof(res)))
1313 StringCchCopyW(res, _countof(res), lpFile);
1314
1316 {
1317 // NOTE: The last parameter of this AssocQueryStringW call is "strange" in Windows.
1318 if (PathIsExeW(res) ||
1320 {
1321 StringCchCopyW(lpResult, MAX_PATH, res);
1322 retval = 42;
1323 }
1324 else
1325 {
1327 }
1328 }
1329 else
1330 {
1332 }
1333
1334 TRACE("returning %s\n", debugstr_w(lpResult));
1335 SetCurrentDirectoryW(old_dir);
1336 return (HINSTANCE)retval;
1337}
#define PRF_TRYPROGRAMEXTENSIONS
Definition: PathResolve.cpp:40
#define PRF_FIRSTDIRDEF
Definition: PathResolve.cpp:41
#define GetCurrentDirectoryW(x, y)
Definition: compat.h:756
BOOL WINAPI SetCurrentDirectoryW(IN LPCWSTR lpPathName)
Definition: path.c:2249
DWORD WINAPI GetShortPathNameW(IN LPCWSTR lpszLongPath, OUT LPWSTR lpszShortPath, IN DWORD cchBuffer)
Definition: path.c:1833
BOOL WINAPI PathResolveW(_Inout_ LPWSTR path, _Inout_opt_ LPCWSTR *dirs, _In_ DWORD flags)
Definition: shellpath.c:883
HRESULT WINAPI AssocQueryStringW(ASSOCF cfFlags, ASSOCSTR str, LPCWSTR pszAssoc, LPCWSTR pszExtra, LPWSTR pszOut, DWORD *pcchOut)
Definition: assoc.c:436
#define SUCCEEDED(hr)
Definition: intsafe.h:50
static DWORD DWORD void LPSTR DWORD cch
Definition: str.c:202
#define UNICODE_NULL
#define SE_ERR_FNF
Definition: shellapi.h:126
EXTERN_C BOOL PathIsExeW(LPCWSTR lpszPath)
Definition: shellpath.c:539
@ ASSOCSTR_EXECUTABLE
Definition: shlwapi.h:613
@ ASSOCF_NONE
Definition: shlwapi.h:590
#define _countof(array)
Definition: sndvol32.h:70
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149

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

◆ OpenAs_RunDLLA()

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

Definition at line 2590 of file shlexec.cpp.

2591{
2592 LPWSTR pszCmdLineW = NULL;
2593 TRACE("%p, %p, %s, %d\n", hwnd, hinst, debugstr_a(cmdline), cmdshow);
2594
2595 if (cmdline)
2596 __SHCloneStrAtoW(&pszCmdLineW, cmdline);
2597 OpenAs_RunDLLW(hwnd, hinst, pszCmdLineW, cmdshow);
2598 SHFree(pszCmdLineW);
2599}
#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:2573
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 2573 of file shlexec.cpp.

2574{
2576 TRACE("%p, %p, %s, %d\n", hwnd, hinst, debugstr_w(cmdline), cmdshow);
2577
2578 ZeroMemory(&info, sizeof(info));
2579 info.pcszFile = cmdline;
2580 info.pcszClass = NULL;
2582
2584}
HRESULT WINAPI SHOpenWithDialog(HWND hwndParent, const OPENASINFO *poainfo)
@ OAIF_EXEC
Definition: shlobj.h:2682
@ OAIF_REGISTER_EXT
Definition: shlobj.h:2681
@ OAIF_ALLOW_REGISTRATION
Definition: shlobj.h:2680
#define ZeroMemory
Definition: winbase.h:1737

Referenced by OpenAs_RunDLLA().

◆ ParseNoTildeEffect()

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

Definition at line 49 of file shlexec.cpp.

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

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

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().

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

2935{
2937 lpOperation,
2938 lpFile,
2939 lpParameters,
2941 lpReturn,
2942 lpTitle,
2943 lpReserved,
2944 nCmdShow,
2945 lphProcess,
2946 0);
2947}
static DWORD const LPVOID const lpReserved
TCHAR lpTitle[80]
Definition: ctm.c:69
EXTERN_C HINSTANCE WINAPI RealShellExecuteExA(_In_opt_ HWND hwnd, _In_opt_ LPCSTR lpOperation, _In_opt_ LPCSTR lpFile, _In_opt_ LPCSTR lpParameters, _In_opt_ LPCSTR lpDirectory, _In_opt_ LPSTR lpReturn, _In_opt_ LPCSTR lpTitle, _In_opt_ LPVOID lpReserved, _In_ INT nCmdShow, _Out_opt_ PHANDLE lphProcess, _In_ DWORD dwFlags)
Definition: shlexec.cpp:2790

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

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

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

2869{
2870 SHELLEXECUTEINFOW ExecInfo;
2871
2872 TRACE("(%p, %s, %s, %s, %s, %p, %s, %p, %u, %p, %lu)\n",
2873 hwnd, debugstr_w(lpOperation), debugstr_w(lpFile), debugstr_w(lpParameters),
2875 lpReserved, nCmdShow, lphProcess, dwFlags);
2876
2877 ZeroMemory(&ExecInfo, sizeof(ExecInfo));
2878 ExecInfo.cbSize = sizeof(ExecInfo);
2880 ExecInfo.hwnd = hwnd;
2881 ExecInfo.lpVerb = lpOperation;
2882 ExecInfo.lpFile = lpFile;
2883 ExecInfo.lpParameters = lpParameters;
2884 ExecInfo.lpDirectory = lpDirectory;
2885 ExecInfo.nShow = (WORD)nCmdShow;
2886
2887 if (lpReserved)
2888 {
2889 ExecInfo.fMask |= SEE_MASK_USE_RESERVED;
2890 ExecInfo.hInstApp = (HINSTANCE)lpReserved;
2891 }
2892
2893 if (lpTitle)
2894 {
2895 ExecInfo.fMask |= SEE_MASK_HASTITLE;
2896 ExecInfo.lpClass = lpTitle;
2897 }
2898
2899 if (dwFlags & 1)
2900 ExecInfo.fMask |= SEE_MASK_FLAG_SEPVDM;
2901
2902 if (dwFlags & 2)
2903 ExecInfo.fMask |= SEE_MASK_NO_CONSOLE;
2904
2905 if (lphProcess == NULL)
2906 {
2907 ShellExecuteExW(&ExecInfo);
2908 }
2909 else
2910 {
2911 ExecInfo.fMask |= SEE_MASK_NOCLOSEPROCESS;
2912 ShellExecuteExW(&ExecInfo);
2913 *lphProcess = ExecInfo.hProcess;
2914 }
2915
2916 return ExecInfo.hInstApp;
2917}
BOOL WINAPI DECLSPEC_HOTPATCH ShellExecuteExW(LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:2452
HINSTANCE hInstApp
Definition: shellapi.h:337
LPCWSTR lpParameters
Definition: shellapi.h:334

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

2965{
2967 lpOperation,
2968 lpFile,
2969 lpParameters,
2971 lpReturn,
2972 lpTitle,
2973 lpReserved,
2974 nCmdShow,
2975 lphProcess,
2976 0);
2977}
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:2857

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

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

556{
558 WCHAR *strings, *p, *p2;
559 int total = wcslen(path) + 1;
560 BOOL got_path = FALSE;
561
562 if (!(strings = GetEnvironmentStringsW())) return NULL;
563 p = strings;
564 while (*p)
565 {
566 int len = wcslen(p) + 1;
567 if (!_wcsnicmp( p, L"PATH=", 5 )) got_path = TRUE;
568 total += len;
569 p += len;
570 }
571 if (!got_path) total += 5; /* we need to create PATH */
572 total++; /* terminating null */
573
574 if (!new_env.Allocate(total))
575 {
577 return NULL;
578 }
579 p = strings;
580 p2 = new_env;
581 while (*p)
582 {
583 int len = wcslen(p) + 1;
584 memcpy(p2, p, len * sizeof(WCHAR));
585 if (!_wcsnicmp( p, L"PATH=", 5 ))
586 {
587 p2[len - 1] = ';';
588 wcscpy( p2 + len, path );
589 p2 += wcslen(path) + 1;
590 }
591 p += len;
592 p2 += len;
593 }
594 if (!got_path)
595 {
596 wcscpy(p2, L"PATH=");
597 wcscat(p2, path);
598 p2 += wcslen(p2) + 1;
599 }
600 *p2 = 0;
602 return new_env.Detach();
603}
T * Detach()
Definition: atlalloc.h:168
wcscat
BOOL WINAPI FreeEnvironmentStringsW(IN LPWSTR EnvironmentStrings)
Definition: environ.c:389
size_t total
GLsizei const GLchar *const * strings
Definition: glext.h:7622
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
LPWSTR WINAPI GetEnvironmentStringsW(void)
Definition: environ.c:344

Referenced by SHELL_TryAppPathW().

◆ SHELL_execute()

static BOOL SHELL_execute ( LPSHELLEXECUTEINFOW  sei,
SHELL_ExecuteW32  execfunc 
)
static

Definition at line 1942 of file shlexec.cpp.

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

Referenced by ShellExecute_Normal(), and WOWShellExecute().

◆ SHELL_execute_class()

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

Definition at line 1663 of file shlexec.cpp.

1664{
1665 WCHAR execCmd[1024], classname[1024];
1666 /* launch a document by fileclass like 'WordPad.Document.1' */
1667 /* the Commandline contains 'c:\Path\wordpad.exe "%1"' */
1668 /* FIXME: wcmd should not be of a fixed size. Fixed to 1024, MAX_PATH is way too short! */
1669 ULONG cmask = (psei->fMask & SEE_MASK_CLASSALL);
1670 DWORD resultLen;
1671 BOOL done;
1672 UINT_PTR rslt;
1673
1674 /* FIXME: remove following block when SHELL_quote_and_execute supports hkeyClass parameter */
1675 if (cmask != SEE_MASK_CLASSNAME)
1676 {
1677 WCHAR wcmd[1024];
1679 (cmask == SEE_MASK_CLASSNAME) ? psei->lpClass : NULL,
1680 psei->lpVerb,
1681 execCmd, sizeof(execCmd));
1682
1683 /* FIXME: get the extension of lpFile, check if it fits to the lpClass */
1684 TRACE("SEE_MASK_CLASSNAME->%s, doc->%s\n", debugstr_w(execCmd), debugstr_w(wszApplicationName));
1685
1686 wcmd[0] = '\0';
1687 done = SHELL_ArgifyW(wcmd, ARRAY_SIZE(wcmd), execCmd, wszApplicationName, (LPITEMIDLIST)psei->lpIDList, psei->lpParameters,
1688 &resultLen, (psei->lpDirectory && *psei->lpDirectory) ? psei->lpDirectory : NULL);
1689 if (!done && wszApplicationName[0])
1690 {
1691#if 0 // Given HKCR\.test=SZ:"test" and HKCR\test\shell\open\command=SZ:"cmd.exe /K echo.Hello", no filename is
1692 // appended on Windows when there is no %1 nor %L when executed with: shlextdbg.exe /shellexec=c:\file.test /INVOKE
1693 strcatW(wcmd, L" ");
1694 if (*wszApplicationName != '"')
1695 {
1696 strcatW(wcmd, L"\"");
1697 strcatW(wcmd, wszApplicationName);
1698 strcatW(wcmd, L"\"");
1699 }
1700 else
1701 strcatW(wcmd, wszApplicationName);
1702#endif
1703 }
1704 if (resultLen > ARRAY_SIZE(wcmd))
1705 ERR("Argify buffer not large enough... truncating\n");
1706 return execfunc(wcmd, NULL, FALSE, psei, psei_out);
1707 }
1708
1709 strcpyW(classname, psei->lpClass);
1710 rslt = SHELL_FindExecutableByVerb(psei->lpVerb, NULL, classname, execCmd, sizeof(execCmd));
1711
1712 TRACE("SHELL_FindExecutableByVerb returned %u (%s, %s)\n", (unsigned int)rslt, debugstr_w(classname), debugstr_w(execCmd));
1713 if (33 > rslt)
1714 return rslt;
1715 rslt = SHELL_quote_and_execute( execCmd, L"", classname,
1716 wszApplicationName, NULL, psei,
1717 psei_out, execfunc );
1718 return rslt;
1719
1720}
WCHAR classname[128]
Definition: startup.c:15
BOOL HCR_GetExecuteCommandW(HKEY hkeyClass, LPCWSTR szClass, LPCWSTR szVerb, LPWSTR szDest, DWORD len)
Definition: classes.c:220
#define SEE_MASK_CLASSKEY
Definition: shellapi.h:26
static UINT SHELL_FindExecutableByVerb(LPCWSTR lpVerb, LPWSTR key, LPWSTR classname, LPWSTR command, LONG commandlen)
Definition: shlexec.cpp:673
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 1866 of file shlexec.cpp.

1867{
1870 LPCWSTR lpstrRes;
1871 INT iSize;
1872 DWORD len;
1873
1874 lpstrRes = strchrW(lpFile, ':');
1875 if (lpstrRes)
1876 iSize = lpstrRes - lpFile;
1877 else
1878 iSize = strlenW(lpFile);
1879
1880 TRACE("Got URL: %s\n", debugstr_w(lpFile));
1881 /* Looking for ...<protocol>\shell<lpVerb>\command */
1882 len = iSize + lstrlenW(L"\\shell\\") + lstrlenW(L"\\command") + 1;
1883 if (psei->lpVerb && *psei->lpVerb)
1884 len += lstrlenW(psei->lpVerb);
1885 else
1886 len += lstrlenW(L"open");
1887 lpstrProtocol.Allocate(len);
1888 memcpy(lpstrProtocol, lpFile, iSize * sizeof(WCHAR));
1889 lpstrProtocol[iSize] = '\0';
1890 strcatW(lpstrProtocol, L"\\shell\\");
1891 strcatW(lpstrProtocol, psei->lpVerb && *psei->lpVerb ? psei->lpVerb : L"open");
1892 strcatW(lpstrProtocol, L"\\command");
1893
1894 retval = execute_from_key(lpstrProtocol, lpFile, NULL, psei->lpParameters,
1895 wcmd, execfunc, psei, psei_out);
1896
1897 return retval;
1898}
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:1186

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

474{
478 UINT gcdret = 0;
479 WCHAR curdir[MAX_PATH];
480 DWORD dwCreationFlags;
481 const WCHAR *lpDirectory = NULL;
482
483 TRACE("Execute %s from directory %s\n", debugstr_w(lpCmd), debugstr_w(psei->lpDirectory));
484
485 /* make sure we don't fail the CreateProcess if the calling app passes in
486 * a bad working directory */
487 if (!StrIsNullOrEmpty(psei->lpDirectory))
488 {
491 lpDirectory = psei->lpDirectory;
492 }
493
494 /* ShellExecute specifies the command from psei->lpDirectory
495 * if present. Not from the current dir as CreateProcess does */
496 if (lpDirectory)
497 if ((gcdret = GetCurrentDirectoryW( MAX_PATH, curdir)))
499 ERR("cannot set directory %s\n", debugstr_w(lpDirectory));
500
502 startup.cb = sizeof(STARTUPINFOW);
504 startup.wShowWindow = psei->nShow;
505 dwCreationFlags = CREATE_UNICODE_ENVIRONMENT;
506 if (!(psei->fMask & SEE_MASK_NO_CONSOLE))
507 dwCreationFlags |= CREATE_NEW_CONSOLE;
508 if (psei->fMask & SEE_MASK_FLAG_SEPVDM)
509 dwCreationFlags |= CREATE_SEPARATE_WOW_VDM;
510 startup.lpTitle = (LPWSTR)(psei->fMask & (SEE_MASK_HASLINKNAME | SEE_MASK_HASTITLE) ? psei->lpClass : NULL);
511
512 if (psei->fMask & SEE_MASK_HASLINKNAME)
513 startup.dwFlags |= STARTF_TITLEISLINKNAME;
514
515 if (CreateProcessW(NULL, (LPWSTR)lpCmd, NULL, NULL, FALSE, dwCreationFlags, env,
517 {
518 /* Give 30 seconds to the app to come up, if desired. Probably only needed
519 when starting app immediately before making a DDE connection. */
520 if (shWait)
521 if (WaitForInputIdle(info.hProcess, 30000) == WAIT_FAILED)
522 WARN("WaitForInputIdle failed: Error %d\n", GetLastError() );
523 retval = 33;
524
525 if (psei->fMask & SEE_MASK_NOCLOSEPROCESS)
526 psei_out->hProcess = info.hProcess;
527 else
528 CloseHandle( info.hProcess );
529 CloseHandle( info.hThread );
530 }
531 else if ((retval = GetLastError()) >= 32)
532 {
533 WARN("CreateProcess returned error %ld\n", retval);
535 }
536
537 TRACE("returning %lu\n", retval);
538
539 psei_out->hInstApp = (HINSTANCE)retval;
540
541 if (gcdret)
542 if (!SetCurrentDirectoryW(curdir))
543 ERR("cannot return to directory %s\n", debugstr_w(curdir));
544
545 return retval;
546}
static void startup(void)
#define CloseHandle
Definition: compat.h:739
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:652
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessW(LPCWSTR lpApplicationName, LPWSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4598
unsigned int UINT
Definition: ndis.h:50
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define SEE_MASK_HASLINKNAME
Definition: shellapi.h:49
Definition: cookie.c:202
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
#define STARTF_USESHOWWINDOW
Definition: winbase.h:517
#define CREATE_UNICODE_ENVIRONMENT
Definition: winbase.h:189
#define CREATE_SEPARATE_WOW_VDM
Definition: winbase.h:190
#define WAIT_FAILED
Definition: winbase.h:439
#define CREATE_NEW_CONSOLE
Definition: winbase.h:183
struct _STARTUPINFOW STARTUPINFOW
#define ERROR_BAD_FORMAT
Definition: winerror.h:114
DWORD WINAPI WaitForInputIdle(_In_ HANDLE, _In_ DWORD)

Referenced by ShellExecute_Normal().

◆ SHELL_FindExecutable()

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

Definition at line 741 of file shlexec.cpp.

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

Referenced by SHELL_execute(), and shellex_get_contextmenu().

◆ SHELL_FindExecutableByVerb()

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

Definition at line 673 of file shlexec.cpp.

674{
675 HKEY hkeyClass;
676 WCHAR verb[MAX_PATH];
677
678 if (RegOpenKeyExW(HKEY_CLASSES_ROOT, classname, 0, 0x02000000, &hkeyClass))
679 return SE_ERR_NOASSOC;
680 if (!HCR_GetDefaultVerbW(hkeyClass, lpVerb, verb, ARRAY_SIZE(verb)))
681 return SE_ERR_NOASSOC;
682 RegCloseKey(hkeyClass);
683
684 /* Looking for ...buffer\shell<verb>\command */
685 wcscat(classname, L"\\shell\\");
686 wcscat(classname, verb);
687 wcscat(classname, L"\\command");
688
690 &commandlen) == ERROR_SUCCESS)
691 {
692 commandlen /= sizeof(WCHAR);
693 if (key) wcscpy(key, classname);
694#if 0
695 LPWSTR tmp;
696 WCHAR param[256];
697 LONG paramlen = sizeof(param);
698
699 /* FIXME: it seems all Windows version don't behave the same here.
700 * the doc states that this ddeexec information can be found after
701 * the exec names.
702 * on Win98, it doesn't appear, but I think it does on Win2k
703 */
704 /* Get the parameters needed by the application
705 from the associated ddeexec key */
706 tmp = strstrW(classname, L"\\command");
707 tmp[0] = '\0';
708 wcscat(classname, wDdeexec);
710 &paramlen) == ERROR_SUCCESS)
711 {
712 paramlen /= sizeof(WCHAR);
713 wcscat(command, L" ");
715 commandlen += paramlen;
716 }
717#endif
718
719 command[commandlen] = '\0';
720
721 return 33; /* FIXME see SHELL_FindExecutable() */
722 }
723
724 return SE_ERR_NOASSOC;
725}
#define RegCloseKey(hKey)
Definition: registry.h:49
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
BOOL HCR_GetDefaultVerbW(HKEY hkeyClass, LPCWSTR szVerb, LPWSTR szDest, DWORD len)
Definition: classes.c:152

Referenced by SHELL_execute_class(), and SHELL_FindExecutable().

◆ SHELL_GetPathFromIDListForExecuteW()

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

Definition at line 450 of file shlexec.cpp.

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

Referenced by SHELL_translate_idlist().

◆ SHELL_InRunDllProcess()

static BOOL SHELL_InRunDllProcess ( VOID  )
static

Definition at line 36 of file shlexec.cpp.

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

Referenced by ShellExec_RunDLL_Helper(), and ShellExecuteExW().

◆ SHELL_InvokePidl()

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

Definition at line 1778 of file shlexec.cpp.

1781{
1782 // Bind pidl
1783 CComPtr<IShellFolder> psfFolder;
1784 LPCITEMIDLIST pidlLast;
1785 HRESULT hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &psfFolder), &pidlLast);
1787 return FALSE;
1788
1789 // Get the context menu to invoke a command
1791 hr = psfFolder->GetUIObjectOf(NULL, 1, &pidlLast, IID_NULL_PPV_ARG(IContextMenu, &pCM));
1793 return FALSE;
1794
1795 // Invoke a command
1796 CMINVOKECOMMANDINFO ici = { sizeof(ici) };
1797 ici.fMask = (sei->fMask & SEE_CMIC_COMMON_BASICFLAGS) & ~CMIC_MASK_UNICODE; // FIXME: Unicode?
1798 ici.nShow = sei->nShow;
1799 ici.hwnd = sei->hwnd;
1800 char szVerb[VERBKEY_CCHMAX];
1801 if (sei->lpVerb && sei->lpVerb[0])
1802 {
1803 WideCharToMultiByte(CP_ACP, 0, sei->lpVerb, -1, szVerb, _countof(szVerb), NULL, NULL);
1804 szVerb[_countof(szVerb) - 1] = ANSI_NULL; // Avoid buffer overrun
1805 ici.lpVerb = szVerb;
1806 }
1807 else // The default verb?
1808 {
1809 HMENU hMenu = CreatePopupMenu();
1810 const INT idCmdFirst = 1, idCmdLast = 0x7FFF;
1811 hr = pCM->QueryContextMenu(hMenu, 0, idCmdFirst, idCmdLast, CMF_DEFAULTONLY);
1813 {
1814 DestroyMenu(hMenu);
1815 return FALSE;
1816 }
1817
1818 INT nDefaultID = GetMenuDefaultItem(hMenu, FALSE, 0);
1819 DestroyMenu(hMenu);
1820 if (nDefaultID == -1)
1821 nDefaultID = idCmdFirst;
1822
1823 ici.lpVerb = MAKEINTRESOURCEA(nDefaultID - idCmdFirst);
1824 }
1825 hr = pCM->InvokeCommand(&ici);
1826
1827 return !FAILED_UNEXPECTEDLY(hr);
1828}
#define FAILED_UNEXPECTEDLY(hr)
Definition: precomp.h:121
#define VERBKEY_CCHMAX
Definition: precomp.h:129
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:63
#define ANSI_NULL
#define SEE_CMIC_COMMON_BASICFLAGS
Definition: shellutils.h:625
HMENU WINAPI CreatePopupMenu(void)
Definition: menu.c:838
UINT WINAPI GetMenuDefaultItem(_In_ HMENU hMenu, _In_ UINT fByPos, _In_ UINT gmdiFlags)
#define MAKEINTRESOURCEA(i)
Definition: winuser.h:581
BOOL WINAPI DestroyMenu(_In_ HMENU)
#define IID_NULL_PPV_ARG(Itype, ppType)

Referenced by SHELL_execute().

◆ SHELL_quote_and_execute()

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

Definition at line 1830 of file shlexec.cpp.

1831{
1833 DWORD len;
1835
1836 /* Length of quotes plus length of command plus NULL terminator */
1837 len = 2 + lstrlenW(wcmd) + 1;
1838 if (wszParameters[0])
1839 {
1840 /* Length of space plus length of parameters */
1841 len += 1 + lstrlenW(wszParameters);
1842 }
1843 wszQuotedCmd.Allocate(len);
1844 /* Must quote to handle case where cmd contains spaces,
1845 * else security hole if malicious user creates executable file "C:\\Program"
1846 */
1847 strcpyW(wszQuotedCmd, L"\"");
1848 strcatW(wszQuotedCmd, wcmd);
1849 strcatW(wszQuotedCmd, L"\"");
1850 if (wszParameters[0])
1851 {
1852 strcatW(wszQuotedCmd, L" ");
1853 strcatW(wszQuotedCmd, wszParameters);
1854 }
1855
1856 TRACE("%s/%s => %s/%s\n", debugstr_w(wszApplicationName), debugstr_w(psei->lpVerb), debugstr_w(wszQuotedCmd), debugstr_w(wszKeyname));
1857
1858 if (*wszKeyname)
1859 retval = execute_from_key(wszKeyname, wszApplicationName, env, psei->lpParameters, wcmd, execfunc, psei, psei_out);
1860 else
1861 retval = execfunc(wszQuotedCmd, env, FALSE, psei, psei_out);
1862
1863 return retval;
1864}

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

1723{
1725 BOOL appKnownSingular = FALSE;
1726
1727 /* last chance to translate IDList: now also allow CLSID paths */
1729 if (buffer[0] == ':' && buffer[1] == ':') {
1730 /* open shell folder for the specified class GUID */
1731 if (strlenW(buffer) + 1 > parametersLen)
1732 ERR("parameters len exceeds buffer size (%i > %i), truncating\n",
1733 lstrlenW(buffer) + 1, parametersLen);
1734 lstrcpynW(wszParameters, buffer, parametersLen);
1735 if (strlenW(L"explorer.exe") > dwApplicationNameLen)
1736 ERR("application len exceeds buffer size (%i), truncating\n",
1737 dwApplicationNameLen);
1738 lstrcpynW(wszApplicationName, L"explorer.exe", dwApplicationNameLen);
1739 appKnownSingular = TRUE;
1740
1741 sei->fMask &= ~SEE_MASK_INVOKEIDLIST;
1742 } else {
1744 DWORD attribs;
1745 DWORD resultLen;
1746 /* Check if we're executing a directory and if so use the
1747 handler for the Folder class */
1752 HCR_GetExecuteCommandW(0, L"Folder",
1753 sei->lpVerb,
1754 buffer, sizeof(buffer))) {
1755 SHELL_ArgifyW(wszApplicationName, dwApplicationNameLen,
1756 buffer, target, (LPITEMIDLIST)sei->lpIDList, NULL, &resultLen,
1757 !StrIsNullOrEmpty(sei->lpDirectory) ? sei->lpDirectory : NULL);
1758 if (resultLen > dwApplicationNameLen)
1759 ERR("Argify buffer not large enough... truncating\n"); // FIXME: Report this to the caller?
1760 appKnownSingular = FALSE;
1761 // HACKFIX: We really want the !appKnownSingular code in SHELL_execute to split the
1762 // parameters for us but we cannot guarantee that the exe in the registry is quoted.
1763 // We have now turned 'explorer.exe "%1" into 'explorer.exe "c:\path\from\pidl"' and
1764 // need to split to application and parameters.
1765 LPCWSTR params = PathGetArgsW(wszApplicationName);
1766 lstrcpynW(wszParameters, params, parametersLen);
1767 PathRemoveArgsW(wszApplicationName);
1768 PathUnquoteSpacesW(wszApplicationName);
1769 appKnownSingular = TRUE;
1770 }
1771 sei->fMask &= ~SEE_MASK_INVOKEIDLIST;
1772 }
1773 }
1774 return appKnownSingular;
1775}
#define lstrcpynW
Definition: compat.h:738
GLenum const GLfloat * params
Definition: glext.h:5645
GLenum target
Definition: glext.h:7315
static HRESULT SHELL_GetPathFromIDListForExecuteW(LPCITEMIDLIST pidl, LPWSTR pszPath, UINT uOutSize)
Definition: shlexec.cpp:450
#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 613 of file shlexec.cpp.

614{
615 HKEY hkApp = NULL;
616 WCHAR buffer[1024];
617 DWORD len, dwType;
618 LONG res;
619 BOOL found = FALSE;
620
621 if (env) *env = NULL;
622 wcscpy(buffer, L"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\");
625 if (res)
626 {
627 // Add ".exe" extension, if extension does not exists
628 if (PathAddExtensionW(buffer, L".exe"))
629 {
631 }
632 if (res) goto end;
633 }
634
635 len = MAX_PATH * sizeof(WCHAR);
636 res = SHRegQueryValueExW(hkApp, NULL, NULL, &dwType, (LPBYTE)lpResult, &len);
637 if (res != ERROR_SUCCESS || dwType != REG_SZ)
638 goto end;
639
640 found = TRUE;
641
642 if (env)
643 {
644 len = sizeof(buffer);
645 res = SHRegQueryValueExW(hkApp, L"Path", NULL, &dwType, (LPBYTE)buffer, &len);
646 if (res == ERROR_SUCCESS && dwType == REG_SZ && buffer[0])
648 }
649
650end:
651 if (hkApp) RegCloseKey(hkApp);
652 return found;
653}
GLuint GLuint end
Definition: gl.h:1545
#define REG_SZ
Definition: layer.c:22
#define KEY_READ
Definition: nt_native.h:1023
#define PathAddExtensionW
Definition: pathcch.h:305
static const WCHAR szName[]
Definition: powrprof.c:45
LONG WINAPI SHRegQueryValueExW(HKEY hkey, LPCWSTR pszValue, LPDWORD pdwReserved, LPDWORD pdwType, LPVOID pvData, LPDWORD pcbData)
Definition: shellreg.c:108
static LPWSTR SHELL_BuildEnvW(const WCHAR *path)
Definition: shlexec.cpp:555
#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 1514 of file shlexec.cpp.

1515{
1516 CComHeapPtr<ITEMIDLIST> allocatedPidl;
1517 LPITEMIDLIST pidl = NULL;
1518
1519 if (sei->lpIDList)
1520 {
1521 pidl = (LPITEMIDLIST)sei->lpIDList;
1522 }
1523 else
1524 {
1525 SFGAOF sfga = 0;
1526 HRESULT hr = SHParseDisplayName(sei->lpFile, NULL, &allocatedPidl, SFGAO_STORAGECAPMASK, &sfga);
1527 if (FAILED(hr))
1528 {
1529 WCHAR Buffer[MAX_PATH] = {};
1530 // FIXME: MAX_PATH.....
1532 if (retval <= 32)
1533 return HRESULT_FROM_WIN32(retval);
1534
1535 hr = SHParseDisplayName(Buffer, NULL, &allocatedPidl, SFGAO_STORAGECAPMASK, &sfga);
1536 // This should not happen, we found it...
1538 return hr;
1539 }
1540
1541 pidl = allocatedPidl;
1542 }
1543
1545 LPCITEMIDLIST pidllast = NULL;
1546 HRESULT hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &shf), &pidllast);
1547 if (FAILED(hr))
1548 return hr;
1549
1550 return shf->GetUIObjectOf(NULL, 1, &pidllast, IID_NULL_PPV_ARG(IContextMenu, &cm));
1551}
Definition: bufpool.h:45
static IShellFolder IShellItem **static IBindCtx LPITEMIDLIST SFGAOF
Definition: ebrowser.c:83
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92

Referenced by ShellExecute_ContextMenuVerb().

◆ shellex_get_dataobj()

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

Definition at line 1386 of file shlexec.cpp.

1387{
1388 CComHeapPtr<ITEMIDLIST> allocatedPidl;
1389 LPITEMIDLIST pidl = NULL;
1390
1391 if (sei->fMask & SEE_MASK_CLASSALL)
1392 {
1393 pidl = (LPITEMIDLIST)sei->lpIDList;
1394 }
1395 else
1396 {
1397 WCHAR fullpath[MAX_PATH];
1398 BOOL ret;
1399
1400 fullpath[0] = 0;
1401 ret = GetFullPathNameW(sei->lpFile, MAX_PATH, fullpath, NULL);
1402 if (!ret)
1404
1405 pidl = ILCreateFromPathW(fullpath);
1406 allocatedPidl.Attach(pidl);
1407 }
1409}
DWORD WINAPI GetFullPathNameW(IN LPCWSTR lpFileName, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart)
Definition: path.c:1106
EXTERN_C HRESULT SHELL_GetUIObjectOfAbsoluteItem(_In_opt_ HWND hWnd, _In_ PCIDLIST_ABSOLUTE pidl, _In_ REFIID riid, _Out_ void **ppvObj)
Definition: utils.cpp:380
LPITEMIDLIST WINAPI ILCreateFromPathW(LPCWSTR path)
Definition: pidl.c:1101

Referenced by shellex_load_object_and_run().

◆ shellex_load_object_and_run()

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

Definition at line 1480 of file shlexec.cpp.

1481{
1482 TRACE("%p %s %p\n", hkey, debugstr_guid(guid), sei);
1483
1484 CCoInit coInit;
1485
1486 if (FAILED_UNEXPECTEDLY(coInit.hr))
1487 return coInit.hr;
1488
1490 HRESULT hr = CoCreateInstance(*guid, NULL, CLSCTX_INPROC_SERVER,
1493 return hr;
1494
1495 CComPtr<IDataObject> dataobj;
1496 hr = shellex_get_dataobj(sei, dataobj);
1498 return hr;
1499
1500 hr = obj->Initialize(NULL, dataobj, hkey);
1502 return hr;
1503
1505 hr = obj->QueryInterface(IID_PPV_ARG(IObjectWithSite, &ows));
1507 return hr;
1508
1509 ows->SetSite(NULL);
1510
1512}
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
#define debugstr_guid
Definition: kernel32.h:35
const GUID * guid
static HRESULT shellex_run_context_menu_default(IShellExtInit *obj, LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:1411
static HRESULT shellex_get_dataobj(LPSHELLEXECUTEINFOW sei, CComPtr< IDataObject > &dataObj)
Definition: shlexec.cpp:1386

Referenced by ShellExecute_FromContextMenuHandlers().

◆ shellex_run_context_menu_default()

static HRESULT shellex_run_context_menu_default ( IShellExtInit obj,
LPSHELLEXECUTEINFOW  sei 
)
static

Definition at line 1411 of file shlexec.cpp.

1413{
1415 CMINVOKECOMMANDINFOEX ici;
1417 WCHAR string[0x80];
1418 INT i, n, def = -1;
1419 HMENU hmenu = 0;
1420 HRESULT r;
1421
1422 TRACE("%p %p\n", obj, sei);
1423
1424 r = obj->QueryInterface(IID_PPV_ARG(IContextMenu, &cm));
1425 if (FAILED(r))
1426 return r;
1427
1428 hmenu = CreateMenu();
1429 if (!hmenu)
1430 goto end;
1431
1432 /* the number of the last menu added is returned in r */
1433 r = cm->QueryContextMenu(hmenu, 0, 0x20, 0x7fff, CMF_DEFAULTONLY);
1434 if (FAILED(r))
1435 goto end;
1436
1438 for (i = 0; i < n; i++)
1439 {
1440 memset(&info, 0, sizeof(info));
1441 info.cbSize = sizeof info;
1443 info.dwTypeData = string;
1444 info.cch = sizeof string;
1445 string[0] = 0;
1447
1448 TRACE("menu %d %s %08x %08lx %08x %08x\n", i, debugstr_w(string),
1449 info.fState, info.dwItemData, info.fType, info.wID);
1450 if ((!sei->lpVerb && (info.fState & MFS_DEFAULT)) ||
1451 (sei->lpVerb && !lstrcmpiW(sei->lpVerb, string)))
1452 {
1453 def = i;
1454 break;
1455 }
1456 }
1457
1458 r = E_FAIL;
1459 if (def == -1)
1460 goto end;
1461
1462 memset(&ici, 0, sizeof ici);
1463 ici.cbSize = sizeof ici;
1464 ici.fMask = (sei->fMask & SEE_CMIC_COMMON_BASICFLAGS) | CMIC_MASK_UNICODE;
1465 ici.nShow = sei->nShow;
1466 ici.lpVerb = MAKEINTRESOURCEA(def);
1467 ici.hwnd = sei->hwnd;
1468 ici.lpParametersW = sei->lpParameters;
1469
1470 r = cm->InvokeCommand((LPCMINVOKECOMMANDINFO)&ici);
1471
1472 TRACE("invoke command returned %08x\n", r);
1473
1474end:
1475 if (hmenu)
1476 DestroyMenu( hmenu );
1477 return r;
1478}
#define E_FAIL
Definition: ddrawi.h:102
int WINAPI lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4262
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLdouble n
Definition: glext.h:7729
static HMENU hmenu
Definition: win.c:66
#define memset(x, y, z)
Definition: compat.h:39
#define MIIM_STRING
Definition: winuser.h:730
#define MIIM_ID
Definition: winuser.h:725
int WINAPI GetMenuItemCount(_In_opt_ HMENU)
HMENU WINAPI CreateMenu(void)
Definition: menu.c:829
#define MIIM_FTYPE
Definition: winuser.h:732
#define MIIM_STATE
Definition: winuser.h:724
#define MFS_DEFAULT
Definition: winuser.h:751
BOOL WINAPI GetMenuItemInfoW(_In_ HMENU, _In_ UINT, _In_ BOOL, _Inout_ LPMENUITEMINFOW)
#define MIIM_DATA
Definition: winuser.h:729

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

2986{
2987 TRACE("(%p, %p, %s, 0x%X)\n", hwnd, hInstance, wine_dbgstr_w(pszCmdLine), nCmdShow);
2988
2989 if (!pszCmdLine || !*pszCmdLine)
2990 return;
2991
2992 // '?' enables us to specify the additional mask value
2993 ULONG fNewMask = SEE_MASK_NOASYNC;
2994 if (*pszCmdLine == L'?') // 1st question
2995 {
2996 INT MaskValue;
2997 if (StrToIntExW(pszCmdLine + 1, STIF_SUPPORT_HEX, &MaskValue))
2998 fNewMask |= MaskValue;
2999
3000 PCWSTR pch2ndQuestion = StrChrW(pszCmdLine + 1, L'?'); // 2nd question
3001 if (pch2ndQuestion)
3002 pszCmdLine = pch2ndQuestion + 1;
3003 }
3004
3005 WCHAR szPath[2 * MAX_PATH];
3006 if (PathProcessCommandAW(pszCmdLine, szPath, _countof(szPath), L'C') == -1)
3007 StrCpyNW(szPath, pszCmdLine, _countof(szPath));
3008
3009 // Split arguments from the path
3011 if (*Args)
3012 *(Args - 1) = UNICODE_NULL;
3013
3015
3016 // Execute
3017 SHELLEXECUTEINFOW execInfo = { sizeof(execInfo) };
3018 execInfo.fMask = fNewMask;
3019 execInfo.hwnd = hwnd;
3020 execInfo.lpFile = szPath;
3021 execInfo.lpParameters = Args;
3022 execInfo.nShow = nCmdShow;
3023 if (!ShellExecuteExW(&execInfo))
3024 {
3025 DWORD dwError = GetLastError();
3026 if (SHELL_InRunDllProcess()) // Is it a RUNDLL process?
3027 ExitProcess(dwError); // Terminate it now
3028 }
3029}
char ** Args
Definition: acdebug.h:353
HINSTANCE hInstance
Definition: charmap.c:19
LPWSTR WINAPI StrChrW(LPCWSTR lpszStr, WCHAR ch)
Definition: string.c:464
VOID WINAPI ExitProcess(IN UINT uExitCode)
Definition: proc.c:1487
LONG WINAPI PathProcessCommandAW(LPCVOID lpszPath, LPVOID lpszBuff, DWORD dwBuffSize, DWORD dwFlags)
Definition: shellpath.c:1003
BOOL WINAPI StrToIntExW(LPCWSTR lpszStr, DWORD dwFlags, int *lpiRet)
Definition: string.c:970
LPWSTR WINAPI StrCpyNW(LPWSTR dst, LPCWSTR src, int count)
Definition: string.c:536
#define wine_dbgstr_w
Definition: kernel32.h:34
LPCWSTR szPath
Definition: env.c:37
#define SEE_MASK_NOASYNC
Definition: shellapi.h:33
static BOOL SHELL_InRunDllProcess(VOID)
Definition: shlexec.cpp:36
#define STIF_SUPPORT_HEX
Definition: shlwapi.h:1487
const uint16_t * PCWSTR
Definition: typedefs.h:57

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

3043{
3044 CStringW strCmdLine = pszCmdLine; // Keep
3045 ShellExec_RunDLL_Helper(hwnd, hInstance, strCmdLine, nCmdShow);
3046}
static VOID ShellExec_RunDLL_Helper(_In_opt_ HWND hwnd, _In_opt_ HINSTANCE hInstance, _In_ PCWSTR pszCmdLine, _In_ INT nCmdShow)
Definition: shlexec.cpp:2981

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

3060{
3061 ShellExec_RunDLL_Helper(hwnd, hInstance, pszCmdLine, nCmdShow);
3062}

Referenced by TEST_ShellExec_RunDLLW().

◆ ShellExecCmdLine()

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

Definition at line 2650 of file shlexec.cpp.

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

◆ ShellExecute_ContextMenuVerb()

static HRESULT ShellExecute_ContextMenuVerb ( LPSHELLEXECUTEINFOW  sei)
static

Definition at line 1553 of file shlexec.cpp.

1554{
1555 TRACE("%p\n", sei);
1556
1557 CCoInit coInit;
1558
1559 if (FAILED_UNEXPECTEDLY(coInit.hr))
1560 return coInit.hr;
1561
1565 return hr;
1566
1567 CComHeapPtr<char> verb, parameters, dir;
1568 __SHCloneStrWtoA(&verb, sei->lpVerb);
1569 __SHCloneStrWtoA(&parameters, sei->lpParameters);
1571
1572 BOOL fDefault = StrIsNullOrEmpty(sei->lpVerb);
1573 CMINVOKECOMMANDINFOEX ici = { sizeof(ici) };
1574 ici.fMask = SeeFlagsToCmicFlags(sei->fMask) | CMIC_MASK_UNICODE;
1575 ici.nShow = sei->nShow;
1576 if (!fDefault)
1577 {
1578 ici.lpVerb = verb;
1579 ici.lpVerbW = sei->lpVerb;
1580 }
1581 ici.hwnd = sei->hwnd;
1582 ici.lpParameters = parameters;
1583 ici.lpParametersW = sei->lpParameters;
1584 ici.lpDirectory = dir;
1585 ici.lpDirectoryW = sei->lpDirectory;
1586 ici.dwHotKey = sei->dwHotKey;
1587 ici.hIcon = sei->hIcon;
1588 if (ici.fMask & (CMIC_MASK_HASLINKNAME | CMIC_MASK_HASTITLE))
1589 ici.lpTitleW = sei->lpClass;
1590
1591 enum { idFirst = 1, idLast = 0x7fff };
1592 HMENU hMenu = CreatePopupMenu();
1593 // Note: Windows does not pass CMF_EXTENDEDVERBS so "hidden" verbs cannot be executed
1594 hr = cm->QueryContextMenu(hMenu, 0, idFirst, idLast, fDefault ? CMF_DEFAULTONLY : 0);
1595 if (!FAILED_UNEXPECTEDLY(hr))
1596 {
1597 if (fDefault)
1598 {
1599 INT uDefault = GetMenuDefaultItem(hMenu, FALSE, 0);
1600 uDefault = (uDefault != -1) ? uDefault - idFirst : 0;
1601 ici.lpVerb = MAKEINTRESOURCEA(uDefault);
1602 ici.lpVerbW = MAKEINTRESOURCEW(uDefault);
1603 }
1604
1605 hr = cm->InvokeCommand((LPCMINVOKECOMMANDINFO)&ici);
1606 if (!FAILED_UNEXPECTEDLY(hr))
1607 hr = S_OK;
1608 }
1609
1610 DestroyMenu(hMenu);
1611
1612 return hr;
1613}
unsigned int dir
Definition: maze.c:112
static UINT SeeFlagsToCmicFlags(UINT flags)
Definition: precomp.h:188
static __inline void __SHCloneStrWtoA(char **target, const WCHAR *source)
Definition: shell32_main.h:165
static HRESULT shellex_get_contextmenu(LPSHELLEXECUTEINFOW sei, CComPtr< IContextMenu > &cm)
Definition: shlexec.cpp:1514
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582

Referenced by SHELL_execute().

◆ ShellExecute_FromContextMenuHandlers()

static LONG ShellExecute_FromContextMenuHandlers ( LPSHELLEXECUTEINFOW  sei)
static

Definition at line 1619 of file shlexec.cpp.

1620{
1621 HKEY hkey, hkeycm = 0;
1622 WCHAR szguid[39];
1623 HRESULT hr;
1624 GUID guid;
1625 DWORD i;
1626 LONG r;
1627
1628 TRACE("%s\n", debugstr_w(sei->lpFile));
1629
1630 hkey = ShellExecute_GetClassKey(sei);
1631 if (!hkey)
1632 return ERROR_FUNCTION_FAILED;
1633
1634 r = RegOpenKeyW(hkey, L"shellex\\ContextMenuHandlers", &hkeycm);
1635 if (r == ERROR_SUCCESS)
1636 {
1637 i = 0;
1638 while (1)
1639 {
1640 r = RegEnumKeyW(hkeycm, i++, szguid, ARRAY_SIZE(szguid));
1641 if (r != ERROR_SUCCESS)
1642 break;
1643
1644 hr = CLSIDFromString(szguid, &guid);
1645 if (SUCCEEDED(hr))
1646 {
1647 /* stop at the first one that succeeds in running */
1648 hr = shellex_load_object_and_run(hkey, &guid, sei);
1649 if (SUCCEEDED(hr))
1650 break;
1651 }
1652 }
1653 RegCloseKey(hkeycm);
1654 }
1655
1656 if (hkey != sei->hkeyClass)
1657 RegCloseKey(hkey);
1658 return r;
1659}
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3268
LONG WINAPI RegEnumKeyW(HKEY hKey, DWORD dwIndex, LPWSTR lpName, DWORD cbName)
Definition: reg.c:2393
HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id)
Definition: compobj.c:2338
static HRESULT shellex_load_object_and_run(HKEY hkey, LPCGUID guid, LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:1480
static HKEY ShellExecute_GetClassKey(const SHELLEXECUTEINFOW *sei)
Definition: shlexec.cpp:1340
#define ERROR_FUNCTION_FAILED
Definition: winerror.h:985

Referenced by SHELL_execute().

◆ ShellExecute_GetClassKey()

static HKEY ShellExecute_GetClassKey ( const SHELLEXECUTEINFOW sei)
static

Definition at line 1340 of file shlexec.cpp.

1341{
1342 LPCWSTR ext = NULL, lpClass = NULL;
1344 DWORD type = 0, sz = 0;
1345 HKEY hkey = 0;
1346 LONG r;
1347
1348 if (sei->fMask & SEE_MASK_CLASSALL)
1349 return sei->hkeyClass;
1350
1351 if (sei->fMask & SEE_MASK_CLASSNAME)
1352 lpClass = sei->lpClass;
1353 else
1354 {
1356 TRACE("ext = %s\n", debugstr_w(ext));
1357 if (!ext)
1358 return hkey;
1359
1361 if (r != ERROR_SUCCESS)
1362 return hkey;
1363
1364 r = RegQueryValueExW(hkey, NULL, 0, &type, NULL, &sz);
1365 if (r == ERROR_SUCCESS && type == REG_SZ)
1366 {
1367 sz += sizeof (WCHAR);
1368 cls.Allocate(sz / sizeof(WCHAR));
1369 cls[0] = 0;
1370 RegQueryValueExW(hkey, NULL, 0, &type, (LPBYTE)(LPWSTR)cls, &sz);
1371 }
1372
1373 RegCloseKey( hkey );
1374 lpClass = cls;
1375 }
1376
1377 TRACE("class = %s\n", debugstr_w(lpClass));
1378
1379 hkey = 0;
1380 if (lpClass)
1381 RegOpenKeyW( HKEY_CLASSES_ROOT, lpClass, &hkey);
1382
1383 return hkey;
1384}
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
static const WCHAR *const ext[]
Definition: module.c:53
LPWSTR WINAPI PathFindExtensionW(LPCWSTR lpszPath)
Definition: path.c:447
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545

Referenced by ShellExecute_FromContextMenuHandlers().

◆ ShellExecute_Normal()

static DWORD ShellExecute_Normal ( _Inout_ LPSHELLEXECUTEINFOW  sei)
static

Definition at line 2373 of file shlexec.cpp.

2374{
2375 // FIXME
2377}
static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
Definition: shlexec.cpp:1942
static UINT_PTR SHELL_ExecuteW(const WCHAR *lpCmd, WCHAR *env, BOOL shWait, const SHELLEXECUTEINFOW *psei, LPSHELLEXECUTEINFOW psei_out)
Definition: shlexec.cpp:472

Referenced by ShellExecuteExW().

◆ ShellExecute_ShowError()

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

Definition at line 2380 of file shlexec.cpp.

2384{
2385 // FIXME: Show error message
2386}

Referenced by ShellExecuteExW().

◆ ShellExecuteA()

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

Definition at line 2343 of file shlexec.cpp.

2345{
2347
2348 TRACE("%p,%s,%s,%s,%s,%d\n",
2349 hWnd, debugstr_a(lpVerb), debugstr_a(lpFile),
2350 debugstr_a(lpParameters), debugstr_a(lpDirectory), iShowCmd);
2351
2352 sei.cbSize = sizeof(sei);
2354 sei.hwnd = hWnd;
2355 sei.lpVerb = lpVerb;
2356 sei.lpFile = lpFile;
2357 sei.lpParameters = lpParameters;
2359 sei.nShow = iShowCmd;
2360 sei.lpIDList = 0;
2361 sei.lpClass = 0;
2362 sei.hkeyClass = 0;
2363 sei.dwHotKey = 0;
2364 sei.hProcess = 0;
2365
2367 sei.fMask |= SEE_MASK_NOASYNC;
2368 ShellExecuteExA(&sei);
2369 return sei.hInstApp;
2370}
HWND hWnd
Definition: settings.c:17
DWORD WINAPI SHGetAppCompatFlags(DWORD dwUnknown)
Definition: ordinal.c:4544
#define SHACF_WIN95SHLEXEC

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

◆ ShellExecuteExA()

Definition at line 2394 of file shlexec.cpp.

2395{
2396 SHELLEXECUTEINFOW seiW;
2397 BOOL ret;
2398 WCHAR *wVerb = NULL, *wFile = NULL, *wParameters = NULL, *wDirectory = NULL, *wClass = NULL;
2399
2400 TRACE("%p\n", sei);
2401
2402 if (sei->cbSize != sizeof(SHELLEXECUTEINFOA))
2403 {
2406 return FALSE;
2407 }
2408
2409 memcpy(&seiW, sei, sizeof(SHELLEXECUTEINFOW));
2410
2411 seiW.cbSize = sizeof(SHELLEXECUTEINFOW);
2412
2413 if (sei->lpVerb)
2414 seiW.lpVerb = __SHCloneStrAtoW(&wVerb, sei->lpVerb);
2415
2416 if (sei->lpFile)
2417 seiW.lpFile = __SHCloneStrAtoW(&wFile, sei->lpFile);
2418
2419 if (sei->lpParameters)
2420 seiW.lpParameters = __SHCloneStrAtoW(&wParameters, sei->lpParameters);
2421
2422 if (sei->lpDirectory)
2423 seiW.lpDirectory = __SHCloneStrAtoW(&wDirectory, sei->lpDirectory);
2424
2425 if ((sei->fMask & SEE_MASK_CLASSALL) == SEE_MASK_CLASSNAME && sei->lpClass)
2426 seiW.lpClass = __SHCloneStrAtoW(&wClass, sei->lpClass);
2427 else
2428 seiW.lpClass = NULL;
2429
2430 ret = ShellExecuteExW(&seiW);
2431
2432 sei->hInstApp = seiW.hInstApp;
2433
2434 if (sei->fMask & SEE_MASK_NOCLOSEPROCESS)
2435 sei->hProcess = seiW.hProcess;
2436
2437 SHFree(wVerb);
2438 SHFree(wFile);
2439 SHFree(wParameters);
2440 SHFree(wDirectory);
2441 SHFree(wClass);
2442
2443 return ret;
2444}
struct _SHELLEXECUTEINFOW SHELLEXECUTEINFOW

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

◆ ShellExecuteExW()

Definition at line 2452 of file shlexec.cpp.

2453{
2454 HRESULT hrCoInit;
2455 DWORD dwError;
2456 ULONG fOldMask;
2457
2458 if (sei->cbSize != sizeof(SHELLEXECUTEINFOW))
2459 {
2462 return FALSE;
2463 }
2464
2465 hrCoInit = SHCoInitializeAnyApartment();
2466
2467 if (SHRegGetBoolUSValueW(L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer",
2468 L"MaximizeApps", FALSE, FALSE))
2469 {
2470 switch (sei->nShow)
2471 {
2472 case SW_SHOW:
2473 case SW_SHOWDEFAULT:
2474 case SW_SHOWNORMAL:
2475 case SW_RESTORE:
2476 sei->nShow = SW_SHOWMAXIMIZED;
2477 break;
2478 default:
2479 break;
2480 }
2481 }
2482
2483 fOldMask = sei->fMask;
2484
2485 if (!(fOldMask & SEE_MASK_NOASYNC) && SHELL_InRunDllProcess())
2487
2488 dwError = ShellExecute_Normal(sei);
2489
2490 if (dwError && dwError != ERROR_DLL_NOT_FOUND && dwError != ERROR_CANCELLED)
2491 ShellExecute_ShowError(sei, NULL, dwError);
2492
2493 sei->fMask = fOldMask;
2494
2495 if (SUCCEEDED(hrCoInit))
2497
2498 if (dwError)
2499 SetLastError(dwError);
2500
2501 return dwError == ERROR_SUCCESS;
2502}
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
HRESULT SHCoInitializeAnyApartment(VOID)
Definition: utils.cpp:468
BOOL WINAPI SHRegGetBoolUSValueW(LPCWSTR pszSubKey, LPCWSTR pszValue, BOOL fIgnoreHKCU, BOOL fDefault)
Definition: reg.c:770
#define SE_ERR_ACCESSDENIED
Definition: shellapi.h:128
#define SEE_MASK_WAITFORINPUTIDLE
Definition: shellapi.h:58
static DWORD ShellExecute_Normal(_Inout_ LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:2373
static VOID ShellExecute_ShowError(_In_ const SHELLEXECUTEINFOW *ExecInfo, _In_opt_ LPCWSTR pszCaption, _In_ DWORD dwError)
Definition: shlexec.cpp:2380
#define ERROR_DLL_NOT_FOUND
Definition: winerror.h:679
#define ERROR_CANCELLED
Definition: winerror.h:726
#define SW_SHOWNORMAL
Definition: winuser.h:773
#define SW_SHOWMAXIMIZED
Definition: winuser.h:776
#define SW_SHOWDEFAULT
Definition: winuser.h:783
#define SW_RESTORE
Definition: winuser.h:782
#define SW_SHOW
Definition: winuser.h:778

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

◆ ShellExecuteW()

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

Definition at line 2507 of file shlexec.cpp.

2509{
2511
2512 TRACE("\n");
2513 sei.cbSize = sizeof(sei);
2515 sei.hwnd = hwnd;
2516 sei.lpVerb = lpVerb;
2517 sei.lpFile = lpFile;
2518 sei.lpParameters = lpParameters;
2520 sei.nShow = nShowCmd;
2521 sei.lpIDList = 0;
2522 sei.lpClass = 0;
2523 sei.hkeyClass = 0;
2524 sei.dwHotKey = 0;
2525 sei.hProcess = 0;
2526
2528 sei.fMask |= SEE_MASK_NOASYNC;
2529 ShellExecuteExW(&sei);
2530 return sei.hInstApp;
2531}

Referenced by _RunHotplug(), _RunMMCpl(), _RunPower(), _RunVolume(), Control_StartApplet(), CPlApplet(), DIALOG_EXECUTE_DlgProc(), dialog_hyperlink_handler(), DisplayApplet(), CShellLink::DoOpenFileLocation(), CExeDropHandler::Drop(), CTrayWindow::ExecContextMenuCmd(), CTrayWindow::ExecResourceCmd(), CDrvDefExt::ExtraPageProc(), GeneralPageProc(), CDrvDefExt::GeneralPageProc(), CTrayWindow::HandleCommand(), CTrayWindow::HandleHotKey(), IHlink_fnNavigate(), CCPLItemMenu::InvokeCommand(), LanguagesPageProc(), 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(), SHELL_execute(), CShellDispatch::ShellExecute(), SHFindFiles(), SHRunControlPanel(), START_TEST(), StartRecDlgProc(), and TEST_Init().

◆ SplitParams()

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

Definition at line 2604 of file shlexec.cpp.

2605{
2606 LPCWSTR pch;
2607 size_t ich = 0;
2608 if (*psz == L'"')
2609 {
2610 // 1st argument is quoted. the string in quotes is quoted 1st argument.
2611 // [pch] --> [pszArg0+ich]
2612 for (pch = psz + 1; *pch && ich + 1 < cchArg0; ++ich, ++pch)
2613 {
2614 if (*pch == L'"' && pch[1] == L'"')
2615 {
2616 // doubled double quotations found!
2617 pszArg0[ich] = L'"';
2618 }
2619 else if (*pch == L'"')
2620 {
2621 // single double quotation found!
2622 ++pch;
2623 break;
2624 }
2625 else
2626 {
2627 // otherwise
2628 pszArg0[ich] = *pch;
2629 }
2630 }
2631 }
2632 else
2633 {
2634 // 1st argument is unquoted. non-space sequence is 1st argument.
2635 // [pch] --> [pszArg0+ich]
2636 for (pch = psz; *pch && !iswspace(*pch) && ich + 1 < cchArg0; ++ich, ++pch)
2637 {
2638 pszArg0[ich] = *pch;
2639 }
2640 }
2641 pszArg0[ich] = 0;
2642
2643 // skip space
2644 while (iswspace(*pch))
2645 ++pch;
2646
2647 return pch;
2648}
#define iswspace(_c)
Definition: ctype.h:669
#define pch(ap)
Definition: match.c:418

Referenced by ShellExecCmdLine().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( exec  )

◆ WOWShellExecute()

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

Definition at line 2538 of file shlexec.cpp.

2540{
2541 SHELLEXECUTEINFOW seiW;
2542 WCHAR *wVerb = NULL, *wFile = NULL, *wParameters = NULL, *wDirectory = NULL;
2543 HANDLE hProcess = 0;
2544
2545 seiW.lpVerb = lpVerb ? __SHCloneStrAtoW(&wVerb, lpVerb) : NULL;
2546 seiW.lpFile = lpFile ? __SHCloneStrAtoW(&wFile, lpFile) : NULL;
2547 seiW.lpParameters = lpParameters ? __SHCloneStrAtoW(&wParameters, lpParameters) : NULL;
2548 seiW.lpDirectory = lpDirectory ? __SHCloneStrAtoW(&wDirectory, lpDirectory) : NULL;
2549
2550 seiW.cbSize = sizeof(seiW);
2551 seiW.fMask = 0;
2552 seiW.hwnd = hWnd;
2553 seiW.nShow = iShowCmd;
2554 seiW.lpIDList = 0;
2555 seiW.lpClass = 0;
2556 seiW.hkeyClass = 0;
2557 seiW.dwHotKey = 0;
2558 seiW.hProcess = hProcess;
2559
2561
2562 SHFree(wVerb);
2563 SHFree(wFile);
2564 SHFree(wParameters);
2565 SHFree(wDirectory);
2566 return seiW.hInstApp;
2567}
_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:32