ReactOS 0.4.15-dev-6661-gcc6e444
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 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 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)
 
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)
 

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

930{
931 TRACE("dde_cb: %04x, %04x, %p, %p, %p, %p, %08lx, %08lx\n",
932 uType, uFmt, hConv, hsz1, hsz2, hData, dwData1, dwData2);
933 return NULL;
934}
#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 945 of file shlexec.cpp.

949{
950 WCHAR regkey[256];
951 WCHAR * endkey = regkey + wcslen(key);
952 WCHAR app[256], topic[256], ifexec[256], static_res[256];
953 WCHAR * dynamic_res=NULL;
954 WCHAR * res;
955 LONG applen, topiclen, ifexeclen;
956 WCHAR * exec;
957 DWORD ddeInst = 0;
958 DWORD tid;
959 DWORD resultLen, endkeyLen;
960 HSZ hszApp, hszTopic;
961 HCONV hConv;
962 HDDEDATA hDdeData;
963 unsigned ret = SE_ERR_NOASSOC;
964 BOOL unicode = !(GetVersion() & 0x80000000);
965
966 if (strlenW(key) + 1 > ARRAY_SIZE(regkey))
967 {
968 FIXME("input parameter %s larger than buffer\n", debugstr_w(key));
969 return 2;
970 }
971 wcscpy(regkey, key);
972 endkeyLen = ARRAY_SIZE(regkey) - (endkey - regkey);
973 if (strlenW(L"\\application") + 1 > endkeyLen)
974 {
975 FIXME("endkey %s overruns buffer\n", debugstr_w(L"\\application"));
976 return 2;
977 }
978 wcscpy(endkey, L"\\application");
979 applen = sizeof(app);
980 if (RegQueryValueW(HKEY_CLASSES_ROOT, regkey, app, &applen) != ERROR_SUCCESS)
981 {
982 WCHAR command[1024], fullpath[MAX_PATH];
983 LPWSTR ptr = NULL;
984 DWORD ret = 0;
985
986 /* Get application command from start string and find filename of application */
987 if (*start == '"')
988 {
989 if (strlenW(start + 1) + 1 > ARRAY_SIZE(command))
990 {
991 FIXME("size of input parameter %s larger than buffer\n",
992 debugstr_w(start + 1));
993 return 2;
994 }
995 wcscpy(command, start + 1);
996 if ((ptr = wcschr(command, '"')))
997 * ptr = 0;
998 ret = SearchPathW(NULL, command, L".exe", ARRAY_SIZE(fullpath), fullpath, &ptr);
999 }
1000 else
1001 {
1002 LPCWSTR p;
1003 LPWSTR space;
1004 for (p = start; (space = const_cast<LPWSTR>(strchrW(p, ' '))); p = space + 1)
1005 {
1006 int idx = space - start;
1007 memcpy(command, start, idx * sizeof(WCHAR));
1008 command[idx] = '\0';
1009 if ((ret = SearchPathW(NULL, command, L".exe", ARRAY_SIZE(fullpath), fullpath, &ptr)))
1010 break;
1011 }
1012 if (!ret)
1013 ret = SearchPathW(NULL, start, L".exe", ARRAY_SIZE(fullpath), fullpath, &ptr);
1014 }
1015
1016 if (!ret)
1017 {
1018 ERR("Unable to find application path for command %s\n", debugstr_w(start));
1019 return ERROR_ACCESS_DENIED;
1020 }
1021 if (strlenW(ptr) + 1 > ARRAY_SIZE(app))
1022 {
1023 FIXME("size of found path %s larger than buffer\n", debugstr_w(ptr));
1024 return 2;
1025 }
1026 wcscpy(app, ptr);
1027
1028 /* Remove extensions (including .so) */
1029 ptr = app + wcslen(app) - 3;
1030 if (ptr > app && !wcscmp(ptr, L".so"))
1031 *ptr = 0;
1032
1033 ptr = const_cast<LPWSTR>(strrchrW(app, '.'));
1034 assert(ptr);
1035 *ptr = 0;
1036 }
1037
1038 if (strlenW(L"\\topic") + 1 > endkeyLen)
1039 {
1040 FIXME("endkey %s overruns buffer\n", debugstr_w(L"\\topic"));
1041 return 2;
1042 }
1043 wcscpy(endkey, L"\\topic");
1044 topiclen = sizeof(topic);
1045 if (RegQueryValueW(HKEY_CLASSES_ROOT, regkey, topic, &topiclen) != ERROR_SUCCESS)
1046 {
1047 wcscpy(topic, L"System");
1048 }
1049
1050 if (unicode)
1051 {
1053 return 2;
1054 }
1055 else
1056 {
1058 return 2;
1059 }
1060
1063
1064 hConv = DdeConnect(ddeInst, hszApp, hszTopic, NULL);
1065 exec = ddeexec;
1066 if (!hConv)
1067 {
1068 TRACE("Launching %s\n", debugstr_w(start));
1069 ret = execfunc(start, env, TRUE, psei, psei_out);
1070 if (ret <= 32)
1071 {
1072 TRACE("Couldn't launch\n");
1073 goto error;
1074 }
1075 /* if ddeexec is NULL, then we just need to exit here */
1076 if (ddeexec == NULL)
1077 {
1078 TRACE("Exiting because ddeexec is NULL. ret=42.\n");
1079 /* See https://docs.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shellexecutew */
1080 /* for reason why we use 42 here and also "Shell32_apitest ShellExecuteW" regression test */
1081 return 42;
1082 }
1083 /* if ddeexec is 'empty string', then we just need to exit here */
1084 if (wcscmp(ddeexec, L"") == 0)
1085 {
1086 TRACE("Exiting because ddeexec is 'empty string'. ret=42.\n");
1087 /* See https://docs.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shellexecutew */
1088 /* for reason why we use 42 here and also "Shell32_apitest ShellExecuteW" regression test */
1089 return 42;
1090 }
1091 hConv = DdeConnect(ddeInst, hszApp, hszTopic, NULL);
1092 if (!hConv)
1093 {
1094 TRACE("Couldn't connect. ret=%d\n", ret);
1097 return 30; /* whatever */
1098 }
1099 if (strlenW(L"\\ifexec") + 1 > endkeyLen)
1100 {
1101 FIXME("endkey %s overruns buffer\n", debugstr_w(L"\\ifexec"));
1102 return 2;
1103 }
1104 strcpyW(endkey, L"\\ifexec");
1105 ifexeclen = sizeof(ifexec);
1106 if (RegQueryValueW(HKEY_CLASSES_ROOT, regkey, ifexec, &ifexeclen) == ERROR_SUCCESS)
1107 {
1108 exec = ifexec;
1109 }
1110 }
1111
1112 SHELL_ArgifyW(static_res, ARRAY_SIZE(static_res), exec, lpFile, pidl, szCommandline, &resultLen, NULL);
1113 if (resultLen > ARRAY_SIZE(static_res))
1114 {
1115 res = dynamic_res = static_cast<WCHAR *>(HeapAlloc(GetProcessHeap(), 0, resultLen * sizeof(WCHAR)));
1116 SHELL_ArgifyW(dynamic_res, resultLen, exec, lpFile, pidl, szCommandline, NULL, NULL);
1117 }
1118 else
1119 res = static_res;
1120 TRACE("%s %s => %s\n", debugstr_w(exec), debugstr_w(lpFile), debugstr_w(res));
1121
1122 /* It's documented in the KB 330337 that IE has a bug and returns
1123 * error DMLERR_NOTPROCESSED on XTYP_EXECUTE request.
1124 */
1125 if (unicode)
1126 hDdeData = DdeClientTransaction((LPBYTE)res, (strlenW(res) + 1) * sizeof(WCHAR), hConv, 0L, 0, XTYP_EXECUTE, 30000, &tid);
1127 else
1128 {
1129 DWORD lenA = WideCharToMultiByte(CP_ACP, 0, res, -1, NULL, 0, NULL, NULL);
1130 char *resA = (LPSTR)HeapAlloc(GetProcessHeap(), 0, lenA);
1131 WideCharToMultiByte(CP_ACP, 0, res, -1, resA, lenA, NULL, NULL);
1132 hDdeData = DdeClientTransaction( (LPBYTE)resA, lenA, hConv, 0L, 0,
1133 XTYP_EXECUTE, 10000, &tid );
1134 HeapFree(GetProcessHeap(), 0, resA);
1135 }
1136 if (hDdeData)
1137 DdeFreeDataHandle(hDdeData);
1138 else
1139 WARN("DdeClientTransaction failed with error %04x\n", DdeGetLastError(ddeInst));
1140 ret = 33;
1141
1142 HeapFree(GetProcessHeap(), 0, dynamic_res);
1143
1144 DdeDisconnect(hConv);
1145
1146error:
1148
1149 return ret;
1150}
#define ARRAY_SIZE(A)
Definition: main.h:33
#define FIXME(fmt,...)
Definition: debug.h:111
#define WARN(fmt,...)
Definition: debug.h:112
#define ERR(fmt,...)
Definition: debug.h:110
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:4256
#define wcschr
Definition: compat.h:17
#define GetProcessHeap()
Definition: compat.h:736
#define CP_ACP
Definition: compat.h:109
#define SetLastError(x)
Definition: compat.h:752
#define HeapAlloc
Definition: compat.h:733
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#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:44
#define strchrW(s, c)
Definition: unicode.h:34
#define strlenW(s)
Definition: unicode.h:28
#define strrchrW(s, c)
Definition: unicode.h:35
#define strcpyW(d, s)
Definition: unicode.h:29
DWORD WINAPI GetVersion()
Definition: redirtest.c:5
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
_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:132
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:927
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:184
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 1777 of file shlexec.cpp.

1778{
1779 WCHAR msg[2048];
1780 DWORD_PTR msgArguments[3] = { (DWORD_PTR)filename, 0, 0 };
1782
1784 if (retval == SE_ERR_NOASSOC)
1786 else
1788 NULL,
1789 error_code,
1791 msg,
1792 ARRAY_SIZE(msg),
1793 (va_list*)msgArguments);
1794
1796}
#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:186
#define LANG_USER_DEFAULT
Definition: tnerror.cpp:50
#define DWORD_PTR
Definition: treelist.c:76
uint32_t DWORD_PTR
Definition: typedefs.h:65
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:423
#define FORMAT_MESSAGE_ARGUMENT_ARRAY
Definition: winbase.h:424
_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:781

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

