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

Go to the source code of this file.

Macros

#define SEE_MASK_CLASSALL   (SEE_MASK_CLASSNAME | SEE_MASK_CLASSKEY)
 

Typedefs

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

Functions

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

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

946{
947 TRACE("dde_cb: %04x, %04x, %p, %p, %p, %p, %08lx, %08lx\n",
948 uType, uFmt, hConv, hsz1, hsz2, hData, dwData1, dwData2);
949 return NULL;
950}
#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 961 of file shlexec.cpp.

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

Referenced by execute_from_key().

◆ do_error_dialog()

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

Definition at line 1881 of file shlexec.cpp.

1882{
1883 WCHAR msg[2048];
1884 DWORD_PTR msgArguments[3] = { (DWORD_PTR)filename, 0, 0 };
1886
1888 if (retval == SE_ERR_NOASSOC)
1890 else
1892 NULL,
1893 error_code,
1895 msg,
1896 ARRAY_SIZE(msg),
1897 (va_list*)msgArguments);
1898
1900}
#define shell32_hInstance
char * va_list
Definition: acmsvcex.h:78
#define msg(x)
Definition: auth_time.c:54
DWORD WINAPI FormatMessageW(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPWSTR lpBuffer, DWORD nSize, __ms_va_list *args)
Definition: format_msg.c:583
const char * filename
Definition: ioapi.h:137
#define IDS_SHLEXEC_NOASSOC
Definition: shresdef.h:187
#define LANG_USER_DEFAULT
Definition: tnerror.cpp:50
#define DWORD_PTR
Definition: treelist.c:76
uint32_t DWORD_PTR
Definition: typedefs.h:65
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:790

Referenced by SHELL_execute().

◆ execute_from_key()

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

Definition at line 1170 of file shlexec.cpp.

1174{
1175 WCHAR cmd[256], param[1024], ddeexec[256];
1176 DWORD cmdlen = sizeof(cmd), ddeexeclen = sizeof(ddeexec);
1177 UINT_PTR retval = SE_ERR_NOASSOC;
1178 DWORD resultLen;
1179 LPWSTR tmp;
1180
1181 TRACE("%s %s %s %s %s\n", debugstr_w(key), debugstr_w(lpFile), debugstr_w(env),
1182 debugstr_w(szCommandline), debugstr_w(executable_name));
1183
1184 cmd[0] = '\0';
1185 param[0] = '\0';
1186
1187 /* Get the application from the registry */
1189 {
1190 TRACE("got cmd: %s\n", debugstr_w(cmd));
1191
1192 /* Is there a replace() function anywhere? */
1193 cmdlen /= sizeof(WCHAR);
1194 if (cmdlen >= ARRAY_SIZE(cmd))
1195 cmdlen = ARRAY_SIZE(cmd) - 1;
1196 cmd[cmdlen] = '\0';
1197 SHELL_ArgifyW(param, ARRAY_SIZE(param), cmd, lpFile, (LPITEMIDLIST)psei->lpIDList, szCommandline, &resultLen,
1198 (psei->lpDirectory && *psei->lpDirectory) ? psei->lpDirectory : NULL);
1199 if (resultLen > ARRAY_SIZE(param))
1200 ERR("Argify buffer not large enough, truncating\n");
1201 }
1202
1203 /* Get the parameters needed by the application
1204 from the associated ddeexec key */
1205 tmp = const_cast<LPWSTR>(strstrW(key, L"command"));
1206 assert(tmp);
1207 wcscpy(tmp, L"ddeexec");
1208
1209 if (RegQueryValueW(HKEY_CLASSES_ROOT, key, ddeexec, (LONG *)&ddeexeclen) == ERROR_SUCCESS)
1210 {
1211 TRACE("Got ddeexec %s => %s\n", debugstr_w(key), debugstr_w(ddeexec));
1212 if (!param[0]) strcpyW(param, executable_name);
1213 retval = dde_connect(key, param, ddeexec, lpFile, env, szCommandline, (LPITEMIDLIST)psei->lpIDList, execfunc, psei, psei_out);
1214 }
1215 else if (param[0])
1216 {
1217 TRACE("executing: %s\n", debugstr_w(param));
1218 retval = execfunc(param, env, FALSE, psei, psei_out);
1219 }
1220 else
1221 WARN("Nothing appropriate found for %s\n", debugstr_w(key));
1222
1223 return retval;
1224}
#define FALSE
Definition: types.h:117
GLfloat param
Definition: glext.h:5796
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
#define strstrW(d, s)
Definition: unicode.h:38
static unsigned dde_connect(const WCHAR *key, const WCHAR *start, WCHAR *ddeexec, const WCHAR *lpFile, WCHAR *env, LPCWSTR szCommandline, LPITEMIDLIST pidl, SHELL_ExecuteW32 execfunc, const SHELLEXECUTEINFOW *psei, LPSHELLEXECUTEINFOW psei_out)
Definition: shlexec.cpp:961
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
LPCWSTR lpDirectory
Definition: shellapi.h:334
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 1902 of file shlexec.cpp.

1903{
1905 DWORD len;
1906
1908 if (!len) return NULL;
1909
1910 if (!buf.Allocate(len))
1911 return NULL;
1912
1914 if (!len)
1915 return NULL;
1916
1917 return buf.Detach();
1918}
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 1229 of file shlexec.cpp.

1230{
1231 HINSTANCE retval;
1232 WCHAR *wFile = NULL, *wDirectory = NULL;
1233 WCHAR wResult[MAX_PATH];
1234
1235 if (lpFile) __SHCloneStrAtoW(&wFile, lpFile);
1236 if (lpDirectory) __SHCloneStrAtoW(&wDirectory, lpDirectory);
1237
1238 retval = FindExecutableW(wFile, wDirectory, wResult);
1239 WideCharToMultiByte(CP_ACP, 0, wResult, -1, lpResult, MAX_PATH, NULL, NULL);
1240 SHFree(wFile);
1241 SHFree(wDirectory);
1242
1243 TRACE("returning %s\n", lpResult);
1244 return retval;
1245}
void WINAPI SHFree(LPVOID pv)
Definition: shellole.c:326
static __inline LPWSTR __SHCloneStrAtoW(WCHAR **target, const char *source)
Definition: shell32_main.h:168
_In_opt_ LPCSTR lpDirectory
Definition: shellapi.h:484
HINSTANCE WINAPI FindExecutableW(LPCWSTR lpFile, LPCWSTR lpDirectory, LPWSTR lpResult)
Definition: shlexec.cpp:1272

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

◆ FindExecutableW()

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

Definition at line 1272 of file shlexec.cpp.

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

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

◆ OpenAs_RunDLLA()

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

Definition at line 2563 of file shlexec.cpp.

2564{
2565 LPWSTR pszCmdLineW = NULL;
2566 TRACE("%p, %p, %s, %d\n", hwnd, hinst, debugstr_a(cmdline), cmdshow);
2567
2568 if (cmdline)
2569 __SHCloneStrAtoW(&pszCmdLineW, cmdline);
2570 OpenAs_RunDLLW(hwnd, hinst, pszCmdLineW, cmdshow);
2571 SHFree(pszCmdLineW);
2572}
#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:2546
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 2546 of file shlexec.cpp.

2547{
2549 TRACE("%p, %p, %s, %d\n", hwnd, hinst, debugstr_w(cmdline), cmdshow);
2550
2551 ZeroMemory(&info, sizeof(info));
2552 info.pcszFile = cmdline;
2553 info.pcszClass = NULL;
2555
2557}
HRESULT WINAPI SHOpenWithDialog(HWND hwndParent, const OPENASINFO *poainfo)
@ OAIF_EXEC
Definition: shlobj.h:2682
@ OAIF_REGISTER_EXT
Definition: shlobj.h:2681
@ OAIF_ALLOW_REGISTRATION
Definition: shlobj.h:2680
#define ZeroMemory
Definition: winbase.h:1712

Referenced by OpenAs_RunDLLA().

◆ ParseNoTildeEffect()

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

Definition at line 49 of file shlexec.cpp.

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

Referenced by SHELL_ArgifyW().

◆ ParseTildeEffect()

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

Definition at line 116 of file shlexec.cpp.

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

Referenced by SHELL_ArgifyW().

◆ PathIsExeW()

EXTERN_C BOOL PathIsExeW ( LPCWSTR  lpszPath)

Definition at line 539 of file shellpath.c.

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

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

◆ RealShellExecuteA()

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

Definition at line 2897 of file shlexec.cpp.

2908{
2910 lpOperation,
2911 lpFile,
2912 lpParameters,
2914 lpReturn,
2915 lpTitle,
2916 lpReserved,
2917 nCmdShow,
2918 lphProcess,
2919 0);
2920}
TCHAR lpTitle[80]
Definition: ctm.c:69
EXTERN_C HINSTANCE WINAPI RealShellExecuteExA(_In_opt_ HWND hwnd, _In_opt_ LPCSTR lpOperation, _In_opt_ LPCSTR lpFile, _In_opt_ LPCSTR lpParameters, _In_opt_ LPCSTR lpDirectory, _In_opt_ LPSTR lpReturn, _In_opt_ LPCSTR lpTitle, _In_opt_ LPVOID lpReserved, _In_ INT nCmdShow, _Out_opt_ PHANDLE lphProcess, _In_ DWORD dwFlags)
Definition: shlexec.cpp:2763

◆ RealShellExecuteExA()

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

Definition at line 2763 of file shlexec.cpp.

2775{
2776 SHELLEXECUTEINFOA ExecInfo;
2777
2778 TRACE("(%p, %s, %s, %s, %s, %p, %s, %p, %u, %p, %lu)\n",
2779 hwnd, debugstr_a(lpOperation), debugstr_a(lpFile), debugstr_a(lpParameters),
2781 lpReserved, nCmdShow, lphProcess, dwFlags);
2782
2783 ZeroMemory(&ExecInfo, sizeof(ExecInfo));
2784 ExecInfo.cbSize = sizeof(ExecInfo);
2786 ExecInfo.hwnd = hwnd;
2787 ExecInfo.lpVerb = lpOperation;
2788 ExecInfo.lpFile = lpFile;
2789 ExecInfo.lpParameters = lpParameters;
2790 ExecInfo.lpDirectory = lpDirectory;
2791 ExecInfo.nShow = (WORD)nCmdShow;
2792
2793 if (lpReserved)
2794 {
2795 ExecInfo.fMask |= SEE_MASK_USE_RESERVED;
2796 ExecInfo.hInstApp = (HINSTANCE)lpReserved;
2797 }
2798
2799 if (lpTitle)
2800 {
2801 ExecInfo.fMask |= SEE_MASK_HASTITLE;
2802 ExecInfo.lpClass = lpTitle;
2803 }
2804
2805 if (dwFlags & 1)
2806 ExecInfo.fMask |= SEE_MASK_FLAG_SEPVDM;
2807
2808 if (dwFlags & 2)
2809 ExecInfo.fMask |= SEE_MASK_NO_CONSOLE;
2810
2811 if (lphProcess == NULL)
2812 {
2813 ShellExecuteExA(&ExecInfo);
2814 }
2815 else
2816 {
2817 ExecInfo.fMask |= SEE_MASK_NOCLOSEPROCESS;
2818 ShellExecuteExA(&ExecInfo);
2819 *lphProcess = ExecInfo.hProcess;
2820 }
2821
2822 return ExecInfo.hInstApp;
2823}
unsigned short WORD
Definition: ntddk_ex.h:93
#define SEE_MASK_USE_RESERVED
Definition: shellapi.h:51
#define SEE_MASK_FLAG_SEPVDM
Definition: shellapi.h:50
#define SEE_MASK_NOCLOSEPROCESS
Definition: shellapi.h:31
#define SEE_MASK_HASTITLE
Definition: shellapi.h:52
#define SEE_MASK_UNKNOWN_0x1000
Definition: shellapi.h:48
#define SEE_MASK_FLAG_NO_UI
Definition: shellapi.h:36
#define SEE_MASK_NO_CONSOLE
Definition: shellapi.h:38
BOOL WINAPI DECLSPEC_HOTPATCH ShellExecuteExA(LPSHELLEXECUTEINFOA sei)
Definition: shlexec.cpp:2366
LPCSTR lpParameters
Definition: shellapi.h:316
HINSTANCE hInstApp
Definition: shellapi.h:319
LPCSTR lpDirectory
Definition: shellapi.h:317
HANDLE HINSTANCE
Definition: typedefs.h:77
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176

Referenced by RealShellExecuteA().

◆ RealShellExecuteExW()

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

Definition at line 2830 of file shlexec.cpp.