1159{
1160 WCHAR cmd[256], param[1024], ddeexec[256];
1161 DWORD cmdlen = sizeof(cmd), ddeexeclen = sizeof(ddeexec);
1162 UINT_PTR retval = SE_ERR_NOASSOC;
1163 DWORD resultLen;
1164 LPWSTR tmp;
1165
1166 TRACE("%s %s %s %s %s\n", debugstr_w(key), debugstr_w(lpFile), debugstr_w(env),
1167 debugstr_w(szCommandline), debugstr_w(executable_name));
1168
1169 cmd[0] = '\0';
1170 param[0] = '\0';
1171
1172 /* Get the application from the registry */
1174 {
1175 TRACE("got cmd: %s\n", debugstr_w(cmd));
1176
1177 /* Is there a replace() function anywhere? */
1178 cmdlen /= sizeof(WCHAR);
1179 if (cmdlen >= ARRAY_SIZE(cmd))
1180 cmdlen = ARRAY_SIZE(cmd) - 1;
1181 cmd[cmdlen] = '\0';
1182 SHELL_ArgifyW(param, ARRAY_SIZE(param), cmd, lpFile, (LPITEMIDLIST)psei->lpIDList, szCommandline, &resultLen,
1183 (psei->lpDirectory && *psei->lpDirectory) ? psei->lpDirectory : NULL);
1184 if (resultLen > ARRAY_SIZE(param))
1185 ERR("Argify buffer not large enough, truncating\n");
1186 }
1187
1188 /* Get the parameters needed by the application
1189 from the associated ddeexec key */
1190 tmp = const_cast<LPWSTR>(strstrW(key, L"command"));
1191 assert(tmp);
1192 wcscpy(tmp, L"ddeexec");
1193
1194 if (RegQueryValueW(HKEY_CLASSES_ROOT, key, ddeexec, (LONG *)&ddeexeclen) == ERROR_SUCCESS)
1195 {
1196 TRACE("Got ddeexec %s => %s\n", debugstr_w(key), debugstr_w(ddeexec));
1197 if (!param[0]) strcpyW(param, executable_name);
1198 retval = dde_connect(key, param, ddeexec, lpFile, env, szCommandline, (LPITEMIDLIST)psei->lpIDList, execfunc, psei, psei_out);
1199 }
1200 else if (param[0])
1201 {
1202 TRACE("executing: %s\n", debugstr_w(param));
1203 retval = execfunc(param, env, FALSE, psei, psei_out);
1204 }
1205 else
1206 WARN("Nothing appropriate found for %s\n", debugstr_w(key));
1207
1208 return retval;
1209}
#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:32
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:945
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
LPCWSTR lpDirectory
Definition: shellapi.h:331
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 1798 of file shlexec.cpp.

1799{
1800 WCHAR *buf;
1801 DWORD len;
1802
1804 if (!len) return NULL;
1805
1806 buf = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1807 if (!buf) return NULL;
1808
1810 if (!len)
1811 {
1813 return NULL;
1814 }
1815 return buf;
1816}
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 1214 of file shlexec.cpp.

1215{
1216 HINSTANCE retval;
1217 WCHAR *wFile = NULL, *wDirectory = NULL;
1218 WCHAR wResult[MAX_PATH];
1219
1220 if (lpFile) __SHCloneStrAtoW(&wFile, lpFile);
1221 if (lpDirectory) __SHCloneStrAtoW(&wDirectory, lpDirectory);
1222
1223 retval = FindExecutableW(wFile, wDirectory, wResult);
1224 WideCharToMultiByte(CP_ACP, 0, wResult, -1, lpResult, MAX_PATH, NULL, NULL);
1225 SHFree(wFile);
1226 SHFree(wDirectory);
1227
1228 TRACE("returning %s\n", lpResult);
1229 return retval;
1230}
void WINAPI SHFree(LPVOID pv)
Definition: shellole.c:326
static __inline LPWSTR __SHCloneStrAtoW(WCHAR **target, const char *source)
Definition: shell32_main.h:160
_In_opt_ LPCSTR lpDirectory
Definition: shellapi.h:481
HINSTANCE WINAPI FindExecutableW(LPCWSTR lpFile, LPCWSTR lpDirectory, LPWSTR lpResult)
Definition: shlexec.cpp:1257

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

◆ FindExecutableW()

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

Definition at line 1257 of file shlexec.cpp.

1258{
1259 UINT_PTR retval = SE_ERR_NOASSOC;
1260 WCHAR old_dir[1024];
1262
1263 TRACE("File %s, Dir %s\n", debugstr_w(lpFile), debugstr_w(lpDirectory));
1264
1265 lpResult[0] = '\0'; /* Start off with an empty return string */
1266 if (lpFile == NULL)
1267 return (HINSTANCE)SE_ERR_FNF;
1268
1269 if (lpDirectory)
1270 {
1271 GetCurrentDirectoryW(ARRAY_SIZE(old_dir), old_dir);
1273 }
1274
1275 retval = SHELL_FindExecutable(lpDirectory, lpFile, L"open", res, MAX_PATH, NULL, NULL, NULL, NULL);
1276 if (retval > 32)
1277 strcpyW(lpResult, res);
1278
1279 TRACE("returning %s\n", debugstr_w(lpResult));
1280 if (lpDirectory)
1281 SetCurrentDirectoryW(old_dir);
1282 return (HINSTANCE)retval;
1283}
#define GetCurrentDirectoryW(x, y)
Definition: compat.h:756
BOOL WINAPI SetCurrentDirectoryW(IN LPCWSTR lpPathName)
Definition: path.c:2249
#define SE_ERR_FNF
Definition: shellapi.h:122
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:732

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

◆ OpenAs_RunDLLA()

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

Definition at line 2427 of file shlexec.cpp.

2428{
2429 LPWSTR pszCmdLineW = NULL;
2430 TRACE("%p, %p, %s, %d\n", hwnd, hinst, debugstr_a(cmdline), cmdshow);
2431
2432 if (cmdline)
2433 __SHCloneStrAtoW(&pszCmdLineW, cmdline);
2434 OpenAs_RunDLLW(hwnd, hinst, pszCmdLineW, cmdshow);
2435 SHFree(pszCmdLineW);
2436}
#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:2410
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 2410 of file shlexec.cpp.

2411{
2413 TRACE("%p, %p, %s, %d\n", hwnd, hinst, debugstr_w(cmdline), cmdshow);
2414
2415 ZeroMemory(&info, sizeof(info));
2416 info.pcszFile = cmdline;
2417 info.pcszClass = NULL;
2419
2421}
HRESULT WINAPI SHOpenWithDialog(HWND hwndParent, const OPENASINFO *poainfo)
@ OAIF_EXEC
Definition: shlobj.h:2538
@ OAIF_REGISTER_EXT
Definition: shlobj.h:2537
@ OAIF_ALLOW_REGISTRATION
Definition: shlobj.h:2536
#define ZeroMemory
Definition: winbase.h:1700

Referenced by OpenAs_RunDLLA().

◆ ParseNoTildeEffect()

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

Definition at line 35 of file shlexec.cpp.

36{
37 bool firstCharQuote = false;
38 bool quotes_opened = false;
39 bool backslash_encountered = false;
40
41 for (int curArg = 0; curArg <= argNum && *args; ++curArg)
42 {
43 firstCharQuote = false;
44 if (*args == '"')
45 {
46 quotes_opened = true;
47 firstCharQuote = true;
48 args++;
49 }
50
51 while(*args)
52 {
53 if (*args == '\\')
54 {
55 // if we found a backslash then flip the variable
56 backslash_encountered = !backslash_encountered;
57 }
58 else if (*args == '"')
59 {
60 if (quotes_opened)
61 {
62 if (*(args + 1) != '"')
63 {
64 quotes_opened = false;
65 args++;
66 break;
67 }
68 else
69 {
70 args++;
71 }
72 }
73 else
74 {
75 quotes_opened = true;
76 }
77
78 backslash_encountered = false;
79 }
80 else
81 {
82 backslash_encountered = false;
83 if (*args == ' ' && !firstCharQuote)
84 break;
85 }
86
87 if (curArg == argNum)
88 {
89 used++;
90 if (used < len)
91 *res++ = *args;
92 }
93
94 args++;
95 }
96
97 while(*args == ' ')
98 ++args;
99 }
100}
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 102 of file shlexec.cpp.

103{
104 bool quotes_opened = false;
105 bool backslash_encountered = false;
106
107 for (int curArg = 0; curArg <= argNum && *args; ++curArg)
108 {
109 while(*args)
110 {
111 if (*args == '\\')
112 {
113 // if we found a backslash then flip the variable
114 backslash_encountered = !backslash_encountered;
115 }
116 else if (*args == '"')
117 {
118 if (quotes_opened)
119 {
120 if (*(args + 1) != '"')
121 {
122 quotes_opened = false;
123 }
124 else
125 {
126 args++;
127 }
128 }
129 else
130 {
131 quotes_opened = true;
132 }
133
134 backslash_encountered = false;
135 }
136 else
137 {
138 backslash_encountered = false;
139 if (*args == ' ' && !quotes_opened && curArg != argNum)
140 break;
141 }
142
143 if (curArg == argNum)
144 {
145 used++;
146 if (used < len)
147 *res++ = *args;
148 }
149
150 args++;
151 }
152 }
153}

Referenced by SHELL_ArgifyW().

◆ PathIsExeW()

EXTERN_C BOOL PathIsExeW ( LPCWSTR  lpszPath)

Definition at line 543 of file shellpath.c.

544{
545 LPCWSTR lpszExtension = PathGetExtensionW(lpszPath);
546 int i;
547 static const WCHAR lpszExtensions[][4] =
548 {L"exe", L"com", L"pif", L"cmd", L"bat", L"scf", L"scr", L"" };
549
550 TRACE("path=%s\n",debugstr_w(lpszPath));
551
552 for(i=0; lpszExtensions[i][0]; i++)
553 if (!wcsicmp(lpszExtension,lpszExtensions[i])) return TRUE;
554
555 return FALSE;
556}
#define wcsicmp
Definition: compat.h:15
static LPWSTR PathGetExtensionW(LPCWSTR lpszPath)
Definition: shellpath.c:438
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 PathIsExeAW(), and SHELL_execute().

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

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

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

547{
548 WCHAR *strings, *new_env;
549 WCHAR *p, *p2;
550 int total = wcslen(path) + 1;
551 BOOL got_path = FALSE;
552
553 if (!(strings = GetEnvironmentStringsW())) return NULL;
554 p = strings;
555 while (*p)
556 {
557 int len = wcslen(p) + 1;
558 if (!_wcsnicmp( p, L"PATH=", 5 )) got_path = TRUE;
559 total += len;
560 p += len;
561 }
562 if (!got_path) total += 5; /* we need to create PATH */
563 total++; /* terminating null */
564
565 if (!(new_env = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, total * sizeof(WCHAR))))
566 {
568 return NULL;
569 }
570 p = strings;
571 p2 = new_env;
572 while (*p)
573 {
574 int len = wcslen(p) + 1;
575 memcpy(p2, p, len * sizeof(WCHAR));
576 if (!_wcsnicmp( p, L"PATH=", 5 ))
577 {
578 p2[len - 1] = ';';
579 wcscpy( p2 + len, path );
580 p2 += wcslen(path) + 1;
581 }
582 p += len;
583 p2 += len;
584 }
585 if (!got_path)
586 {
587 wcscpy(p2, L"PATH=");
588 wcscat(p2, path);
589 p2 += wcslen(p2) + 1;
590 }
591 *p2 = 0;
593 return new_env;
594}
BOOL WINAPI FreeEnvironmentStringsW(IN LPWSTR EnvironmentStrings)
Definition: environ.c:389
size_t total
GLsizei const GLchar *const * strings
Definition: glext.h:7622
_CRTIMP wchar_t *__cdecl wcscat(_Inout_updates_z_(_String_length_(_Dest)+_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
_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 1821 of file shlexec.cpp.

1822{
1823 static const DWORD unsupportedFlags =
1827
1828 WCHAR parametersBuffer[1024], dirBuffer[MAX_PATH], wcmdBuffer[1024];
1829 WCHAR *wszApplicationName, *wszParameters, *wszDir, *wcmd;
1830 DWORD dwApplicationNameLen = MAX_PATH + 2;
1831 DWORD parametersLen = ARRAY_SIZE(parametersBuffer);
1832 DWORD dirLen = ARRAY_SIZE(dirBuffer);
1833 DWORD wcmdLen = ARRAY_SIZE(wcmdBuffer);
1834 DWORD len;
1835 SHELLEXECUTEINFOW sei_tmp; /* modifiable copy of SHELLEXECUTEINFO struct */
1836 WCHAR wfileName[MAX_PATH];
1837 WCHAR *env;
1838 WCHAR wszKeyname[256];
1839 LPCWSTR lpFile;
1840 UINT_PTR retval = SE_ERR_NOASSOC;
1841 BOOL appKnownSingular = FALSE;
1842
1843 /* make a local copy of the LPSHELLEXECUTEINFO structure and work with this from now on */
1844 sei_tmp = *sei;
1845
1846 TRACE("mask=0x%08x hwnd=%p verb=%s file=%s parm=%s dir=%s show=0x%08x class=%s\n",
1847 sei_tmp.fMask, sei_tmp.hwnd, debugstr_w(sei_tmp.lpVerb),
1848 debugstr_w(sei_tmp.lpFile), debugstr_w(sei_tmp.lpParameters),
1849 debugstr_w(sei_tmp.lpDirectory), sei_tmp.nShow,
1850 ((sei_tmp.fMask & SEE_MASK_CLASSALL) == SEE_MASK_CLASSNAME) ?
1851 debugstr_w(sei_tmp.lpClass) : "not used");
1852
1853 sei->hProcess = NULL;
1854
1855 /* make copies of all path/command strings */
1856 if (!sei_tmp.lpFile)
1857 {
1858 wszApplicationName = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, dwApplicationNameLen * sizeof(WCHAR));
1859 *wszApplicationName = '\0';
1860 }
1861 else if (*sei_tmp.lpFile == '\"' && sei_tmp.lpFile[(len = strlenW(sei_tmp.lpFile))-1] == '\"')
1862 {
1863 if(len-1 >= dwApplicationNameLen)
1864 dwApplicationNameLen = len;
1865
1866 wszApplicationName = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, dwApplicationNameLen * sizeof(WCHAR));
1867 memcpy(wszApplicationName, sei_tmp.lpFile + 1, len * sizeof(WCHAR));
1868
1869 if(len > 2)
1870 wszApplicationName[len-2] = '\0';
1871 appKnownSingular = TRUE;
1872
1873 TRACE("wszApplicationName=%s\n", debugstr_w(wszApplicationName));
1874 }
1875 else
1876 {
1877 DWORD l = strlenW(sei_tmp.lpFile) + 1;
1878 if(l > dwApplicationNameLen) dwApplicationNameLen = l + 1;
1879 wszApplicationName = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, dwApplicationNameLen * sizeof(WCHAR));
1880 memcpy(wszApplicationName, sei_tmp.lpFile, l * sizeof(WCHAR));
1881
1882 if (wszApplicationName[2] == 0 && wszApplicationName[1] == L':' &&
1883 ((L'A' <= wszApplicationName[0] && wszApplicationName[0] <= L'Z') ||
1884 (L'a' <= wszApplicationName[0] && wszApplicationName[0] <= L'z')))
1885 {
1886 // 'C:' --> 'C:\'
1887 PathAddBackslashW(wszApplicationName);
1888 }
1889 }
1890
1891 wszParameters = parametersBuffer;
1892 if (sei_tmp.lpParameters)
1893 {
1894 len = lstrlenW(sei_tmp.lpParameters) + 1;
1895 if (len > parametersLen)
1896 {
1897 wszParameters = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1898 parametersLen = len;
1899 }
1900 strcpyW(wszParameters, sei_tmp.lpParameters);
1901 }
1902 else
1903 *wszParameters = L'\0';
1904
1905 wszDir = dirBuffer;
1906 if (sei_tmp.lpDirectory)
1907 {
1908 len = lstrlenW(sei_tmp.lpDirectory) + 1;
1909 if (len > dirLen)
1910 {
1911 wszDir = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1912 dirLen = len;
1913 }
1914 strcpyW(wszDir, sei_tmp.lpDirectory);
1915 }
1916 else
1917 *wszDir = L'\0';
1918
1919 /* adjust string pointers to point to the new buffers */
1920 sei_tmp.lpFile = wszApplicationName;
1921 sei_tmp.lpParameters = wszParameters;
1922 sei_tmp.lpDirectory = wszDir;
1923
1924 if (sei_tmp.fMask & unsupportedFlags)
1925 {
1926 FIXME("flags ignored: 0x%08x\n", sei_tmp.fMask & unsupportedFlags);
1927 }
1928
1929 /* process the IDList */
1930 if (sei_tmp.fMask & SEE_MASK_IDLIST &&
1932 {
1934
1936
1937 if (SUCCEEDED(hr))
1938 {
1939 hr = pSEH->Execute(&sei_tmp);
1940
1941 if (hr == S_OK)
1942 {
1943 HeapFree(GetProcessHeap(), 0, wszApplicationName);
1944 if (wszParameters != parametersBuffer)
1945 HeapFree(GetProcessHeap(), 0, wszParameters);
1946 if (wszDir != dirBuffer)
1947 HeapFree(GetProcessHeap(), 0, wszDir);
1948 return TRUE;
1949 }
1950 }
1951
1952 SHGetPathFromIDListW((LPCITEMIDLIST)sei_tmp.lpIDList, wszApplicationName);
1953 appKnownSingular = TRUE;
1954 TRACE("-- idlist=%p (%s)\n", sei_tmp.lpIDList, debugstr_w(wszApplicationName));
1955 }
1956
1957 if (sei_tmp.fMask & SEE_MASK_DOENVSUBST)
1958 {
1959 WCHAR *tmp;
1960
1961 tmp = expand_environment(sei_tmp.lpFile);
1962 if (!tmp)
1963 {
1964 return FALSE;
1965 }
1966 HeapFree(GetProcessHeap(), 0, wszApplicationName);
1967 sei_tmp.lpFile = wszApplicationName = tmp;
1968
1969 tmp = expand_environment(sei_tmp.lpDirectory);
1970 if (!tmp)
1971 {
1972 return FALSE;
1973 }
1974 if (wszDir != dirBuffer) HeapFree(GetProcessHeap(), 0, wszDir);
1975 sei_tmp.lpDirectory = wszDir = tmp;
1976 }
1977
1979 {
1981 if (SUCCEEDED(hr))
1982 {
1983 sei->hInstApp = (HINSTANCE)42;
1984 HeapFree(GetProcessHeap(), 0, wszApplicationName);
1985 if (wszParameters != parametersBuffer)
1986 HeapFree(GetProcessHeap(), 0, wszParameters);
1987 if (wszDir != dirBuffer)
1988 HeapFree(GetProcessHeap(), 0, wszDir);
1989 return TRUE;
1990 }
1991 }
1992
1993
1995 {
1996 sei->hInstApp = (HINSTANCE) 33;
1997 HeapFree(GetProcessHeap(), 0, wszApplicationName);
1998 if (wszParameters != parametersBuffer)
1999 HeapFree(GetProcessHeap(), 0, wszParameters);
2000 if (wszDir != dirBuffer)
2001 HeapFree(GetProcessHeap(), 0, wszDir);
2002 return TRUE;
2003 }
2004
2005 if (sei_tmp.fMask & SEE_MASK_CLASSALL)
2006 {
2007 retval = SHELL_execute_class(wszApplicationName, &sei_tmp, sei, execfunc);
2008 if (retval <= 32 && !(sei_tmp.fMask & SEE_MASK_FLAG_NO_UI))
2009 {
2011
2012 //FIXME
2013 // need full path
2014
2015 Info.pcszFile = wszApplicationName;
2016 Info.pcszClass = NULL;
2017 Info.oaifInFlags = OAIF_ALLOW_REGISTRATION | OAIF_EXEC;
2018
2019 //if (SHOpenWithDialog(sei_tmp.hwnd, &Info) != S_OK)
2021 do_error_dialog(retval, sei_tmp.hwnd, wszApplicationName);
2022 }
2023 HeapFree(GetProcessHeap(), 0, wszApplicationName);
2024 if (wszParameters != parametersBuffer)
2025 HeapFree(GetProcessHeap(), 0, wszParameters);
2026 if (wszDir != dirBuffer)
2027 HeapFree(GetProcessHeap(), 0, wszDir);
2028 return retval > 32;
2029 }
2030
2031 /* Has the IDList not yet been translated? */
2032 if (sei_tmp.fMask & SEE_MASK_IDLIST)
2033 {
2034 appKnownSingular = SHELL_translate_idlist( &sei_tmp, wszParameters,
2035 parametersLen,
2036 wszApplicationName,
2037 dwApplicationNameLen );
2038 }
2039
2040 /* convert file URLs */
2041 if (UrlIsFileUrlW(sei_tmp.lpFile))
2042 {
2043 LPWSTR buf;
2044 DWORD size;
2045
2046 size = MAX_PATH;
2047 buf = static_cast<LPWSTR>(HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR)));
2048 if (!buf || FAILED(PathCreateFromUrlW(sei_tmp.lpFile, buf, &size, 0)))
2049 {
2051 return SE_ERR_OOM;
2052 }
2053
2054 HeapFree(GetProcessHeap(), 0, wszApplicationName);
2055 wszApplicationName = buf;
2056 sei_tmp.lpFile = wszApplicationName;
2057 }
2058 else /* or expand environment strings (not both!) */
2059 {
2061 if (len > 0)
2062 {
2063 LPWSTR buf;
2064 buf = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
2065
2066 ExpandEnvironmentStringsW(sei_tmp.lpFile, buf, len + 1);
2067 HeapFree(GetProcessHeap(), 0, wszApplicationName);
2068 wszApplicationName = buf;
2069 /* appKnownSingular unmodified */
2070
2071 sei_tmp.lpFile = wszApplicationName;
2072 }
2073 }
2074
2075 if (*sei_tmp.lpDirectory)
2076 {
2078 if (len > 0)
2079 {
2080 LPWSTR buf;
2081 len++;
2082 buf = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2084 if (wszDir != dirBuffer)
2085 HeapFree(GetProcessHeap(), 0, wszDir);
2086 wszDir = buf;
2087 sei_tmp.lpDirectory = wszDir;
2088 }
2089 }
2090
2091 /* Else, try to execute the filename */
2092 TRACE("execute: %s,%s,%s\n", debugstr_w(wszApplicationName), debugstr_w(wszParameters), debugstr_w(wszDir));
2093
2094 /* separate out command line arguments from executable file name */
2095 if (!*sei_tmp.lpParameters && !appKnownSingular)
2096 {
2097 /* If the executable path is quoted, handle the rest of the command line as parameters. */
2098 if (sei_tmp.lpFile[0] == L'"')
2099 {
2100 LPWSTR src = wszApplicationName/*sei_tmp.lpFile*/ + 1;
2101 LPWSTR dst = wfileName;
2102 LPWSTR end;
2103
2104 /* copy the unquoted executable path to 'wfileName' */
2105 while(*src && *src != L'"')
2106 *dst++ = *src++;
2107
2108 *dst = L'\0';
2109
2110 if (*src == L'"')
2111 {
2112 end = ++src;
2113
2114 while(isspaceW(*src))
2115 ++src;
2116 }
2117 else
2118 end = src;
2119
2120 /* copy the parameter string to 'wszParameters' */
2121 strcpyW(wszParameters, src);
2122
2123 /* terminate previous command string after the quote character */
2124 *end = L'\0';
2125 lpFile = wfileName;
2126 }
2127 else
2128 {
2129 lpFile = sei_tmp.lpFile;
2130 }
2131 }
2132 else
2133 lpFile = sei_tmp.lpFile;
2134
2135 wcmd = wcmdBuffer;
2136
2137 /* Only execute if it has an executable extension */
2138 if (PathIsExeW(lpFile))
2139 {
2140 len = lstrlenW(wszApplicationName) + 3;
2141 if (sei_tmp.lpParameters[0])
2142 len += 1 + lstrlenW(wszParameters);
2143 if (len > wcmdLen)
2144 {
2145 wcmd = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2146 wcmdLen = len;
2147 }
2148 swprintf(wcmd, L"\"%s\"", wszApplicationName);
2149 if (sei_tmp.lpParameters[0])
2150 {
2151 strcatW(wcmd, L" ");
2152 strcatW(wcmd, wszParameters);
2153 }
2154
2155 retval = execfunc(wcmd, NULL, FALSE, &sei_tmp, sei);
2156 if (retval > 32)
2157 {
2158 HeapFree(GetProcessHeap(), 0, wszApplicationName);
2159 if (wszParameters != parametersBuffer)
2160 HeapFree(GetProcessHeap(), 0, wszParameters);
2161 if (wszDir != dirBuffer)
2162 HeapFree(GetProcessHeap(), 0, wszDir);
2163 if (wcmd != wcmdBuffer)
2164 HeapFree(GetProcessHeap(), 0, wcmd);
2165 return TRUE;
2166 }
2167 }
2168
2169 /* Else, try to find the executable */
2170 wcmd[0] = L'\0';
2171 retval = SHELL_FindExecutable(sei_tmp.lpDirectory, lpFile, sei_tmp.lpVerb, wcmd, wcmdLen, wszKeyname, &env, (LPITEMIDLIST)sei_tmp.lpIDList, sei_tmp.lpParameters);
2172 if (retval > 32) /* Found */
2173 {
2174 retval = SHELL_quote_and_execute(wcmd, wszParameters, wszKeyname,
2175 wszApplicationName, env, &sei_tmp,
2176 sei, execfunc);
2178 }
2179 else if (PathIsDirectoryW(lpFile))
2180 {
2181 WCHAR wExec[MAX_PATH];
2182 WCHAR * lpQuotedFile = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * (strlenW(lpFile) + 3));
2183
2184 if (lpQuotedFile)
2185 {
2186 retval = SHELL_FindExecutable(sei_tmp.lpDirectory, L"explorer",
2187 L"open", wExec, MAX_PATH,
2188 NULL, &env, NULL, NULL);
2189 if (retval > 32)
2190 {
2191 swprintf(lpQuotedFile, L"\"%s\"", lpFile);
2192 retval = SHELL_quote_and_execute(wExec, lpQuotedFile,
2193 wszKeyname,
2194 wszApplicationName, env,
2195 &sei_tmp, sei, execfunc);
2197 }
2198 HeapFree(GetProcessHeap(), 0, lpQuotedFile);
2199 }
2200 else
2201 retval = 0; /* Out of memory */
2202 }
2203 else if (PathIsURLW(lpFile)) /* File not found, check for URL */
2204 {
2205 retval = SHELL_execute_url(lpFile, wcmd, &sei_tmp, sei, execfunc );
2206 }
2207 /* Check if file specified is in the form www.??????.*** */
2208 else if (!strncmpiW(lpFile, L"www", 3))
2209 {
2210 /* if so, prefix lpFile with http:// and call ShellExecute */
2211 WCHAR lpstrTmpFile[256];
2212 strcpyW(lpstrTmpFile, L"http://");
2213 strcatW(lpstrTmpFile, lpFile);
2214 retval = (UINT_PTR)ShellExecuteW(sei_tmp.hwnd, sei_tmp.lpVerb, lpstrTmpFile, NULL, NULL, 0);
2215 }
2216
2217 TRACE("retval %lu\n", retval);
2218
2219 if (retval <= 32 && !(sei_tmp.fMask & SEE_MASK_FLAG_NO_UI))
2220 {
2222
2223 //FIXME
2224 // need full path
2225
2226 Info.pcszFile = wszApplicationName;
2227 Info.pcszClass = NULL;
2228 Info.oaifInFlags = OAIF_ALLOW_REGISTRATION | OAIF_EXEC;
2229
2230 //if (SHOpenWithDialog(sei_tmp.hwnd, &Info) != S_OK)
2232 do_error_dialog(retval, sei_tmp.hwnd, wszApplicationName);
2233 }
2234
2235 HeapFree(GetProcessHeap(), 0, wszApplicationName);
2236 if (wszParameters != parametersBuffer)
2237 HeapFree(GetProcessHeap(), 0, wszParameters);
2238 if (wszDir != dirBuffer)
2239 HeapFree(GetProcessHeap(), 0, wszDir);
2240 if (wcmd != wcmdBuffer)
2241 HeapFree(GetProcessHeap(), 0, wcmd);
2242
2243 sei->hInstApp = (HINSTANCE)(retval > 32 ? 33 : retval);
2244
2245 return retval > 32;
2246}
r l[0]
Definition: byte_order.h:168
#define lstrlenW
Definition: compat.h:750
LPWSTR WINAPI PathAddBackslashW(LPWSTR lpszPath)
Definition: path.c:294
HRESULT WINAPI PathCreateFromUrlW(LPCWSTR pszUrl, LPWSTR pszPath, LPDWORD pcchPath, DWORD dwReserved)
Definition: path.c:3355
BOOL WINAPI PathIsDirectoryW(LPCWSTR lpszPath)
Definition: path.c:1723
BOOL WINAPI PathIsURLW(LPCWSTR lpstrPath)
Definition: url.c:2432
GLuint GLuint end
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLenum src
Definition: glext.h:6340
GLenum GLenum dst
Definition: glext.h:6340
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
#define DBG_UNREFERENCED_LOCAL_VARIABLE(L)
Definition: ntbasedef.h:319
HRESULT WINAPI SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCITEMIDLIST *ppidlLast)
Definition: pidl.c:1341
BOOL WINAPI SHGetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath)
Definition: pidl.c:1298
#define strncmpiW(s1, s2, n)
Definition: unicode.h:40
#define strcatW(d, s)
Definition: unicode.h:30
#define isspaceW(n)
Definition: unicode.h:52
#define 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:53
#define SEE_MASK_CLASSNAME
Definition: shellapi.h:25
#define SEE_MASK_ASYNCOK
Definition: shellapi.h:52
#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:125
#define SEE_MASK_INVOKEIDLIST
Definition: shellapi.h:28
#define SEE_MASK_FLAG_NO_UI
Definition: shellapi.h:36
static UINT_PTR SHELL_execute_class(LPCWSTR wszApplicationName, LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out, SHELL_ExecuteW32 execfunc)
Definition: shlexec.cpp:1605
static HRESULT ShellExecute_ContextMenuVerb(LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:1508
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:1707
static LONG ShellExecute_FromContextMenuHandlers(LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:1561
#define SEE_MASK_CLASSALL
Definition: shlexec.cpp:30
static WCHAR * expand_environment(const WCHAR *str)
Definition: shlexec.cpp:1798
static UINT_PTR SHELL_execute_url(LPCWSTR lpFile, LPCWSTR wcmd, LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out, SHELL_ExecuteW32 execfunc)
Definition: shlexec.cpp:1743
EXTERN_C BOOL PathIsExeW(LPCWSTR lpszPath)
Definition: shellpath.c:543
static void do_error_dialog(UINT_PTR retval, HWND hwnd, WCHAR *filename)
Definition: shlexec.cpp:1777
HINSTANCE WINAPI ShellExecuteW(HWND hwnd, LPCWSTR lpVerb, LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd)
Definition: shlexec.cpp:2346
static BOOL SHELL_translate_idlist(LPSHELLEXECUTEINFOW sei, LPWSTR wszParameters, DWORD parametersLen, LPWSTR wszApplicationName, DWORD dwApplicationNameLen)
Definition: shlexec.cpp:1661
HRESULT hr
Definition: shlfolder.c:183
#define UrlIsFileUrlW(x)
Definition: shlwapi.h:1377
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
HINSTANCE hInstApp
Definition: shellapi.h:333
LPCWSTR lpParameters
Definition: shellapi.h:330
HANDLE HINSTANCE
Definition: typedefs.h:77
_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 ShellExecuteExA(), ShellExecuteExW(), ShellExecuteW(), 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 1605 of file shlexec.cpp.

1606{
1607 WCHAR execCmd[1024], classname[1024];
1608 /* launch a document by fileclass like 'WordPad.Document.1' */
1609 /* the Commandline contains 'c:\Path\wordpad.exe "%1"' */
1610 /* FIXME: wcmd should not be of a fixed size. Fixed to 1024, MAX_PATH is way too short! */
1611 ULONG cmask = (psei->fMask & SEE_MASK_CLASSALL);
1612 DWORD resultLen;
1613 BOOL done;
1614 UINT_PTR rslt;
1615
1616 /* FIXME: remove following block when SHELL_quote_and_execute supports hkeyClass parameter */
1617 if (cmask != SEE_MASK_CLASSNAME)
1618 {
1619 WCHAR wcmd[1024];
1621 (cmask == SEE_MASK_CLASSNAME) ? psei->lpClass : NULL,
1622 psei->lpVerb,
1623 execCmd, sizeof(execCmd));
1624
1625 /* FIXME: get the extension of lpFile, check if it fits to the lpClass */
1626 TRACE("SEE_MASK_CLASSNAME->%s, doc->%s\n", debugstr_w(execCmd), debugstr_w(wszApplicationName));
1627
1628 wcmd[0] = '\0';
1629 done = SHELL_ArgifyW(wcmd, ARRAY_SIZE(wcmd), execCmd, wszApplicationName, (LPITEMIDLIST)psei->lpIDList, NULL, &resultLen,
1630 (psei->lpDirectory && *psei->lpDirectory) ? psei->lpDirectory : NULL);
1631 if (!done && wszApplicationName[0])
1632 {
1633 strcatW(wcmd, L" ");
1634 if (*wszApplicationName != '"')
1635 {
1636 strcatW(wcmd, L"\"");
1637 strcatW(wcmd, wszApplicationName);
1638 strcatW(wcmd, L"\"");
1639 }
1640 else
1641 strcatW(wcmd, wszApplicationName);
1642 }
1643 if (resultLen > ARRAY_SIZE(wcmd))
1644 ERR("Argify buffer not large enough... truncating\n");
1645 return execfunc(wcmd, NULL, FALSE, psei, psei_out);
1646 }
1647
1648 strcpyW(classname, psei->lpClass);
1649 rslt = SHELL_FindExecutableByVerb(psei->lpVerb, NULL, classname, execCmd, sizeof(execCmd));
1650
1651 TRACE("SHELL_FindExecutableByVerb returned %u (%s, %s)\n", (unsigned int)rslt, debugstr_w(classname), debugstr_w(execCmd));
1652 if (33 > rslt)
1653 return rslt;
1654 rslt = SHELL_quote_and_execute( execCmd, L"", classname,
1655 wszApplicationName, NULL, psei,
1656 psei_out, execfunc );
1657 return rslt;
1658
1659}
WCHAR classname[128]
Definition: startup.c:15
BOOL HCR_GetExecuteCommandW(HKEY hkeyClass, LPCWSTR szClass, LPCWSTR szVerb, LPWSTR szDest, DWORD len)
Definition: classes.c:194
#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:664
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 1743 of file shlexec.cpp.

1744{
1745 UINT_PTR retval;
1746 WCHAR *lpstrProtocol;
1747 LPCWSTR lpstrRes;
1748 INT iSize;
1749 DWORD len;
1750
1751 lpstrRes = strchrW(lpFile, ':');
1752 if (lpstrRes)
1753 iSize = lpstrRes - lpFile;
1754 else
1755 iSize = strlenW(lpFile);
1756
1757 TRACE("Got URL: %s\n", debugstr_w(lpFile));
1758 /* Looking for ...<protocol>\shell<lpVerb>\command */
1759 len = iSize + lstrlenW(L"\\shell\\") + lstrlenW(L"\\command") + 1;
1760 if (psei->lpVerb && *psei->lpVerb)
1761 len += lstrlenW(psei->lpVerb);
1762 else
1763 len += lstrlenW(L"open");
1764 lpstrProtocol = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1765 memcpy(lpstrProtocol, lpFile, iSize * sizeof(WCHAR));
1766 lpstrProtocol[iSize] = '\0';
1767 strcatW(lpstrProtocol, L"\\shell\\");
1768 strcatW(lpstrProtocol, psei->lpVerb && *psei->lpVerb ? psei->lpVerb : L"open");
1769 strcatW(lpstrProtocol, L"\\command");
1770
1771 retval = execute_from_key(lpstrProtocol, lpFile, NULL, psei->lpParameters,
1772 wcmd, execfunc, psei, psei_out);
1773 HeapFree(GetProcessHeap(), 0, lpstrProtocol);
1774 return retval;
1775}
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:1155
int32_t INT
Definition: typedefs.h:58

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

467{
470 UINT_PTR retval = SE_ERR_NOASSOC;
471 UINT gcdret = 0;
472 WCHAR curdir[MAX_PATH];
473 DWORD dwCreationFlags;
474 const WCHAR *lpDirectory = NULL;
475
476 TRACE("Execute %s from directory %s\n", debugstr_w(lpCmd), debugstr_w(psei->lpDirectory));
477
478 /* make sure we don't fail the CreateProcess if the calling app passes in
479 * a bad working directory */
480 if (psei->lpDirectory && psei->lpDirectory[0])
481 {
484 lpDirectory = psei->lpDirectory;
485 }
486
487 /* ShellExecute specifies the command from psei->lpDirectory
488 * if present. Not from the current dir as CreateProcess does */
489 if (lpDirectory)
490 if ((gcdret = GetCurrentDirectoryW( MAX_PATH, curdir)))
492 ERR("cannot set directory %s\n", debugstr_w(lpDirectory));
493
495 startup.cb = sizeof(STARTUPINFOW);
497 startup.wShowWindow = psei->nShow;
498 dwCreationFlags = CREATE_UNICODE_ENVIRONMENT;
499 if (!(psei->fMask & SEE_MASK_NO_CONSOLE))
500 dwCreationFlags |= CREATE_NEW_CONSOLE;
501 startup.lpTitle = (LPWSTR)(psei->fMask & (SEE_MASK_HASLINKNAME | SEE_MASK_HASTITLE) ? psei->lpClass : NULL);
502
503 if (psei->fMask & SEE_MASK_HASLINKNAME)
504 startup.dwFlags |= STARTF_TITLEISLINKNAME;
505
506 if (CreateProcessW(NULL, (LPWSTR)lpCmd, NULL, NULL, FALSE, dwCreationFlags, env,
508 {
509 /* Give 30 seconds to the app to come up, if desired. Probably only needed
510 when starting app immediately before making a DDE connection. */
511 if (shWait)
512 if (WaitForInputIdle(info.hProcess, 30000) == WAIT_FAILED)
513 WARN("WaitForInputIdle failed: Error %d\n", GetLastError() );
514 retval = 33;
515
516 if (psei->fMask & SEE_MASK_NOCLOSEPROCESS)
517 psei_out->hProcess = info.hProcess;
518 else
519 CloseHandle( info.hProcess );
520 CloseHandle( info.hThread );
521 }
522 else if ((retval = GetLastError()) >= 32)
523 {
524 WARN("CreateProcess returned error %ld\n", retval);
525 retval = ERROR_BAD_FORMAT;
526 }
527
528 TRACE("returning %lu\n", retval);
529
530 psei_out->hInstApp = (HINSTANCE)retval;
531
532 if (gcdret)
533 if (!SetCurrentDirectoryW(curdir))
534 ERR("cannot return to directory %s\n", debugstr_w(curdir));
535
536 return retval;
537}
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:4592
unsigned int UINT
Definition: ndis.h:50
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define SEE_MASK_NOCLOSEPROCESS
Definition: shellapi.h:31
#define SEE_MASK_HASTITLE
Definition: shellapi.h:49
#define SEE_MASK_NO_CONSOLE
Definition: shellapi.h:38
#define SEE_MASK_HASLINKNAME
Definition: shellapi.h:48
Definition: cookie.c:202
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
#define STARTF_USESHOWWINDOW
Definition: winbase.h:491
#define CREATE_UNICODE_ENVIRONMENT
Definition: winbase.h:186
#define WAIT_FAILED
Definition: winbase.h:413
#define CREATE_NEW_CONSOLE
Definition: winbase.h:180
struct _STARTUPINFOW STARTUPINFOW
#define ERROR_BAD_FORMAT
Definition: winerror.h:114
DWORD WINAPI WaitForInputIdle(_In_ HANDLE, _In_ DWORD)

Referenced by ShellExecuteExA(), ShellExecuteExW(), and ShellExecuteW().

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

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

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

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

Referenced by SHELL_execute_class(), and SHELL_FindExecutable().

◆ SHELL_GetPathFromIDListForExecuteW()

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

Definition at line 443 of file shlexec.cpp.

444{
445 STRRET strret;
446 CComPtr<IShellFolder> desktop;
447
448 HRESULT hr = SHGetDesktopFolder(&desktop);
449
450 if (SUCCEEDED(hr))
451 {
452 hr = desktop->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &strret);
453
454 if (SUCCEEDED(hr))
455 StrRetToStrNW(pszPath, uOutSize, &strret, pidl);
456 }
457
458 return hr;
459}
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_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 1707 of file shlexec.cpp.

1708{
1709 UINT_PTR retval;
1710 DWORD len;
1711 WCHAR *wszQuotedCmd;
1712
1713 /* Length of quotes plus length of command plus NULL terminator */
1714 len = 2 + lstrlenW(wcmd) + 1;
1715 if (wszParameters[0])
1716 {
1717 /* Length of space plus length of parameters */
1718 len += 1 + lstrlenW(wszParameters);
1719 }
1720 wszQuotedCmd = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1721 /* Must quote to handle case where cmd contains spaces,
1722 * else security hole if malicious user creates executable file "C:\\Program"
1723 */
1724 strcpyW(wszQuotedCmd, L"\"");
1725 strcatW(wszQuotedCmd, wcmd);
1726 strcatW(wszQuotedCmd, L"\"");
1727 if (wszParameters[0])
1728 {
1729 strcatW(wszQuotedCmd, L" ");
1730 strcatW(wszQuotedCmd, wszParameters);
1731 }
1732
1733 TRACE("%s/%s => %s/%s\n", debugstr_w(wszApplicationName), debugstr_w(psei->lpVerb), debugstr_w(wszQuotedCmd), debugstr_w(wszKeyname));
1734
1735 if (*wszKeyname)
1736 retval = execute_from_key(wszKeyname, wszApplicationName, env, psei->lpParameters, wcmd, execfunc, psei, psei_out);
1737 else
1738 retval = execfunc(wszQuotedCmd, env, FALSE, psei, psei_out);
1739 HeapFree(GetProcessHeap(), 0, wszQuotedCmd);
1740 return retval;
1741}

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

1662{
1664 BOOL appKnownSingular = FALSE;
1665
1666 /* last chance to translate IDList: now also allow CLSID paths */
1668 if (buffer[0] == ':' && buffer[1] == ':') {
1669 /* open shell folder for the specified class GUID */
1670 if (strlenW(buffer) + 1 > parametersLen)
1671 ERR("parameters len exceeds buffer size (%i > %i), truncating\n",
1672 lstrlenW(buffer) + 1, parametersLen);
1673 lstrcpynW(wszParameters, buffer, parametersLen);
1674 if (strlenW(L"explorer.exe") > dwApplicationNameLen)
1675 ERR("application len exceeds buffer size (%i), truncating\n",
1676 dwApplicationNameLen);
1677 lstrcpynW(wszApplicationName, L"explorer.exe", dwApplicationNameLen);
1678 appKnownSingular = TRUE;
1679
1680 sei->fMask &= ~SEE_MASK_INVOKEIDLIST;
1681 } else {
1683 DWORD attribs;
1684 DWORD resultLen;
1685 /* Check if we're executing a directory and if so use the
1686 handler for the Folder class */
1691 HCR_GetExecuteCommandW(0, L"Folder",
1692 sei->lpVerb,
1693 buffer, sizeof(buffer))) {
1694 SHELL_ArgifyW(wszApplicationName, dwApplicationNameLen,
1695 buffer, target, (LPITEMIDLIST)sei->lpIDList, NULL, &resultLen,
1696 (sei->lpDirectory && *sei->lpDirectory) ? sei->lpDirectory : NULL);
1697 if (resultLen > dwApplicationNameLen)
1698 ERR("Argify buffer not large enough... truncating\n");
1699 appKnownSingular = FALSE;
1700 }
1701 sei->fMask &= ~SEE_MASK_INVOKEIDLIST;
1702 }
1703 }
1704 return appKnownSingular;
1705}
#define lstrcpynW
Definition: compat.h:738
GLuint buffer
Definition: glext.h:5915
GLenum target
Definition: glext.h:7315
static HRESULT SHELL_GetPathFromIDListForExecuteW(LPCITEMIDLIST pidl, LPWSTR pszPath, UINT uOutSize)
Definition: shlexec.cpp:443