2842{
2843 SHELLEXECUTEINFOW ExecInfo;
2844
2845 TRACE("(%p, %s, %s, %s, %s, %p, %s, %p, %u, %p, %lu)\n",
2846 hwnd, debugstr_w(lpOperation), debugstr_w(lpFile), debugstr_w(lpParameters),
2848 lpReserved, nCmdShow, lphProcess, dwFlags);
2849
2850 ZeroMemory(&ExecInfo, sizeof(ExecInfo));
2851 ExecInfo.cbSize = sizeof(ExecInfo);
2853 ExecInfo.hwnd = hwnd;
2854 ExecInfo.lpVerb = lpOperation;
2855 ExecInfo.lpFile = lpFile;
2856 ExecInfo.lpParameters = lpParameters;
2857 ExecInfo.lpDirectory = lpDirectory;
2858 ExecInfo.nShow = (WORD)nCmdShow;
2859
2860 if (lpReserved)
2861 {
2862 ExecInfo.fMask |= SEE_MASK_USE_RESERVED;
2863 ExecInfo.hInstApp = (HINSTANCE)lpReserved;
2864 }
2865
2866 if (lpTitle)
2867 {
2868 ExecInfo.fMask |= SEE_MASK_HASTITLE;
2869 ExecInfo.lpClass = lpTitle;
2870 }
2871
2872 if (dwFlags & 1)
2873 ExecInfo.fMask |= SEE_MASK_FLAG_SEPVDM;
2874
2875 if (dwFlags & 2)
2876 ExecInfo.fMask |= SEE_MASK_NO_CONSOLE;
2877
2878 if (lphProcess == NULL)
2879 {
2880 ShellExecuteExW(&ExecInfo);
2881 }
2882 else
2883 {
2884 ExecInfo.fMask |= SEE_MASK_NOCLOSEPROCESS;
2885 ShellExecuteExW(&ExecInfo);
2886 *lphProcess = ExecInfo.hProcess;
2887 }
2888
2889 return ExecInfo.hInstApp;
2890}
BOOL WINAPI DECLSPEC_HOTPATCH ShellExecuteExW(LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:2424
HINSTANCE hInstApp
Definition: shellapi.h:336
LPCWSTR lpParameters
Definition: shellapi.h:333

Referenced by RealShellExecuteW().

◆ RealShellExecuteW()

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

Definition at line 2927 of file shlexec.cpp.

2938{
2940 lpOperation,
2941 lpFile,
2942 lpParameters,
2944 lpReturn,
2945 lpTitle,
2946 lpReserved,
2947 nCmdShow,
2948 lphProcess,
2949 0);
2950}
EXTERN_C HINSTANCE WINAPI RealShellExecuteExW(_In_opt_ HWND hwnd, _In_opt_ LPCWSTR lpOperation, _In_opt_ LPCWSTR lpFile, _In_opt_ LPCWSTR lpParameters, _In_opt_ LPCWSTR lpDirectory, _In_opt_ LPWSTR lpReturn, _In_opt_ LPCWSTR lpTitle, _In_opt_ LPVOID lpReserved, _In_ INT nCmdShow, _Out_opt_ PHANDLE lphProcess, _In_ DWORD dwFlags)
Definition: shlexec.cpp:2830

◆ SHELL_ArgifyW()

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

Definition at line 198 of file shlexec.cpp.

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

563{
565 WCHAR *strings, *p, *p2;
566 int total = wcslen(path) + 1;
567 BOOL got_path = FALSE;
568
569 if (!(strings = GetEnvironmentStringsW())) return NULL;
570 p = strings;
571 while (*p)
572 {
573 int len = wcslen(p) + 1;
574 if (!_wcsnicmp( p, L"PATH=", 5 )) got_path = TRUE;
575 total += len;
576 p += len;
577 }
578 if (!got_path) total += 5; /* we need to create PATH */
579 total++; /* terminating null */
580
581 if (!new_env.Allocate(total))
582 {
584 return NULL;
585 }
586 p = strings;
587 p2 = new_env;
588 while (*p)
589 {
590 int len = wcslen(p) + 1;
591 memcpy(p2, p, len * sizeof(WCHAR));
592 if (!_wcsnicmp( p, L"PATH=", 5 ))
593 {
594 p2[len - 1] = ';';
595 wcscpy( p2 + len, path );
596 p2 += wcslen(path) + 1;
597 }
598 p += len;
599 p2 += len;
600 }
601 if (!got_path)
602 {
603 wcscpy(p2, L"PATH=");
604 wcscat(p2, path);
605 p2 += wcslen(p2) + 1;
606 }
607 *p2 = 0;
609 return new_env.Detach();
610}
T * Detach()
Definition: atlalloc.h:168
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 1923 of file shlexec.cpp.

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

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

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

1848{
1849 UINT_PTR retval;
1851 LPCWSTR lpstrRes;
1852 INT iSize;
1853 DWORD len;
1854
1855 lpstrRes = strchrW(lpFile, ':');
1856 if (lpstrRes)
1857 iSize = lpstrRes - lpFile;
1858 else
1859 iSize = strlenW(lpFile);
1860
1861 TRACE("Got URL: %s\n", debugstr_w(lpFile));
1862 /* Looking for ...<protocol>\shell<lpVerb>\command */
1863 len = iSize + lstrlenW(L"\\shell\\") + lstrlenW(L"\\command") + 1;
1864 if (psei->lpVerb && *psei->lpVerb)
1865 len += lstrlenW(psei->lpVerb);
1866 else
1867 len += lstrlenW(L"open");
1868 lpstrProtocol.Allocate(len);
1869 memcpy(lpstrProtocol, lpFile, iSize * sizeof(WCHAR));
1870 lpstrProtocol[iSize] = '\0';
1871 strcatW(lpstrProtocol, L"\\shell\\");
1872 strcatW(lpstrProtocol, psei->lpVerb && *psei->lpVerb ? psei->lpVerb : L"open");
1873 strcatW(lpstrProtocol, L"\\command");
1874
1875 retval = execute_from_key(lpstrProtocol, lpFile, NULL, psei->lpParameters,
1876 wcmd, execfunc, psei, psei_out);
1877
1878 return retval;
1879}
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:1170

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

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

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

Referenced by SHELL_execute(), and shellex_get_contextmenu().

◆ SHELL_FindExecutableByVerb()

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

Definition at line 680 of file shlexec.cpp.

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

Referenced by SHELL_execute_class(), and SHELL_FindExecutable().

◆ SHELL_GetPathFromIDListForExecuteW()

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

Definition at line 457 of file shlexec.cpp.

458{
459 STRRET strret;
460 CComPtr<IShellFolder> desktop;
461
462 HRESULT hr = SHGetDesktopFolder(&desktop);
463
464 if (SUCCEEDED(hr))
465 {
466 hr = desktop->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &strret);
467
468 if (SUCCEEDED(hr))
469 StrRetToStrNW(pszPath, uOutSize, &strret, pidl);
470 }
471
472 return hr;
473}
HRESULT WINAPI SHGetDesktopFolder(IShellFolder **psf)
BOOL WINAPI StrRetToStrNW(LPWSTR dest, DWORD len, LPSTRRET src, const ITEMIDLIST *pidl)
Definition: shellstring.c:85