Referenced by SHELL_execute().

◆ SHELL_TryAppPathW()

static BOOL SHELL_TryAppPathW ( LPCWSTR  szName,
LPWSTR  lpResult,
WCHAR **  env 
)
static

Definition at line 604 of file shlexec.cpp.

605{
606 HKEY hkApp = NULL;
607 WCHAR buffer[1024];
608 DWORD len, dwType;
609 LONG res;
610 BOOL found = FALSE;
611
612 if (env) *env = NULL;
613 wcscpy(buffer, L"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\");
616 if (res)
617 {
618 // Add ".exe" extension, if extension does not exists
619 if (PathAddExtensionW(buffer, L".exe"))
620 {
622 }
623 if (res) goto end;
624 }
625
626 len = MAX_PATH * sizeof(WCHAR);
627 res = SHRegQueryValueExW(hkApp, NULL, NULL, &dwType, (LPBYTE)lpResult, &len);
628 if (res != ERROR_SUCCESS || dwType != REG_SZ)
629 goto end;
630
631 found = TRUE;
632
633 if (env)
634 {
635 len = sizeof(buffer);
636 res = SHRegQueryValueExW(hkApp, L"Path", NULL, &dwType, (LPBYTE)buffer, &len);
637 if (res == ERROR_SUCCESS && dwType == REG_SZ && buffer[0])
639 }
640
641end:
642 if (hkApp) RegCloseKey(hkApp);
643 return found;
644}
BOOL WINAPI PathAddExtensionW(LPWSTR lpszPath, LPCWSTR lpszExtension)
Definition: path.c:2638
#define REG_SZ
Definition: layer.c:22
#define KEY_READ
Definition: nt_native.h:1023
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:107
static LPWSTR SHELL_BuildEnvW(const WCHAR *path)
Definition: shlexec.cpp:546
#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 1469 of file shlexec.cpp.

1470{
1471 CComHeapPtr<ITEMIDLIST> allocatedPidl;
1472 LPITEMIDLIST pidl = NULL;
1473
1474 if (sei->lpIDList)
1475 {
1476 pidl = (LPITEMIDLIST)sei->lpIDList;
1477 }
1478 else
1479 {
1480 SFGAOF sfga = 0;
1481 HRESULT hr = SHParseDisplayName(sei->lpFile, NULL, &allocatedPidl, SFGAO_STORAGECAPMASK, &sfga);
1482 if (FAILED(hr))
1483 {
1484 WCHAR Buffer[MAX_PATH] = {};
1485 // FIXME: MAX_PATH.....
1487 if (retval <= 32)
1488 return HRESULT_FROM_WIN32(retval);
1489
1490 hr = SHParseDisplayName(Buffer, NULL, &allocatedPidl, SFGAO_STORAGECAPMASK, &sfga);
1491 // This should not happen, we found it...
1493 return hr;
1494 }
1495
1496 pidl = allocatedPidl;
1497 }
1498
1500 LPCITEMIDLIST pidllast = NULL;
1501 HRESULT hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &shf), &pidllast);
1502 if (FAILED(hr))
1503 return hr;
1504
1505 return shf->GetUIObjectOf(NULL, 1, &pidllast, IID_NULL_PPV_ARG(IContextMenu, &cm));
1506}
Definition: bufpool.h:45
static IShellFolder IShellItem **static IBindCtx LPITEMIDLIST SFGAOF
Definition: ebrowser.c:83
HRESULT WINAPI SHParseDisplayName(LPCWSTR pszName, IBindCtx *pbc, LPITEMIDLIST *ppidl, SFGAOF sfgaoIn, SFGAOF *psfgaoOut)
Definition: pidl.c:1385
#define FAILED_UNEXPECTEDLY(hr)
Definition: shellutils.h:82
#define _countof(array)
Definition: sndvol32.h:68
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
#define IID_NULL_PPV_ARG(Itype, ppType)

Referenced by ShellExecute_ContextMenuVerb().

◆ shellex_get_dataobj()

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

Definition at line 1334 of file shlexec.cpp.

1335{
1336 CComHeapPtr<ITEMIDLIST> allocatedPidl;
1337 LPITEMIDLIST pidl = NULL;
1338
1339 if (sei->fMask & SEE_MASK_CLASSALL)
1340 {
1341 pidl = (LPITEMIDLIST)sei->lpIDList;
1342 }
1343 else
1344 {
1345 WCHAR fullpath[MAX_PATH];
1346 BOOL ret;
1347
1348 fullpath[0] = 0;
1349 ret = GetFullPathNameW(sei->lpFile, MAX_PATH, fullpath, NULL);
1350 if (!ret)
1352
1353 pidl = ILCreateFromPathW(fullpath);
1354 allocatedPidl.Attach(pidl);
1355 }
1356
1358 LPCITEMIDLIST pidllast = NULL;
1359 HRESULT hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &shf), &pidllast);
1361 return hr;
1362
1363 return shf->GetUIObjectOf(NULL, 1, &pidllast, IID_NULL_PPV_ARG(IDataObject, &dataObj));
1364}
void Attach(T *lp)
Definition: atlalloc.h:162
DWORD WINAPI GetFullPathNameW(IN LPCWSTR lpFileName, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart)
Definition: path.c:1106
LPITEMIDLIST WINAPI ILCreateFromPathW(LPCWSTR path)
Definition: pidl.c:986

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