Referenced by SHELL_translate_idlist().

◆ SHELL_InRunDllProcess()

static BOOL SHELL_InRunDllProcess ( VOID  )
static

Definition at line 36 of file shlexec.cpp.

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

Referenced by ShellExecuteExW().

◆ SHELL_InvokePidl()

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

Definition at line 1759 of file shlexec.cpp.

1762{
1763 // Bind pidl
1764 CComPtr<IShellFolder> psfFolder;
1765 LPCITEMIDLIST pidlLast;
1766 HRESULT hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &psfFolder), &pidlLast);
1768 return FALSE;
1769
1770 // Get the context menu to invoke a command
1772 hr = psfFolder->GetUIObjectOf(NULL, 1, &pidlLast, IID_NULL_PPV_ARG(IContextMenu, &pCM));
1774 return FALSE;
1775
1776 // Invoke a command
1777 CMINVOKECOMMANDINFO ici = { sizeof(ici) };
1778 ici.fMask = (sei->fMask & (SEE_MASK_NO_CONSOLE | SEE_MASK_ASYNCOK | SEE_MASK_FLAG_NO_UI));
1779 ici.nShow = sei->nShow;
1780 ici.hwnd = sei->hwnd;
1781 char szVerb[VERBKEY_CCHMAX];
1782 if (sei->lpVerb && sei->lpVerb[0])
1783 {
1784 WideCharToMultiByte(CP_ACP, 0, sei->lpVerb, -1, szVerb, _countof(szVerb), NULL, NULL);
1785 szVerb[_countof(szVerb) - 1] = ANSI_NULL; // Avoid buffer overrun
1786 ici.lpVerb = szVerb;
1787 }
1788 else // The default verb?
1789 {
1790 HMENU hMenu = CreatePopupMenu();
1791 const INT idCmdFirst = 1, idCmdLast = 0x7FFF;
1792 hr = pCM->QueryContextMenu(hMenu, 0, idCmdFirst, idCmdLast, CMF_DEFAULTONLY);
1794 {
1795 DestroyMenu(hMenu);
1796 return FALSE;
1797 }
1798
1799 INT nDefaultID = GetMenuDefaultItem(hMenu, FALSE, 0);
1800 DestroyMenu(hMenu);
1801 if (nDefaultID == -1)
1802 nDefaultID = idCmdFirst;
1803
1804 ici.lpVerb = MAKEINTRESOURCEA(nDefaultID - idCmdFirst);
1805 }
1806 hr = pCM->InvokeCommand(&ici);
1807
1808 return !FAILED_UNEXPECTEDLY(hr);
1809}
#define FAILED_UNEXPECTEDLY(hr)
Definition: precomp.h:121
#define VERBKEY_CCHMAX
Definition: precomp.h:131
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:63
#define ANSI_NULL
HMENU WINAPI CreatePopupMenu(void)
Definition: menu.c:838
UINT WINAPI GetMenuDefaultItem(_In_ HMENU hMenu, _In_ UINT fByPos, _In_ UINT gmdiFlags)
#define MAKEINTRESOURCEA(i)
Definition: winuser.h:581
BOOL WINAPI DestroyMenu(_In_ HMENU)
#define IID_NULL_PPV_ARG(Itype, ppType)

Referenced by SHELL_execute().

◆ SHELL_quote_and_execute()

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

Definition at line 1811 of file shlexec.cpp.

1812{
1813 UINT_PTR retval;
1814 DWORD len;
1816
1817 /* Length of quotes plus length of command plus NULL terminator */
1818 len = 2 + lstrlenW(wcmd) + 1;
1819 if (wszParameters[0])
1820 {
1821 /* Length of space plus length of parameters */
1822 len += 1 + lstrlenW(wszParameters);
1823 }
1824 wszQuotedCmd.Allocate(len);
1825 /* Must quote to handle case where cmd contains spaces,
1826 * else security hole if malicious user creates executable file "C:\\Program"
1827 */
1828 strcpyW(wszQuotedCmd, L"\"");
1829 strcatW(wszQuotedCmd, wcmd);
1830 strcatW(wszQuotedCmd, L"\"");
1831 if (wszParameters[0])
1832 {
1833 strcatW(wszQuotedCmd, L" ");
1834 strcatW(wszQuotedCmd, wszParameters);
1835 }
1836
1837 TRACE("%s/%s => %s/%s\n", debugstr_w(wszApplicationName), debugstr_w(psei->lpVerb), debugstr_w(wszQuotedCmd), debugstr_w(wszKeyname));
1838
1839 if (*wszKeyname)
1840 retval = execute_from_key(wszKeyname, wszApplicationName, env, psei->lpParameters, wcmd, execfunc, psei, psei_out);
1841 else
1842 retval = execfunc(wszQuotedCmd, env, FALSE, psei, psei_out);
1843
1844 return retval;
1845}

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

1713{
1715 BOOL appKnownSingular = FALSE;
1716
1717 /* last chance to translate IDList: now also allow CLSID paths */
1719 if (buffer[0] == ':' && buffer[1] == ':') {
1720 /* open shell folder for the specified class GUID */
1721 if (strlenW(buffer) + 1 > parametersLen)
1722 ERR("parameters len exceeds buffer size (%i > %i), truncating\n",
1723 lstrlenW(buffer) + 1, parametersLen);
1724 lstrcpynW(wszParameters, buffer, parametersLen);
1725 if (strlenW(L"explorer.exe") > dwApplicationNameLen)
1726 ERR("application len exceeds buffer size (%i), truncating\n",
1727 dwApplicationNameLen);
1728 lstrcpynW(wszApplicationName, L"explorer.exe", dwApplicationNameLen);
1729 appKnownSingular = TRUE;
1730
1731 sei->fMask &= ~SEE_MASK_INVOKEIDLIST;
1732 } else {
1734 DWORD attribs;
1735 DWORD resultLen;
1736 /* Check if we're executing a directory and if so use the
1737 handler for the Folder class */
1742 HCR_GetExecuteCommandW(0, L"Folder",
1743 sei->lpVerb,
1744 buffer, sizeof(buffer))) {
1745 SHELL_ArgifyW(wszApplicationName, dwApplicationNameLen,
1746 buffer, target, (LPITEMIDLIST)sei->lpIDList, NULL, &resultLen,
1747 (sei->lpDirectory && *sei->lpDirectory) ? sei->lpDirectory : NULL);
1748 if (resultLen > dwApplicationNameLen)
1749 ERR("Argify buffer not large enough... truncating\n");
1750 appKnownSingular = FALSE;
1751 }
1752 sei->fMask &= ~SEE_MASK_INVOKEIDLIST;
1753 }
1754 }
1755 return appKnownSingular;
1756}
#define lstrcpynW
Definition: compat.h:738
GLenum target
Definition: glext.h:7315
static HRESULT SHELL_GetPathFromIDListForExecuteW(LPCITEMIDLIST pidl, LPWSTR pszPath, UINT uOutSize)
Definition: shlexec.cpp:457