1436{
1437 TRACE("%p %s %p\n", hkey, debugstr_guid(guid), sei);
1438
1439 CCoInit coInit;
1440
1441 if (FAILED_UNEXPECTEDLY(coInit.hr))
1442 return coInit.hr;
1443
1445 HRESULT hr = CoCreateInstance(*guid, NULL, CLSCTX_INPROC_SERVER,
1448 return hr;
1449
1450 CComPtr<IDataObject> dataobj;
1451 hr = shellex_get_dataobj(sei, dataobj);
1453 return hr;
1454
1455 hr = obj->Initialize(NULL, dataobj, hkey);
1457 return hr;
1458
1460 hr = obj->QueryInterface(IID_PPV_ARG(IObjectWithSite, &ows));
1462 return hr;
1463
1464 ows->SetSite(NULL);
1465
1467}
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:1366
static HRESULT shellex_get_dataobj(LPSHELLEXECUTEINFOW sei, CComPtr< IDataObject > &dataObj)
Definition: shlexec.cpp:1334

Referenced by ShellExecute_FromContextMenuHandlers().

◆ shellex_run_context_menu_default()

static HRESULT shellex_run_context_menu_default ( IShellExtInit obj,
LPSHELLEXECUTEINFOW  sei 
)
static

Definition at line 1366 of file shlexec.cpp.

1368{
1370 CMINVOKECOMMANDINFOEX ici;
1372 WCHAR string[0x80];
1373 INT i, n, def = -1;
1374 HMENU hmenu = 0;
1375 HRESULT r;
1376
1377 TRACE("%p %p\n", obj, sei);
1378
1379 r = obj->QueryInterface(IID_PPV_ARG(IContextMenu, &cm));
1380 if (FAILED(r))
1381 return r;
1382
1383 hmenu = CreateMenu();
1384 if (!hmenu)
1385 goto end;
1386
1387 /* the number of the last menu added is returned in r */
1388 r = cm->QueryContextMenu(hmenu, 0, 0x20, 0x7fff, CMF_DEFAULTONLY);
1389 if (FAILED(r))
1390 goto end;
1391
1393 for (i = 0; i < n; i++)
1394 {
1395 memset(&info, 0, sizeof(info));
1396 info.cbSize = sizeof info;
1398 info.dwTypeData = string;
1399 info.cch = sizeof string;
1400 string[0] = 0;
1402
1403 TRACE("menu %d %s %08x %08lx %08x %08x\n", i, debugstr_w(string),
1404 info.fState, info.dwItemData, info.fType, info.wID);
1405 if ((!sei->lpVerb && (info.fState & MFS_DEFAULT)) ||
1406 (sei->lpVerb && !lstrcmpiW(sei->lpVerb, string)))
1407 {
1408 def = i;
1409 break;
1410 }
1411 }
1412
1413 r = E_FAIL;
1414 if (def == -1)
1415 goto end;
1416
1417 memset(&ici, 0, sizeof ici);
1418 ici.cbSize = sizeof ici;
1419 ici.fMask = CMIC_MASK_UNICODE | (sei->fMask & (SEE_MASK_NO_CONSOLE | SEE_MASK_NOASYNC | SEE_MASK_ASYNCOK | SEE_MASK_FLAG_NO_UI));
1420 ici.nShow = sei->nShow;
1421 ici.lpVerb = MAKEINTRESOURCEA(def);
1422 ici.hwnd = sei->hwnd;
1423 ici.lpParametersW = sei->lpParameters;
1424
1425 r = cm->InvokeCommand((LPCMINVOKECOMMANDINFO)&ici);
1426
1427 TRACE("invoke command returned %08x\n", r);
1428
1429end:
1430 if (hmenu)
1431 DestroyMenu( hmenu );
1432 return r;
1433}
#define E_FAIL
Definition: ddrawi.h:102
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLdouble n
Definition: glext.h:7729
int WINAPI lstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:194
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:63
#define memset(x, y, z)
Definition: compat.h:39
#define SEE_MASK_NOASYNC
Definition: shellapi.h:33
static HMENU hmenu
Definition: win.c:66
#define MIIM_STRING
Definition: winuser.h:722
#define MIIM_ID
Definition: winuser.h:717
int WINAPI GetMenuItemCount(_In_opt_ HMENU)
HMENU WINAPI CreateMenu(void)
Definition: menu.c:829
#define MIIM_FTYPE
Definition: winuser.h:724
#define MIIM_STATE
Definition: winuser.h:716
#define MFS_DEFAULT
Definition: winuser.h:743
#define MAKEINTRESOURCEA(i)
Definition: winuser.h:581
BOOL WINAPI DestroyMenu(_In_ HMENU)
BOOL WINAPI GetMenuItemInfoW(_In_ HMENU, _In_ UINT, _In_ BOOL, _Inout_ LPMENUITEMINFOW)
#define MIIM_DATA
Definition: winuser.h:721

Referenced by shellex_load_object_and_run().

◆ ShellExecCmdLine()

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

Definition at line 2487 of file shlexec.cpp.

2494{
2497 LPCWSTR pszVerb = NULL;
2498 WCHAR szFile[MAX_PATH], szFile2[MAX_PATH];
2499 HRESULT hr;
2500 LPCWSTR pchParams;
2501 LPWSTR lpCommand = NULL;
2502
2503 if (pwszCommand == NULL)
2505 1, (ULONG_PTR*)pwszCommand);
2506
2507 __SHCloneStrW(&lpCommand, pwszCommand);
2508 StrTrimW(lpCommand, L" \t");
2509
2510 if (dwSeclFlags & SECL_NO_UI)
2512 if (dwSeclFlags & SECL_LOG_USAGE)
2514 if (dwSeclFlags & SECL_USE_IDLIST)
2516
2517 if (dwSeclFlags & SECL_RUNAS)
2518 {
2519 dwSize = 0;
2520 hr = AssocQueryStringW(0, ASSOCSTR_COMMAND, lpCommand, L"RunAs", NULL, &dwSize);
2521 if (SUCCEEDED(hr) && dwSize != 0)
2522 {
2523 pszVerb = L"runas";
2524 }
2525 }
2526
2527 if (PathIsURLW(lpCommand) || UrlIsW(lpCommand, URLIS_APPLIABLE))
2528 {
2529 StringCchCopyW(szFile, _countof(szFile), lpCommand);
2530 pchParams = NULL;
2531 }
2532 else
2533 {
2534 PCWSTR apPathList[2];
2535
2536 pchParams = SplitParams(lpCommand, szFile, _countof(szFile));
2537 if (szFile[0] != UNICODE_NULL && szFile[1] == L':' &&
2538 szFile[2] == UNICODE_NULL)
2539 {
2540 PathAddBackslashW(szFile);
2541 }
2542
2543 WCHAR szCurDir[MAX_PATH];
2544 GetCurrentDirectoryW(_countof(szCurDir), szCurDir);
2545 if (pwszStartDir)
2546 {
2547 SetCurrentDirectoryW(pwszStartDir);
2548 }
2549
2550 if (PathIsRelativeW(szFile) &&
2551 GetFullPathNameW(szFile, _countof(szFile2), szFile2, NULL) &&
2552 PathFileExistsW(szFile2))
2553 {
2554 StringCchCopyW(szFile, _countof(szFile), szFile2);
2555 }
2556
2557 apPathList[0] = pwszStartDir;
2558 apPathList[1] = NULL;
2559 PathFindOnPathExW(szFile, apPathList, WHICH_DEFAULT);
2560
2561 if (!(dwSeclFlags & SECL_ALLOW_NONEXE))
2562 {
2563 if (!GetBinaryTypeW(szFile, &dwType))
2564 {
2565 SHFree(lpCommand);
2566
2567 if (!(dwSeclFlags & SECL_NO_UI))
2568 {
2569 WCHAR szText[128 + MAX_PATH], szFormat[128];
2571 StringCchPrintfW(szText, _countof(szText), szFormat, szFile);
2572 MessageBoxW(hwnd, szText, NULL, MB_ICONERROR);
2573 }
2574 return CO_E_APPNOTFOUND;
2575 }
2576 }
2577 else
2578 {
2580 {
2581 SHFree(lpCommand);
2582
2583 if (!(dwSeclFlags & SECL_NO_UI))
2584 {
2585 WCHAR szText[128 + MAX_PATH], szFormat[128];
2587 StringCchPrintfW(szText, _countof(szText), szFormat, szFile);
2588 MessageBoxW(hwnd, szText, NULL, MB_ICONERROR);
2589 }
2591 }
2592 }
2593 }
2594
2595 ZeroMemory(&info, sizeof(info));
2596 info.cbSize = sizeof(info);
2597 info.fMask = dwFlags;
2598 info.hwnd = hwnd;
2599 info.lpVerb = pszVerb;
2600 info.lpFile = szFile;
2601 info.lpParameters = (pchParams && *pchParams) ? pchParams : NULL;
2602 info.lpDirectory = pwszStartDir;
2603 info.nShow = nShow;
2604 if (ShellExecuteExW(&info))
2605 {
2606 if (info.lpIDList)
2607 CoTaskMemFree(info.lpIDList);
2608
2609 SHFree(lpCommand);
2610
2611 return S_OK;
2612 }
2613
2614 dwError = GetLastError();
2615
2616 SHFree(lpCommand);
2617
2618 return HRESULT_FROM_WIN32(dwError);
2619}
#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
HRESULT WINAPI AssocQueryStringW(ASSOCF cfFlags, ASSOCSTR str, LPCWSTR pszAssoc, LPCWSTR pszExtra, LPWSTR pszOut, DWORD *pcchOut)
Definition: assoc.c:431
BOOL WINAPI PathFileExistsW(LPCWSTR lpszPath)
Definition: path.c:1777
BOOL WINAPI PathFindOnPathExW(LPWSTR lpszFile, LPCWSTR *lppszOtherDirs, DWORD dwWhich)
Definition: path.c:1351
BOOL WINAPI PathIsRelativeW(LPCWSTR lpszPath)
Definition: path.c:1579
BOOL WINAPI StrTrimW(LPWSTR lpszStr, LPCWSTR lpszTrim)
Definition: string.c:1869
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 UNICODE_NULL
static __inline void __SHCloneStrW(WCHAR **target, const WCHAR *source)
Definition: shell32_main.h:154
#define SEE_MASK_FLAG_LOG_USAGE
Definition: shellapi.h:57
static LPCWSTR SplitParams(LPCWSTR psz, LPWSTR pszArg0, size_t cchArg0)
Definition: shlexec.cpp:2441
BOOL WINAPI DECLSPEC_HOTPATCH ShellExecuteExW(LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:2335
@ ASSOCSTR_COMMAND
Definition: shlwapi.h:603
@ URLIS_APPLIABLE
Definition: shlwapi.h:1195
#define WHICH_DEFAULT
#define IDS_FILE_NOT_FOUND
Definition: shresdef.h:326
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define EXCEPTION_ACCESS_VIOLATION
Definition: winbase.h:311
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
#define CO_E_APPNOTFOUND
Definition: winerror.h:2808
#define EXCEPTION_NONCONTINUABLE
Definition: rtltypes.h:154

◆ ShellExecute_ContextMenuVerb()

static HRESULT ShellExecute_ContextMenuVerb ( LPSHELLEXECUTEINFOW  sei)
static

Definition at line 1508 of file shlexec.cpp.

1509{
1510 TRACE("%p\n", sei);
1511
1512 CCoInit coInit;
1513
1514 if (FAILED_UNEXPECTEDLY(coInit.hr))
1515 return coInit.hr;
1516
1520 return hr;
1521
1522 CComHeapPtr<char> verb, parameters;
1523 __SHCloneStrWtoA(&verb, sei->lpVerb);
1524 __SHCloneStrWtoA(&parameters, sei->lpParameters);
1525
1526 CMINVOKECOMMANDINFOEX ici = {};
1527 ici.cbSize = sizeof ici;
1529 ici.nShow = sei->nShow;
1530 ici.lpVerb = verb;
1531 ici.hwnd = sei->hwnd;
1532 ici.lpParameters = parameters;
1533
1534 HMENU hMenu = CreatePopupMenu();
1535 BOOL fDefault = !ici.lpVerb || !ici.lpVerb[0];
1536 hr = cm->QueryContextMenu(hMenu, 0, 1, 0x7fff, fDefault ? CMF_DEFAULTONLY : 0);
1537 if (!FAILED_UNEXPECTEDLY(hr))
1538 {
1539 if (fDefault)
1540 {
1541 INT uDefault = GetMenuDefaultItem(hMenu, FALSE, 0);
1542 uDefault = (uDefault != -1) ? uDefault - 1 : 0;
1543 ici.lpVerb = MAKEINTRESOURCEA(uDefault);
1544 }
1545
1546 hr = cm->InvokeCommand((LPCMINVOKECOMMANDINFO)&ici);
1547 if (!FAILED_UNEXPECTEDLY(hr))
1548 hr = S_OK;
1549 }
1550
1551 DestroyMenu(hMenu);
1552
1553 return hr;
1554}
static __inline void __SHCloneStrWtoA(char **target, const WCHAR *source)
Definition: shell32_main.h:147
static HRESULT shellex_get_contextmenu(LPSHELLEXECUTEINFOW sei, CComPtr< IContextMenu > &cm)
Definition: shlexec.cpp:1469
HMENU WINAPI CreatePopupMenu(void)
Definition: menu.c:838
UINT WINAPI GetMenuDefaultItem(_In_ HMENU hMenu, _In_ UINT fByPos, _In_ UINT gmdiFlags)

Referenced by SHELL_execute().

◆ ShellExecute_FromContextMenuHandlers()

static LONG ShellExecute_FromContextMenuHandlers ( LPSHELLEXECUTEINFOW  sei)
static

Definition at line 1561 of file shlexec.cpp.

1562{
1563 HKEY hkey, hkeycm = 0;
1564 WCHAR szguid[39];
1565 HRESULT hr;
1566 GUID guid;
1567 DWORD i;
1568 LONG r;
1569
1570 TRACE("%s\n", debugstr_w(sei->lpFile));
1571
1572 hkey = ShellExecute_GetClassKey(sei);
1573 if (!hkey)
1574 return ERROR_FUNCTION_FAILED;
1575
1576 r = RegOpenKeyW(hkey, L"shellex\\ContextMenuHandlers", &hkeycm);
1577 if (r == ERROR_SUCCESS)
1578 {
1579 i = 0;
1580 while (1)
1581 {
1582 r = RegEnumKeyW(hkeycm, i++, szguid, ARRAY_SIZE(szguid));
1583 if (r != ERROR_SUCCESS)
1584 break;
1585
1586 hr = CLSIDFromString(szguid, &guid);
1587 if (SUCCEEDED(hr))
1588 {
1589 /* stop at the first one that succeeds in running */
1590 hr = shellex_load_object_and_run(hkey, &guid, sei);
1591 if (SUCCEEDED(hr))
1592 break;
1593 }
1594 }
1595 RegCloseKey(hkeycm);
1596 }
1597
1598 if (hkey != sei->hkeyClass)
1599 RegCloseKey(hkey);
1600 return r;
1601}
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3288
LONG WINAPI RegEnumKeyW(HKEY hKey, DWORD dwIndex, LPWSTR lpName, DWORD cbName)
Definition: reg.c:2413
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:1435
static HKEY ShellExecute_GetClassKey(const SHELLEXECUTEINFOW *sei)
Definition: shlexec.cpp:1286
#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 1286 of file shlexec.cpp.

1287{
1288 LPCWSTR ext = NULL, lpClass = NULL;
1289 LPWSTR cls = NULL;
1290 DWORD type = 0, sz = 0;
1291 HKEY hkey = 0;
1292 LONG r;
1293
1294 if (sei->fMask & SEE_MASK_CLASSALL)
1295 return sei->hkeyClass;
1296
1297 if (sei->fMask & SEE_MASK_CLASSNAME)
1298 lpClass = sei->lpClass;
1299 else
1300 {
1302 TRACE("ext = %s\n", debugstr_w(ext));
1303 if (!ext)
1304 return hkey;
1305
1307 if (r != ERROR_SUCCESS)
1308 return hkey;
1309
1310 r = RegQueryValueExW(hkey, NULL, 0, &type, NULL, &sz);
1311 if (r == ERROR_SUCCESS && type == REG_SZ)
1312 {
1313 sz += sizeof (WCHAR);
1314 cls = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, sz);
1315 cls[0] = 0;
1316 RegQueryValueExW(hkey, NULL, 0, &type, (LPBYTE) cls, &sz);
1317 }
1318
1319 RegCloseKey( hkey );
1320 lpClass = cls;
1321 }
1322
1323 TRACE("class = %s\n", debugstr_w(lpClass));
1324
1325 hkey = 0;
1326 if (lpClass)
1327 RegOpenKeyW( HKEY_CLASSES_ROOT, lpClass, &hkey);
1328
1329 HeapFree(GetProcessHeap(), 0, cls);
1330
1331 return hkey;
1332}
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4118
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().