Referenced by SHELL_execute().

◆ SHELL_TryAppPathW()

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

Definition at line 620 of file shlexec.cpp.

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

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

Referenced by ShellExecute_ContextMenuVerb().

◆ shellex_get_dataobj()

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

Definition at line 1370 of file shlexec.cpp.

1371{
1372 CComHeapPtr<ITEMIDLIST> allocatedPidl;
1373 LPITEMIDLIST pidl = NULL;
1374
1375 if (sei->fMask & SEE_MASK_CLASSALL)
1376 {
1377 pidl = (LPITEMIDLIST)sei->lpIDList;
1378 }
1379 else
1380 {
1381 WCHAR fullpath[MAX_PATH];
1382 BOOL ret;
1383
1384 fullpath[0] = 0;
1385 ret = GetFullPathNameW(sei->lpFile, MAX_PATH, fullpath, NULL);
1386 if (!ret)
1388
1389 pidl = ILCreateFromPathW(fullpath);
1390 allocatedPidl.Attach(pidl);
1391 }
1392
1394 LPCITEMIDLIST pidllast = NULL;
1395 HRESULT hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &shf), &pidllast);
1397 return hr;
1398
1399 return shf->GetUIObjectOf(NULL, 1, &pidllast, IID_NULL_PPV_ARG(IDataObject, &dataObj));
1400}
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:1003

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

1472{
1473 TRACE("%p %s %p\n", hkey, debugstr_guid(guid), sei);
1474
1475 CCoInit coInit;
1476
1477 if (FAILED_UNEXPECTEDLY(coInit.hr))
1478 return coInit.hr;
1479
1481 HRESULT hr = CoCreateInstance(*guid, NULL, CLSCTX_INPROC_SERVER,
1484 return hr;
1485
1486 CComPtr<IDataObject> dataobj;
1487 hr = shellex_get_dataobj(sei, dataobj);
1489 return hr;
1490
1491 hr = obj->Initialize(NULL, dataobj, hkey);
1493 return hr;
1494
1496 hr = obj->QueryInterface(IID_PPV_ARG(IObjectWithSite, &ows));
1498 return hr;
1499
1500 ows->SetSite(NULL);
1501
1503}
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:1402
static HRESULT shellex_get_dataobj(LPSHELLEXECUTEINFOW sei, CComPtr< IDataObject > &dataObj)
Definition: shlexec.cpp:1370

Referenced by ShellExecute_FromContextMenuHandlers().

◆ shellex_run_context_menu_default()

static HRESULT shellex_run_context_menu_default ( IShellExtInit obj,
LPSHELLEXECUTEINFOW  sei 
)
static

Definition at line 1402 of file shlexec.cpp.

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

Referenced by shellex_load_object_and_run().

◆ ShellExecCmdLine()

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

Definition at line 2623 of file shlexec.cpp.

2630{
2633 LPCWSTR pszVerb = NULL;
2634 WCHAR szFile[MAX_PATH], szFile2[MAX_PATH];
2635 HRESULT hr;
2636 LPCWSTR pchParams;
2637 LPWSTR lpCommand = NULL;
2638
2639 if (pwszCommand == NULL)
2641 1, (ULONG_PTR*)pwszCommand);
2642
2643 __SHCloneStrW(&lpCommand, pwszCommand);
2644 StrTrimW(lpCommand, L" \t");
2645
2646 if (dwSeclFlags & SECL_NO_UI)
2648 if (dwSeclFlags & SECL_LOG_USAGE)
2650 if (dwSeclFlags & SECL_USE_IDLIST)
2652
2653 if (dwSeclFlags & SECL_RUNAS)
2654 {
2655 dwSize = 0;
2656 hr = AssocQueryStringW(ASSOCF_NONE, ASSOCSTR_COMMAND, lpCommand, L"RunAs", NULL, &dwSize);
2657 if (SUCCEEDED(hr) && dwSize != 0)
2658 {
2659 pszVerb = L"runas";
2660 }
2661 }
2662
2663 if (PathIsURLW(lpCommand) || UrlIsW(lpCommand, URLIS_APPLIABLE))
2664 {
2665 StringCchCopyW(szFile, _countof(szFile), lpCommand);
2666 pchParams = NULL;
2667 }
2668 else
2669 {
2670 PCWSTR apPathList[2];
2671
2672 pchParams = SplitParams(lpCommand, szFile, _countof(szFile));
2673 if (szFile[0] != UNICODE_NULL && szFile[1] == L':' &&
2674 szFile[2] == UNICODE_NULL)
2675 {
2676 PathAddBackslashW(szFile);
2677 }
2678
2679 WCHAR szCurDir[MAX_PATH];
2680 GetCurrentDirectoryW(_countof(szCurDir), szCurDir);
2681 if (pwszStartDir)
2682 {
2683 SetCurrentDirectoryW(pwszStartDir);
2684 }
2685
2686 if ((PathIsRelativeW(szFile) &&
2687 GetFullPathNameW(szFile, _countof(szFile2), szFile2, NULL) &&
2688 PathFileExistsW(szFile2)) ||
2689 SearchPathW(NULL, szFile, NULL, _countof(szFile2), szFile2, NULL))
2690 {
2691 StringCchCopyW(szFile, _countof(szFile), szFile2);
2692 }
2693
2694 apPathList[0] = pwszStartDir;
2695 apPathList[1] = NULL;
2696 PathFindOnPathExW(szFile, apPathList, WHICH_DEFAULT);
2697
2698 if (!(dwSeclFlags & SECL_ALLOW_NONEXE))
2699 {
2700 if (!GetBinaryTypeW(szFile, &dwType))
2701 {
2702 SHFree(lpCommand);
2703
2704 if (!(dwSeclFlags & SECL_NO_UI))
2705 {
2706 WCHAR szText[128 + MAX_PATH], szFormat[128];
2708 StringCchPrintfW(szText, _countof(szText), szFormat, szFile);
2709 MessageBoxW(hwnd, szText, NULL, MB_ICONERROR);
2710 }
2711 return CO_E_APPNOTFOUND;
2712 }
2713 }
2714 else
2715 {
2717 {
2718 SHFree(lpCommand);
2719
2720 if (!(dwSeclFlags & SECL_NO_UI))
2721 {
2722 WCHAR szText[128 + MAX_PATH], szFormat[128];
2724 StringCchPrintfW(szText, _countof(szText), szFormat, szFile);
2725 MessageBoxW(hwnd, szText, NULL, MB_ICONERROR);
2726 }
2728 }
2729 }
2730 }
2731
2732 ZeroMemory(&info, sizeof(info));
2733 info.cbSize = sizeof(info);
2734 info.fMask = dwFlags;
2735 info.hwnd = hwnd;
2736 info.lpVerb = pszVerb;
2737 info.lpFile = szFile;
2738 info.lpParameters = (pchParams && *pchParams) ? pchParams : NULL;
2739 info.lpDirectory = pwszStartDir;
2740 info.nShow = nShow;
2741 if (ShellExecuteExW(&info))
2742 {
2743 if (info.lpIDList)
2744 CoTaskMemFree(info.lpIDList);
2745
2746 SHFree(lpCommand);
2747
2748 return S_OK;
2749 }
2750
2751 dwError = GetLastError();
2752
2753 SHFree(lpCommand);
2754
2755 return HRESULT_FROM_WIN32(dwError);
2756}
#define SECL_USE_IDLIST
#define SECL_LOG_USAGE
#define SECL_ALLOW_NONEXE
#define SECL_RUNAS
#define SECL_NO_UI
VOID WINAPI RaiseException(_In_ DWORD dwExceptionCode, _In_ DWORD dwExceptionFlags, _In_ DWORD nNumberOfArguments, _In_opt_ const ULONG_PTR *lpArguments)
Definition: except.c:700
BOOL WINAPI GetBinaryTypeW(LPCWSTR lpApplicationName, LPDWORD lpBinaryType)
Definition: vdm.c:1243
BOOL WINAPI PathFileExistsW(LPCWSTR lpszPath)
Definition: path.c: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:1877
BOOL WINAPI UrlIsW(LPCWSTR pszUrl, URLIS Urlis)
Definition: url.c:1933
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
#define SEE_MASK_FLAG_LOG_USAGE
Definition: shellapi.h:59
static LPCWSTR SplitParams(LPCWSTR psz, LPWSTR pszArg0, size_t cchArg0)
Definition: shlexec.cpp:2577
@ ASSOCSTR_COMMAND
Definition: shlwapi.h:603
@ URLIS_APPLIABLE
Definition: shlwapi.h:1221
#define WHICH_DEFAULT
#define IDS_FILE_NOT_FOUND
Definition: shresdef.h:341
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
#define EXCEPTION_NONCONTINUABLE
Definition: stubs.h:23
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define EXCEPTION_ACCESS_VIOLATION
Definition: winbase.h:311
#define CO_E_APPNOTFOUND
Definition: winerror.h:2808