◆ ShellExecuteA()

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

Definition at line 2251 of file shlexec.cpp.

2253{
2255
2256 TRACE("%p,%s,%s,%s,%s,%d\n",
2257 hWnd, debugstr_a(lpVerb), debugstr_a(lpFile),
2258 debugstr_a(lpParameters), debugstr_a(lpDirectory), iShowCmd);
2259
2260 sei.cbSize = sizeof(sei);
2262 sei.hwnd = hWnd;
2263 sei.lpVerb = lpVerb;
2264 sei.lpFile = lpFile;
2265 sei.lpParameters = lpParameters;
2267 sei.nShow = iShowCmd;
2268 sei.lpIDList = 0;
2269 sei.lpClass = 0;
2270 sei.hkeyClass = 0;
2271 sei.dwHotKey = 0;
2272 sei.hProcess = 0;
2273
2274 ShellExecuteExA(&sei);
2275 return sei.hInstApp;
2276}
HWND hWnd
Definition: settings.c:17
BOOL WINAPI DECLSPEC_HOTPATCH ShellExecuteExA(LPSHELLEXECUTEINFOA sei)
Definition: shlexec.cpp:2285
LPCSTR lpParameters
Definition: shellapi.h:313
HINSTANCE hInstApp
Definition: shellapi.h:316
LPCSTR lpDirectory
Definition: shellapi.h:314

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