◆ ShellExecute_ContextMenuVerb()

static HRESULT ShellExecute_ContextMenuVerb ( LPSHELLEXECUTEINFOW  sei)
static

Definition at line 1544 of file shlexec.cpp.

1545{
1546 TRACE("%p\n", sei);
1547
1548 CCoInit coInit;
1549
1550 if (FAILED_UNEXPECTEDLY(coInit.hr))
1551 return coInit.hr;
1552
1556 return hr;
1557
1558 CComHeapPtr<char> verb, parameters, dir;
1559 __SHCloneStrWtoA(&verb, sei->lpVerb);
1560 __SHCloneStrWtoA(&parameters, sei->lpParameters);
1562
1563 BOOL fDefault = StrIsNullOrEmpty(sei->lpVerb);
1564 CMINVOKECOMMANDINFOEX ici = { sizeof(ici) };
1565 ici.fMask = SeeFlagsToCmicFlags(sei->fMask) | CMIC_MASK_UNICODE;
1566 ici.nShow = sei->nShow;
1567 if (!fDefault)
1568 {
1569 ici.lpVerb = verb;
1570 ici.lpVerbW = sei->lpVerb;
1571 }
1572 ici.hwnd = sei->hwnd;
1573 ici.lpParameters = parameters;
1574 ici.lpParametersW = sei->lpParameters;
1575 ici.lpDirectory = dir;
1576 ici.lpDirectoryW = sei->lpDirectory;
1577 ici.dwHotKey = sei->dwHotKey;
1578 ici.hIcon = sei->hIcon;
1579 if (ici.fMask & (CMIC_MASK_HASLINKNAME | CMIC_MASK_HASTITLE))
1580 ici.lpTitleW = sei->lpClass;
1581
1582 enum { idFirst = 1, idLast = 0x7fff };
1583 HMENU hMenu = CreatePopupMenu();
1584 hr = cm->QueryContextMenu(hMenu, 0, idFirst, idLast, fDefault ? CMF_DEFAULTONLY : 0);
1585 if (!FAILED_UNEXPECTEDLY(hr))
1586 {
1587 if (fDefault)
1588 {
1589 INT uDefault = GetMenuDefaultItem(hMenu, FALSE, 0);
1590 uDefault = (uDefault != -1) ? uDefault - idFirst : 0;
1591 ici.lpVerb = MAKEINTRESOURCEA(uDefault);
1592 ici.lpVerbW = MAKEINTRESOURCEW(uDefault);
1593 }
1594
1595 hr = cm->InvokeCommand((LPCMINVOKECOMMANDINFO)&ici);
1596 if (!FAILED_UNEXPECTEDLY(hr))
1597 hr = S_OK;
1598 }
1599
1600 DestroyMenu(hMenu);
1601
1602 return hr;
1603}
unsigned int dir
Definition: maze.c:112
static UINT SeeFlagsToCmicFlags(UINT flags)
Definition: precomp.h:160
static __inline void __SHCloneStrWtoA(char **target, const WCHAR *source)
Definition: shell32_main.h:155
static HRESULT shellex_get_contextmenu(LPSHELLEXECUTEINFOW sei, CComPtr< IContextMenu > &cm)
Definition: shlexec.cpp:1505
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582

Referenced by SHELL_execute().

◆ ShellExecute_FromContextMenuHandlers()

static LONG ShellExecute_FromContextMenuHandlers ( LPSHELLEXECUTEINFOW  sei)
static

Definition at line 1609 of file shlexec.cpp.