◆ ShellExecuteExA()

Definition at line 2285 of file shlexec.cpp.

2286{
2287 SHELLEXECUTEINFOW seiW;
2288 BOOL ret;
2289 WCHAR *wVerb = NULL, *wFile = NULL, *wParameters = NULL, *wDirectory = NULL, *wClass = NULL;
2290
2291 TRACE("%p\n", sei);
2292
2293 memcpy(&seiW, sei, sizeof(SHELLEXECUTEINFOW));
2294
2295 if (sei->lpVerb)
2296 seiW.lpVerb = __SHCloneStrAtoW(&wVerb, sei->lpVerb);
2297
2298 if (sei->lpFile)
2299 seiW.lpFile = __SHCloneStrAtoW(&wFile, sei->lpFile);
2300
2301 if (sei->lpParameters)
2302 seiW.lpParameters = __SHCloneStrAtoW(&wParameters, sei->lpParameters);
2303
2304 if (sei->lpDirectory)
2305 seiW.lpDirectory = __SHCloneStrAtoW(&wDirectory, sei->lpDirectory);
2306
2307 if ((sei->fMask & SEE_MASK_CLASSALL) == SEE_MASK_CLASSNAME && sei->lpClass)
2308 seiW.lpClass = __SHCloneStrAtoW(&wClass, sei->lpClass);
2309 else
2310 seiW.lpClass = NULL;
2311
2313
2314 sei->hInstApp = seiW.hInstApp;
2315
2316 if (sei->fMask & SEE_MASK_NOCLOSEPROCESS)
2317 sei->hProcess = seiW.hProcess;
2318
2319 SHFree(wVerb);
2320 SHFree(wFile);
2321 SHFree(wParameters);
2322 SHFree(wDirectory);
2323 SHFree(wClass);
2324
2325 return ret;
2326}
static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
Definition: shlexec.cpp:1821
static UINT_PTR SHELL_ExecuteW(const WCHAR *lpCmd, WCHAR *env, BOOL shWait, const SHELLEXECUTEINFOW *psei, LPSHELLEXECUTEINFOW psei_out)
Definition: shlexec.cpp:465

Referenced by DoTestEntry(), shell_execute_ex_(), and ShellExecuteA().

◆ ShellExecuteExW()

◆ ShellExecuteW()

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

Definition at line 2346 of file shlexec.cpp.

2348{
2350
2351 TRACE("\n");
2352 sei.cbSize = sizeof(sei);
2354 sei.hwnd = hwnd;
2355 sei.lpVerb = lpVerb;
2356 sei.lpFile = lpFile;
2357 sei.lpParameters = lpParameters;
2359 sei.nShow = nShowCmd;
2360 sei.lpIDList = 0;
2361 sei.lpClass = 0;
2362 sei.hkeyClass = 0;
2363 sei.dwHotKey = 0;
2364 sei.hProcess = 0;
2365
2367 return sei.hInstApp;
2368}

Referenced by _RunHotplug(), _RunMMCpl(), _RunPower(), _RunVolume(), CDesktopFolder::CallBack(), CDrivesFolder::CallBack(), Control_StartApplet(), CPlApplet(), DIALOG_EXECUTE_DlgProc(), DisplayApplet(), CShellLink::DoOpenFileLocation(), DoTestGroup(), CExeDropHandler::Drop(), CTrayWindow::ExecContextMenuCmd(), CTrayWindow::ExecResourceCmd(), CDrvDefExt::ExtraPageProc(), GeneralPageProc(), CDrvDefExt::GeneralPageProc(), CTrayWindow::HandleCommand(), CTrayWindow::HandleHotKey(), IHlink_fnNavigate(), CCPLItemMenu::InvokeCommand(), LanguagesPageProc(), LaunchDeviceManager(), LaunchSoundControl(), MainWnd_OnOpenRegKey(), msi_dialog_hyperlink_handler(), OnAddStartMenuItems(), OnAdvancedStartMenuItems(), CAppInfoDisplay::OnCommand(), CShellMenuCallback::OnExec(), CTrayClockWnd::OnLButtonDblClick(), OnLink(), OnNotify(), OnRemoveStartmenuItems(), CZipExtract::CCompleteSettingsPage::OnWizardFinish(), OpenShellFolder(), ProcessPage_OnOpenFileLocation(), PROGRAM_ExecuteProgram(), RegFolderContextMenuCallback(), RouteTheCall(), RunCommand(), SHELL_execute(), CShellDispatch::ShellExecute(), SHFindFiles(), SHRunControlPanel(), START_TEST(), and StartRecDlgProc().

◆ SplitParams()

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

Definition at line 2441 of file shlexec.cpp.

2442{
2443 LPCWSTR pch;
2444 size_t ich = 0;
2445 if (*psz == L'"')
2446 {
2447 // 1st argument is quoted. the string in quotes is quoted 1st argument.
2448 // [pch] --> [pszArg0+ich]
2449 for (pch = psz + 1; *pch && ich + 1 < cchArg0; ++ich, ++pch)
2450 {
2451 if (*pch == L'"' && pch[1] == L'"')
2452 {
2453 // doubled double quotations found!
2454 pszArg0[ich] = L'"';
2455 }
2456 else if (*pch == L'"')
2457 {
2458 // single double quotation found!
2459 ++pch;
2460 break;
2461 }
2462 else
2463 {
2464 // otherwise
2465 pszArg0[ich] = *pch;
2466 }
2467 }
2468 }
2469 else
2470 {
2471 // 1st argument is unquoted. non-space sequence is 1st argument.
2472 // [pch] --> [pszArg0+ich]
2473 for (pch = psz; *pch && !iswspace(*pch) && ich + 1 < cchArg0; ++ich, ++pch)
2474 {
2475 pszArg0[ich] = *pch;
2476 }
2477 }
2478 pszArg0[ich] = 0;
2479
2480 // skip space
2481 while (iswspace(*pch))
2482 ++pch;
2483
2484 return pch;
2485}
#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 2375 of file shlexec.cpp.

2377{
2378 SHELLEXECUTEINFOW seiW;
2379 WCHAR *wVerb = NULL, *wFile = NULL, *wParameters = NULL, *wDirectory = NULL;
2380 HANDLE hProcess = 0;
2381
2382 seiW.lpVerb = lpVerb ? __SHCloneStrAtoW(&wVerb, lpVerb) : NULL;
2383 seiW.lpFile = lpFile ? __SHCloneStrAtoW(&wFile, lpFile) : NULL;
2384 seiW.lpParameters = lpParameters ? __SHCloneStrAtoW(&wParameters, lpParameters) : NULL;
2385 seiW.lpDirectory = lpDirectory ? __SHCloneStrAtoW(&wDirectory, lpDirectory) : NULL;
2386
2387 seiW.cbSize = sizeof(seiW);
2388 seiW.fMask = 0;
2389 seiW.hwnd = hWnd;
2390 seiW.nShow = iShowCmd;
2391 seiW.lpIDList = 0;
2392 seiW.lpClass = 0;
2393 seiW.hkeyClass = 0;
2394 seiW.dwHotKey = 0;
2395 seiW.hProcess = hProcess;
2396
2398
2399 SHFree(wVerb);
2400 SHFree(wFile);
2401 SHFree(wParameters);
2402 SHFree(wDirectory);
2403 return seiW.hInstApp;
2404}
_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