1610{
1611 HKEY hkey, hkeycm = 0;
1612 WCHAR szguid[39];
1613 HRESULT hr;
1614 GUID guid;
1615 DWORD i;
1616 LONG r;
1617
1618 TRACE("%s\n", debugstr_w(sei->lpFile));
1619
1620 hkey = ShellExecute_GetClassKey(sei);
1621 if (!hkey)
1622 return ERROR_FUNCTION_FAILED;
1623
1624 r = RegOpenKeyW(hkey, L"shellex\\ContextMenuHandlers", &hkeycm);
1625 if (r == ERROR_SUCCESS)
1626 {
1627 i = 0;
1628 while (1)
1629 {
1630 r = RegEnumKeyW(hkeycm, i++, szguid, ARRAY_SIZE(szguid));
1631 if (r != ERROR_SUCCESS)
1632 break;
1633
1634 hr = CLSIDFromString(szguid, &guid);
1635 if (SUCCEEDED(hr))
1636 {
1637 /* stop at the first one that succeeds in running */
1638 hr = shellex_load_object_and_run(hkey, &guid, sei);
1639 if (SUCCEEDED(hr))
1640 break;
1641 }
1642 }
1643 RegCloseKey(hkeycm);
1644 }
1645
1646 if (hkey != sei->hkeyClass)
1647 RegCloseKey(hkey);
1648 return r;
1649}
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3268
LONG WINAPI RegEnumKeyW(HKEY hKey, DWORD dwIndex, LPWSTR lpName, DWORD cbName)
Definition: reg.c:2393
HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id)
Definition: compobj.c:2338
static HRESULT shellex_load_object_and_run(HKEY hkey, LPCGUID guid, LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:1471
static HKEY ShellExecute_GetClassKey(const SHELLEXECUTEINFOW *sei)
Definition: shlexec.cpp:1324
#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 1324 of file shlexec.cpp.

1325{
1326 LPCWSTR ext = NULL, lpClass = NULL;
1328 DWORD type = 0, sz = 0;
1329 HKEY hkey = 0;
1330 LONG r;
1331
1332 if (sei->fMask & SEE_MASK_CLASSALL)
1333 return sei->hkeyClass;
1334
1335 if (sei->fMask & SEE_MASK_CLASSNAME)
1336 lpClass = sei->lpClass;
1337 else
1338 {
1340 TRACE("ext = %s\n", debugstr_w(ext));
1341 if (!ext)
1342 return hkey;
1343
1345 if (r != ERROR_SUCCESS)
1346 return hkey;
1347
1348 r = RegQueryValueExW(hkey, NULL, 0, &type, NULL, &sz);
1349 if (r == ERROR_SUCCESS && type == REG_SZ)
1350 {
1351 sz += sizeof (WCHAR);
1352 cls.Allocate(sz / sizeof(WCHAR));
1353 cls[0] = 0;
1354 RegQueryValueExW(hkey, NULL, 0, &type, (LPBYTE)(LPWSTR)cls, &sz);
1355 }
1356
1357 RegCloseKey( hkey );
1358 lpClass = cls;
1359 }
1360
1361 TRACE("class = %s\n", debugstr_w(lpClass));
1362
1363 hkey = 0;
1364 if (lpClass)
1365 RegOpenKeyW( HKEY_CLASSES_ROOT, lpClass, &hkey);
1366
1367 return hkey;
1368}
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
static const WCHAR *const ext[]
Definition: module.c:53
LPWSTR WINAPI PathFindExtensionW(LPCWSTR lpszPath)
Definition: path.c:447
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545

Referenced by ShellExecute_FromContextMenuHandlers().

◆ ShellExecute_Normal()

static DWORD ShellExecute_Normal ( _Inout_ LPSHELLEXECUTEINFOW  sei)
static

Definition at line 2345 of file shlexec.cpp.

2346{
2347 // FIXME
2349}
static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
Definition: shlexec.cpp:1923
static UINT_PTR SHELL_ExecuteW(const WCHAR *lpCmd, WCHAR *env, BOOL shWait, const SHELLEXECUTEINFOW *psei, LPSHELLEXECUTEINFOW psei_out)
Definition: shlexec.cpp:479

Referenced by ShellExecuteExW().

◆ ShellExecute_ShowError()

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

Definition at line 2352 of file shlexec.cpp.

2356{
2357 // FIXME: Show error message
2358}

Referenced by ShellExecuteExW().

◆ ShellExecuteA()

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

Definition at line 2317 of file shlexec.cpp.

2319{
2321
2322 TRACE("%p,%s,%s,%s,%s,%d\n",
2323 hWnd, debugstr_a(lpVerb), debugstr_a(lpFile),
2324 debugstr_a(lpParameters), debugstr_a(lpDirectory), iShowCmd);
2325
2326 sei.cbSize = sizeof(sei);
2328 sei.hwnd = hWnd;
2329 sei.lpVerb = lpVerb;
2330 sei.lpFile = lpFile;
2331 sei.lpParameters = lpParameters;
2333 sei.nShow = iShowCmd;
2334 sei.lpIDList = 0;
2335 sei.lpClass = 0;
2336 sei.hkeyClass = 0;
2337 sei.dwHotKey = 0;
2338 sei.hProcess = 0;
2339
2340 ShellExecuteExA(&sei);
2341 return sei.hInstApp;
2342}
HWND hWnd
Definition: settings.c:17

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

◆ ShellExecuteExA()

Definition at line 2366 of file shlexec.cpp.

2367{
2368 SHELLEXECUTEINFOW seiW;
2369 BOOL ret;
2370 WCHAR *wVerb = NULL, *wFile = NULL, *wParameters = NULL, *wDirectory = NULL, *wClass = NULL;
2371
2372 TRACE("%p\n", sei);
2373
2374 if (sei->cbSize != sizeof(SHELLEXECUTEINFOA))
2375 {
2378 return FALSE;
2379 }
2380
2381 memcpy(&seiW, sei, sizeof(SHELLEXECUTEINFOW));
2382
2383 seiW.cbSize = sizeof(SHELLEXECUTEINFOW);
2384
2385 if (sei->lpVerb)
2386 seiW.lpVerb = __SHCloneStrAtoW(&wVerb, sei->lpVerb);
2387
2388 if (sei->lpFile)
2389 seiW.lpFile = __SHCloneStrAtoW(&wFile, sei->lpFile);
2390
2391 if (sei->lpParameters)
2392 seiW.lpParameters = __SHCloneStrAtoW(&wParameters, sei->lpParameters);
2393
2394 if (sei->lpDirectory)
2395 seiW.lpDirectory = __SHCloneStrAtoW(&wDirectory, sei->lpDirectory);
2396
2397 if ((sei->fMask & SEE_MASK_CLASSALL) == SEE_MASK_CLASSNAME && sei->lpClass)
2398 seiW.lpClass = __SHCloneStrAtoW(&wClass, sei->lpClass);
2399 else
2400 seiW.lpClass = NULL;
2401
2402 ret = ShellExecuteExW(&seiW);
2403
2404 sei->hInstApp = seiW.hInstApp;
2405
2406 if (sei->fMask & SEE_MASK_NOCLOSEPROCESS)
2407 sei->hProcess = seiW.hProcess;
2408
2409 SHFree(wVerb);
2410 SHFree(wFile);
2411 SHFree(wParameters);
2412 SHFree(wDirectory);
2413 SHFree(wClass);
2414
2415 return ret;
2416}
struct _SHELLEXECUTEINFOW SHELLEXECUTEINFOW

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

◆ ShellExecuteExW()

Definition at line 2424 of file shlexec.cpp.

2425{
2426 HRESULT hrCoInit;
2427 DWORD dwError;
2428 ULONG fOldMask;
2429
2430 if (sei->cbSize != sizeof(SHELLEXECUTEINFOW))
2431 {
2434 return FALSE;
2435 }
2436
2437 hrCoInit = SHCoInitializeAnyApartment();
2438
2439 if (SHRegGetBoolUSValueW(L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer",
2440 L"MaximizeApps", FALSE, FALSE))
2441 {
2442 switch (sei->nShow)
2443 {
2444 case SW_SHOW:
2445 case SW_SHOWDEFAULT:
2446 case SW_SHOWNORMAL:
2447 case SW_RESTORE:
2448 sei->nShow = SW_SHOWMAXIMIZED;
2449 break;
2450 default:
2451 break;
2452 }
2453 }
2454
2455 fOldMask = sei->fMask;
2456
2457 if (!(fOldMask & SEE_MASK_NOASYNC) && SHELL_InRunDllProcess())
2459
2460 dwError = ShellExecute_Normal(sei);
2461
2462 if (dwError && dwError != ERROR_DLL_NOT_FOUND && dwError != ERROR_CANCELLED)
2463 ShellExecute_ShowError(sei, NULL, dwError);
2464
2465 sei->fMask = fOldMask;
2466
2467 if (SUCCEEDED(hrCoInit))
2469
2470 if (dwError)
2471 SetLastError(dwError);
2472
2473 return dwError == ERROR_SUCCESS;
2474}
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
HRESULT SHCoInitializeAnyApartment(VOID)
Definition: utils.cpp:280
BOOL WINAPI SHRegGetBoolUSValueW(LPCWSTR pszSubKey, LPCWSTR pszValue, BOOL fIgnoreHKCU, BOOL fDefault)
Definition: reg.c:770
#define SE_ERR_ACCESSDENIED
Definition: shellapi.h:127
#define SEE_MASK_WAITFORINPUTIDLE
Definition: shellapi.h:58
static DWORD ShellExecute_Normal(_Inout_ LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:2345
static VOID ShellExecute_ShowError(_In_ const SHELLEXECUTEINFOW *ExecInfo, _In_opt_ LPCWSTR pszCaption, _In_ DWORD dwError)
Definition: shlexec.cpp:2352
static BOOL SHELL_InRunDllProcess(VOID)
Definition: shlexec.cpp:36
#define ERROR_DLL_NOT_FOUND
Definition: winerror.h:679
#define ERROR_CANCELLED
Definition: winerror.h:726
#define SW_SHOWNORMAL
Definition: winuser.h:773
#define SW_SHOWMAXIMIZED
Definition: winuser.h:776
#define SW_SHOWDEFAULT
Definition: winuser.h:783
#define SW_RESTORE
Definition: winuser.h:782
#define SW_SHOW
Definition: winuser.h:778

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

◆ ShellExecuteW()

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

Definition at line 2482 of file shlexec.cpp.

2484{
2486
2487 TRACE("\n");
2488 sei.cbSize = sizeof(sei);
2490 sei.hwnd = hwnd;
2491 sei.lpVerb = lpVerb;
2492 sei.lpFile = lpFile;
2493 sei.lpParameters = lpParameters;
2495 sei.nShow = nShowCmd;
2496 sei.lpIDList = 0;
2497 sei.lpClass = 0;
2498 sei.hkeyClass = 0;
2499 sei.dwHotKey = 0;
2500 sei.hProcess = 0;
2501
2503 return sei.hInstApp;
2504}

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

◆ SplitParams()

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

Definition at line 2577 of file shlexec.cpp.

2578{
2579 LPCWSTR pch;
2580 size_t ich = 0;
2581 if (*psz == L'"')
2582 {
2583 // 1st argument is quoted. the string in quotes is quoted 1st argument.
2584 // [pch] --> [pszArg0+ich]
2585 for (pch = psz + 1; *pch && ich + 1 < cchArg0; ++ich, ++pch)
2586 {
2587 if (*pch == L'"' && pch[1] == L'"')
2588 {
2589 // doubled double quotations found!
2590 pszArg0[ich] = L'"';
2591 }
2592 else if (*pch == L'"')
2593 {
2594 // single double quotation found!
2595 ++pch;
2596 break;
2597 }
2598 else
2599 {
2600 // otherwise
2601 pszArg0[ich] = *pch;
2602 }
2603 }
2604 }
2605 else
2606 {
2607 // 1st argument is unquoted. non-space sequence is 1st argument.
2608 // [pch] --> [pszArg0+ich]
2609 for (pch = psz; *pch && !iswspace(*pch) && ich + 1 < cchArg0; ++ich, ++pch)
2610 {
2611 pszArg0[ich] = *pch;
2612 }
2613 }
2614 pszArg0[ich] = 0;
2615
2616 // skip space
2617 while (iswspace(*pch))
2618 ++pch;
2619
2620 return pch;
2621}
#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 2511 of file shlexec.cpp.

2513{
2514 SHELLEXECUTEINFOW seiW;
2515 WCHAR *wVerb = NULL, *wFile = NULL, *wParameters = NULL, *wDirectory = NULL;
2516 HANDLE hProcess = 0;
2517
2518 seiW.lpVerb = lpVerb ? __SHCloneStrAtoW(&wVerb, lpVerb) : NULL;
2519 seiW.lpFile = lpFile ? __SHCloneStrAtoW(&wFile, lpFile) : NULL;
2520 seiW.lpParameters = lpParameters ? __SHCloneStrAtoW(&wParameters, lpParameters) : NULL;
2521 seiW.lpDirectory = lpDirectory ? __SHCloneStrAtoW(&wDirectory, lpDirectory) : NULL;
2522
2523 seiW.cbSize = sizeof(seiW);
2524 seiW.fMask = 0;
2525 seiW.hwnd = hWnd;
2526 seiW.nShow = iShowCmd;
2527 seiW.lpIDList = 0;
2528 seiW.lpClass = 0;
2529 seiW.hkeyClass = 0;
2530 seiW.dwHotKey = 0;
2531 seiW.hProcess = hProcess;
2532
2534
2535 SHFree(wVerb);
2536 SHFree(wFile);
2537 SHFree(wParameters);
2538 SHFree(wDirectory);
2539 return seiW.hInstApp;
2540}
_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