ReactOS 0.4.15-dev-8413-gc1c91f2
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 941 of file shlexec.cpp.

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

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

1865{
1866 WCHAR msg[2048];
1867 DWORD_PTR msgArguments[3] = { (DWORD_PTR)filename, 0, 0 };
1869
1871 if (retval == SE_ERR_NOASSOC)
1873 else
1875 NULL,
1876 error_code,
1878 msg,
1879 ARRAY_SIZE(msg),
1880 (va_list*)msgArguments);
1881
1883}
#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:189
#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:787

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

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

1886{
1888 DWORD len;
1889
1891 if (!len) return NULL;
1892
1893 if (!buf.Allocate(len))
1894 return NULL;
1895
1897 if (!len)
1898 return NULL;
1899
1900 return buf.Detach();
1901}
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 1227 of file shlexec.cpp.

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

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

◆ FindExecutableW()

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

Definition at line 1270 of file shlexec.cpp.

1271{
1272 UINT_PTR retval;
1273 WCHAR old_dir[MAX_PATH], res[MAX_PATH];
1274 DWORD cch = _countof(res);
1275 LPCWSTR dirs[2];
1276
1277 TRACE("File %s, Dir %s\n", debugstr_w(lpFile), debugstr_w(lpDirectory));
1278
1279 *lpResult = UNICODE_NULL;
1280
1281 GetCurrentDirectoryW(_countof(old_dir), old_dir);
1282
1283 if (lpDirectory && *lpDirectory)
1284 {
1286 dirs[0] = lpDirectory;
1287 }
1288 else
1289 {
1290 dirs[0] = old_dir;
1291 }
1292 dirs[1] = NULL;
1293
1294 if (!GetShortPathNameW(lpFile, res, _countof(res)))
1295 StringCchCopyW(res, _countof(res), lpFile);
1296
1298 {
1299 // NOTE: The last parameter of this AssocQueryStringW call is "strange" in Windows.
1300 if (PathIsExeW(res) ||
1302 {
1303 StringCchCopyW(lpResult, MAX_PATH, res);
1304 retval = 42;
1305 }
1306 else
1307 {
1308 retval = SE_ERR_NOASSOC;
1309 }
1310 }
1311 else
1312 {
1313 retval = SE_ERR_FNF;
1314 }
1315
1316 TRACE("returning %s\n", debugstr_w(lpResult));
1317 SetCurrentDirectoryW(old_dir);
1318 return (HINSTANCE)retval;
1319}
#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 2584 of file shlexec.cpp.

2585{
2586 LPWSTR pszCmdLineW = NULL;
2587 TRACE("%p, %p, %s, %d\n", hwnd, hinst, debugstr_a(cmdline), cmdshow);
2588
2589 if (cmdline)
2590 __SHCloneStrAtoW(&pszCmdLineW, cmdline);
2591 OpenAs_RunDLLW(hwnd, hinst, pszCmdLineW, cmdshow);
2592 SHFree(pszCmdLineW);
2593}
#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:2567
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 2567 of file shlexec.cpp.

2568{
2570 TRACE("%p, %p, %s, %d\n", hwnd, hinst, debugstr_w(cmdline), cmdshow);
2571
2572 ZeroMemory(&info, sizeof(info));
2573 info.pcszFile = cmdline;
2574 info.pcszClass = NULL;
2576
2578}
HRESULT WINAPI SHOpenWithDialog(HWND hwndParent, const OPENASINFO *poainfo)
@ OAIF_EXEC
Definition: shlobj.h:2681
@ OAIF_REGISTER_EXT
Definition: shlobj.h:2680
@ OAIF_ALLOW_REGISTRATION
Definition: shlobj.h:2679
#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 2917 of file shlexec.cpp.

2928{
2930 lpOperation,
2931 lpFile,
2932 lpParameters,
2934 lpReturn,
2935 lpTitle,
2936 lpReserved,
2937 nCmdShow,
2938 lphProcess,
2939 0);
2940}
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:2783

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

2795{
2796 SHELLEXECUTEINFOA ExecInfo;
2797
2798 TRACE("(%p, %s, %s, %s, %s, %p, %s, %p, %u, %p, %lu)\n",
2799 hwnd, debugstr_a(lpOperation), debugstr_a(lpFile), debugstr_a(lpParameters),
2801 lpReserved, nCmdShow, lphProcess, dwFlags);
2802
2803 ZeroMemory(&ExecInfo, sizeof(ExecInfo));
2804 ExecInfo.cbSize = sizeof(ExecInfo);
2806 ExecInfo.hwnd = hwnd;
2807 ExecInfo.lpVerb = lpOperation;
2808 ExecInfo.lpFile = lpFile;
2809 ExecInfo.lpParameters = lpParameters;
2810 ExecInfo.lpDirectory = lpDirectory;
2811 ExecInfo.nShow = (WORD)nCmdShow;
2812
2813 if (lpReserved)
2814 {
2815 ExecInfo.fMask |= SEE_MASK_USE_RESERVED;
2816 ExecInfo.hInstApp = (HINSTANCE)lpReserved;
2817 }
2818
2819 if (lpTitle)
2820 {
2821 ExecInfo.fMask |= SEE_MASK_HASTITLE;
2822 ExecInfo.lpClass = lpTitle;
2823 }
2824
2825 if (dwFlags & 1)
2826 ExecInfo.fMask |= SEE_MASK_FLAG_SEPVDM;
2827
2828 if (dwFlags & 2)
2829 ExecInfo.fMask |= SEE_MASK_NO_CONSOLE;
2830
2831 if (lphProcess == NULL)
2832 {
2833 ShellExecuteExA(&ExecInfo);
2834 }
2835 else
2836 {
2837 ExecInfo.fMask |= SEE_MASK_NOCLOSEPROCESS;
2838 ShellExecuteExA(&ExecInfo);
2839 *lphProcess = ExecInfo.hProcess;
2840 }
2841
2842 return ExecInfo.hInstApp;
2843}
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:2387
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 2850 of file shlexec.cpp.

2862{
2863 SHELLEXECUTEINFOW ExecInfo;
2864
2865 TRACE("(%p, %s, %s, %s, %s, %p, %s, %p, %u, %p, %lu)\n",
2866 hwnd, debugstr_w(lpOperation), debugstr_w(lpFile), debugstr_w(lpParameters),
2868 lpReserved, nCmdShow, lphProcess, dwFlags);
2869
2870 ZeroMemory(&ExecInfo, sizeof(ExecInfo));
2871 ExecInfo.cbSize = sizeof(ExecInfo);
2873 ExecInfo.hwnd = hwnd;
2874 ExecInfo.lpVerb = lpOperation;
2875 ExecInfo.lpFile = lpFile;
2876 ExecInfo.lpParameters = lpParameters;
2877 ExecInfo.lpDirectory = lpDirectory;
2878 ExecInfo.nShow = (WORD)nCmdShow;
2879
2880 if (lpReserved)
2881 {
2882 ExecInfo.fMask |= SEE_MASK_USE_RESERVED;
2883 ExecInfo.hInstApp = (HINSTANCE)lpReserved;
2884 }
2885
2886 if (lpTitle)
2887 {
2888 ExecInfo.fMask |= SEE_MASK_HASTITLE;
2889 ExecInfo.lpClass = lpTitle;
2890 }
2891
2892 if (dwFlags & 1)
2893 ExecInfo.fMask |= SEE_MASK_FLAG_SEPVDM;
2894
2895 if (dwFlags & 2)
2896 ExecInfo.fMask |= SEE_MASK_NO_CONSOLE;
2897
2898 if (lphProcess == NULL)
2899 {
2900 ShellExecuteExW(&ExecInfo);
2901 }
2902 else
2903 {
2904 ExecInfo.fMask |= SEE_MASK_NOCLOSEPROCESS;
2905 ShellExecuteExW(&ExecInfo);
2906 *lphProcess = ExecInfo.hProcess;
2907 }
2908
2909 return ExecInfo.hInstApp;
2910}
BOOL WINAPI DECLSPEC_HOTPATCH ShellExecuteExW(LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:2445
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 2947 of file shlexec.cpp.

2958{
2960 lpOperation,
2961 lpFile,
2962 lpParameters,
2964 lpReturn,
2965 lpTitle,
2966 lpReserved,
2967 nCmdShow,
2968 lphProcess,
2969 0);
2970}
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:2850

◆ 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:165
PVOID WINAPI SHLockShared(HANDLE hShared, DWORD dwProcId)
Definition: ordinal.c:255
BOOL WINAPI SHUnlockShared(LPVOID lpView)
Definition: ordinal.c:291
#define swprintf
Definition: precomp.h:40
static FILE * out
Definition: regtests2xml.c:44
#define ILGetSize
Definition: shellclasses.h:638
static void ParseNoTildeEffect(PWSTR &res, LPCWSTR &args, DWORD &len, DWORD &used, int argNum)
Definition: shlexec.cpp: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 560 of file shlexec.cpp.

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

1907{
1908 static const DWORD unsupportedFlags =
1912
1913 DWORD len;
1914 UINT_PTR retval = SE_ERR_NOASSOC;
1915 BOOL appKnownSingular = FALSE;
1916
1917 /* make a local copy of the LPSHELLEXECUTEINFO structure and work with this from now on */
1918 SHELLEXECUTEINFOW sei_tmp = *sei;
1919
1920 TRACE("mask=0x%08x hwnd=%p verb=%s file=%s parm=%s dir=%s show=0x%08x class=%s\n",
1921 sei_tmp.fMask, sei_tmp.hwnd, debugstr_w(sei_tmp.lpVerb),
1922 debugstr_w(sei_tmp.lpFile), debugstr_w(sei_tmp.lpParameters),
1923 debugstr_w(sei_tmp.lpDirectory), sei_tmp.nShow,
1924 ((sei_tmp.fMask & SEE_MASK_CLASSALL) == SEE_MASK_CLASSNAME) ?
1925 debugstr_w(sei_tmp.lpClass) : "not used");
1926
1927 sei->hProcess = NULL;
1928
1929 /* make copies of all path/command strings */
1930 CHeapPtr<WCHAR, CLocalAllocator> wszApplicationName;
1931 DWORD dwApplicationNameLen = MAX_PATH + 2;
1932 if (!sei_tmp.lpFile)
1933 {
1934 wszApplicationName.Allocate(dwApplicationNameLen);
1935 *wszApplicationName = '\0';
1936 }
1937 else if (*sei_tmp.lpFile == '\"' && sei_tmp.lpFile[(len = strlenW(sei_tmp.lpFile))-1] == '\"')
1938 {
1939 if(len-1 >= dwApplicationNameLen)
1940 dwApplicationNameLen = len;
1941
1942 wszApplicationName.Allocate(dwApplicationNameLen);
1943 memcpy(wszApplicationName, sei_tmp.lpFile + 1, len * sizeof(WCHAR));
1944
1945 if(len > 2)
1946 wszApplicationName[len-2] = '\0';
1947 appKnownSingular = TRUE;
1948
1949 TRACE("wszApplicationName=%s\n", debugstr_w(wszApplicationName));
1950 }
1951 else
1952 {
1953 DWORD l = strlenW(sei_tmp.lpFile) + 1;
1954 if(l > dwApplicationNameLen) dwApplicationNameLen = l + 1;
1955 wszApplicationName.Allocate(dwApplicationNameLen);
1956 memcpy(wszApplicationName, sei_tmp.lpFile, l * sizeof(WCHAR));
1957
1958 if (wszApplicationName[2] == 0 && wszApplicationName[1] == L':' &&
1959 ((L'A' <= wszApplicationName[0] && wszApplicationName[0] <= L'Z') ||
1960 (L'a' <= wszApplicationName[0] && wszApplicationName[0] <= L'z')))
1961 {
1962 // 'C:' --> 'C:\'
1963 PathAddBackslashW(wszApplicationName);
1964 }
1965 }
1966
1967 WCHAR parametersBuffer[1024];
1968 LPWSTR wszParameters = parametersBuffer;
1970 DWORD parametersLen = _countof(parametersBuffer);
1971
1972 if (sei_tmp.lpParameters)
1973 {
1974 len = lstrlenW(sei_tmp.lpParameters) + 1;
1975 if (len > parametersLen)
1976 {
1977 wszParamAlloc.Allocate(len);
1978 wszParameters = wszParamAlloc;
1979 parametersLen = len;
1980 }
1981 strcpyW(wszParameters, sei_tmp.lpParameters);
1982 }
1983 else
1984 *wszParameters = L'\0';
1985
1986 // Get the working directory
1987 WCHAR dirBuffer[MAX_PATH];
1988 LPWSTR wszDir = dirBuffer;
1989 wszDir[0] = UNICODE_NULL;
1991 if (sei_tmp.lpDirectory && *sei_tmp.lpDirectory)
1992 {
1993 if (sei_tmp.fMask & SEE_MASK_DOENVSUBST)
1994 {
1995 LPWSTR tmp = expand_environment(sei_tmp.lpDirectory);
1996 if (tmp)
1997 {
1998 wszDirAlloc.Attach(tmp);
1999 wszDir = wszDirAlloc;
2000 }
2001 }
2002 else
2003 {
2004 __SHCloneStrW(&wszDirAlloc, sei_tmp.lpDirectory);
2005 if (wszDirAlloc)
2006 wszDir = wszDirAlloc;
2007 }
2008 }
2009 if (!wszDir[0])
2010 {
2011 ::GetCurrentDirectoryW(_countof(dirBuffer), dirBuffer);
2012 wszDir = dirBuffer;
2013 }
2014 // NOTE: ShellExecute should accept the invalid working directory for historical reason.
2015 if (!PathIsDirectoryW(wszDir))
2016 {
2017 INT iDrive = PathGetDriveNumberW(wszDir);
2018 if (iDrive >= 0)
2019 {
2020 PathStripToRootW(wszDir);
2021 if (!PathIsDirectoryW(wszDir))
2022 {
2023 ::GetWindowsDirectoryW(dirBuffer, _countof(dirBuffer));
2024 wszDir = dirBuffer;
2025 }
2026 }
2027 }
2028
2029 /* adjust string pointers to point to the new buffers */
2030 sei_tmp.lpFile = wszApplicationName;
2031 sei_tmp.lpParameters = wszParameters;
2032 sei_tmp.lpDirectory = wszDir;
2033
2034 if (sei_tmp.fMask & unsupportedFlags)
2035 {
2036 FIXME("flags ignored: 0x%08x\n", sei_tmp.fMask & unsupportedFlags);
2037 }
2038
2039 /* process the IDList */
2040 if (sei_tmp.fMask & SEE_MASK_IDLIST &&
2042 {
2044
2046
2047 if (SUCCEEDED(hr))
2048 {
2049 hr = pSEH->Execute(&sei_tmp);
2050 if (hr == S_OK)
2051 return TRUE;
2052 }
2053
2054 SHGetPathFromIDListW((LPCITEMIDLIST)sei_tmp.lpIDList, wszApplicationName);
2055 appKnownSingular = TRUE;
2056 TRACE("-- idlist=%p (%s)\n", sei_tmp.lpIDList, debugstr_w(wszApplicationName));
2057 }
2058
2059 if (sei_tmp.fMask & SEE_MASK_DOENVSUBST)
2060 {
2061 WCHAR *tmp = expand_environment(sei_tmp.lpFile);
2062 if (tmp)
2063 {
2064 wszApplicationName.Attach(tmp);
2065 sei_tmp.lpFile = wszApplicationName;
2066 }
2067
2068 tmp = expand_environment(sei_tmp.lpDirectory);
2069 if (tmp)
2070 {
2071 wszDirAlloc.Attach(tmp);
2072 sei_tmp.lpDirectory = wszDir = wszDirAlloc;
2073 }
2074 }
2075
2077 {
2079 if (SUCCEEDED(hr))
2080 {
2081 sei->hInstApp = (HINSTANCE)42;
2082 return TRUE;
2083 }
2084 }
2085
2086
2088 {
2089 sei->hInstApp = (HINSTANCE) 33;
2090 return TRUE;
2091 }
2092
2093 if (sei_tmp.fMask & SEE_MASK_CLASSALL)
2094 {
2095 retval = SHELL_execute_class(wszApplicationName, &sei_tmp, sei, execfunc);
2096 if (retval <= 32 && !(sei_tmp.fMask & SEE_MASK_FLAG_NO_UI))
2097 {
2099
2100 //FIXME
2101 // need full path
2102
2103 Info.pcszFile = wszApplicationName;
2104 Info.pcszClass = NULL;
2105 Info.oaifInFlags = OAIF_ALLOW_REGISTRATION | OAIF_EXEC;
2106
2107 //if (SHOpenWithDialog(sei_tmp.hwnd, &Info) != S_OK)
2109 do_error_dialog(retval, sei_tmp.hwnd, wszApplicationName);
2110 }
2111 return retval > 32;
2112 }
2113
2114 if (!(sei_tmp.fMask & SEE_MASK_IDLIST) && // Not an ID List
2115 (StrCmpNIW(sei_tmp.lpFile, L"shell:", 6) == 0 ||
2116 StrCmpNW(sei_tmp.lpFile, L"::{", 3) == 0))
2117 {
2118 CComHeapPtr<ITEMIDLIST> pidlParsed;
2119 HRESULT hr = SHParseDisplayName(sei_tmp.lpFile, NULL, &pidlParsed, 0, NULL);
2120 if (SUCCEEDED(hr) && SHELL_InvokePidl(&sei_tmp, pidlParsed))
2121 {
2122 sei_tmp.hInstApp = (HINSTANCE)UlongToHandle(42);
2123 return TRUE;
2124 }
2125 }
2126
2127 /* Has the IDList not yet been translated? */
2128 if (sei_tmp.fMask & SEE_MASK_IDLIST)
2129 {
2130 appKnownSingular = SHELL_translate_idlist( &sei_tmp, wszParameters,
2131 parametersLen,
2132 wszApplicationName,
2133 dwApplicationNameLen );
2134 }
2135
2136 /* convert file URLs */
2137 if (UrlIsFileUrlW(sei_tmp.lpFile))
2138 {
2141 if (!buf.Allocate(size) || FAILED(PathCreateFromUrlW(sei_tmp.lpFile, buf, &size, 0)))
2142 return SE_ERR_OOM;
2143
2144 wszApplicationName.Attach(buf.Detach());
2145 sei_tmp.lpFile = wszApplicationName;
2146 }
2147 else /* or expand environment strings (not both!) */
2148 {
2149 LPWSTR tmp = expand_environment(sei_tmp.lpFile);
2150 if (tmp)
2151 {
2152 wszApplicationName.Attach(tmp);
2153 /* appKnownSingular unmodified */
2154 sei_tmp.lpFile = wszApplicationName;
2155 }
2156 }
2157
2158 /* Else, try to execute the filename */
2159 TRACE("execute: %s,%s,%s\n", debugstr_w(wszApplicationName), debugstr_w(wszParameters), debugstr_w(wszDir));
2160
2161 /* separate out command line arguments from executable file name */
2162 LPCWSTR lpFile;
2163 WCHAR wfileName[MAX_PATH];
2164 if (!*sei_tmp.lpParameters && !appKnownSingular)
2165 {
2166 /* If the executable path is quoted, handle the rest of the command line as parameters. */
2167 if (sei_tmp.lpFile[0] == L'"')
2168 {
2169 LPWSTR src = wszApplicationName/*sei_tmp.lpFile*/ + 1;
2170 LPWSTR dst = wfileName;
2171 LPWSTR end;
2172
2173 /* copy the unquoted executable path to 'wfileName' */
2174 while(*src && *src != L'"')
2175 *dst++ = *src++;
2176
2177 *dst = L'\0';
2178
2179 if (*src == L'"')
2180 {
2181 end = ++src;
2182
2183 while(isspaceW(*src))
2184 ++src;
2185 }
2186 else
2187 end = src;
2188
2189 /* copy the parameter string to 'wszParameters' */
2190 strcpyW(wszParameters, src);
2191
2192 /* terminate previous command string after the quote character */
2193 *end = L'\0';
2194 lpFile = wfileName;
2195 }
2196 /* We have to test sei instead of sei_tmp because sei_tmp had its
2197 * input fMask modified above in SHELL_translate_idlist.
2198 * This code is needed to handle the case where we only have an
2199 * lpIDList with multiple CLSID/PIDL's (not 'My Computer' only) */
2200 else if ((sei->fMask & SEE_MASK_IDLIST) == SEE_MASK_IDLIST)
2201 {
2202 WCHAR buffer[MAX_PATH], xlpFile[MAX_PATH];
2203 LPWSTR space, s;
2204
2205 LPWSTR beg = wszApplicationName;
2206 for(s = beg; (space = const_cast<LPWSTR>(strchrW(s, L' '))); s = space + 1)
2207 {
2208 int idx = space - sei_tmp.lpFile;
2209 memcpy(buffer, sei_tmp.lpFile, idx * sizeof(WCHAR));
2210 buffer[idx] = '\0';
2211
2212 if (SearchPathW(*sei_tmp.lpDirectory ? sei_tmp.lpDirectory : NULL,
2213 buffer, L".exe", _countof(xlpFile), xlpFile, NULL))
2214 {
2215 /* separate out command from parameter string */
2216 LPCWSTR p = space + 1;
2217
2218 while(isspaceW(*p))
2219 ++p;
2220
2221 strcpyW(wszParameters, p);
2222 *space = L'\0';
2223
2224 break;
2225 }
2226 }
2227 lpFile = sei_tmp.lpFile;
2228 }
2229 else
2230 {
2231 lpFile = sei_tmp.lpFile;
2232 }
2233 }
2234 else
2235 lpFile = sei_tmp.lpFile;
2236
2237 WCHAR wcmdBuffer[1024];
2238 LPWSTR wcmd = wcmdBuffer;
2239 DWORD wcmdLen = _countof(wcmdBuffer);
2241
2242 /* Only execute if it has an executable extension */
2243 if (PathIsExeW(lpFile))
2244 {
2245 len = lstrlenW(wszApplicationName) + 3;
2246 if (sei_tmp.lpParameters[0])
2247 len += 1 + lstrlenW(wszParameters);
2248 if (len > wcmdLen)
2249 {
2250 wcmdAlloc.Allocate(len);
2251 wcmd = wcmdAlloc;
2252 wcmdLen = len;
2253 }
2254 swprintf(wcmd, L"\"%s\"", (LPWSTR)wszApplicationName);
2255 if (sei_tmp.lpParameters[0])
2256 {
2257 strcatW(wcmd, L" ");
2258 strcatW(wcmd, wszParameters);
2259 }
2260
2261 retval = execfunc(wcmd, NULL, FALSE, &sei_tmp, sei);
2262 if (retval > 32)
2263 return TRUE;
2264 }
2265
2266 /* Else, try to find the executable */
2267 WCHAR wszKeyname[256];
2269 wcmd[0] = UNICODE_NULL;
2270 retval = SHELL_FindExecutable(sei_tmp.lpDirectory, lpFile, sei_tmp.lpVerb, wcmd, wcmdLen, wszKeyname, &env, (LPITEMIDLIST)sei_tmp.lpIDList, sei_tmp.lpParameters);
2271 if (retval > 32) /* Found */
2272 {
2273 retval = SHELL_quote_and_execute(wcmd, wszParameters, wszKeyname,
2274 wszApplicationName, env, &sei_tmp,
2275 sei, execfunc);
2276 }
2277 else if (PathIsDirectoryW(lpFile))
2278 {
2279 WCHAR wExec[MAX_PATH];
2281 if (lpQuotedFile.Allocate(strlenW(lpFile) + 3))
2282 {
2283 retval = SHELL_FindExecutable(sei_tmp.lpDirectory, L"explorer",
2284 L"open", wExec, MAX_PATH,
2285 NULL, &env, NULL, NULL);
2286 if (retval > 32)
2287 {
2288 swprintf(lpQuotedFile, L"\"%s\"", lpFile);
2289 retval = SHELL_quote_and_execute(wExec, lpQuotedFile,
2290 wszKeyname,
2291 wszApplicationName, env,
2292 &sei_tmp, sei, execfunc);
2293 }
2294 }
2295 else
2296 retval = 0; /* Out of memory */
2297 }
2298 else if (PathIsURLW(lpFile)) /* File not found, check for URL */
2299 {
2300 retval = SHELL_execute_url(lpFile, wcmd, &sei_tmp, sei, execfunc );
2301 }
2302 /* Check if file specified is in the form www.??????.*** */
2303 else if (!strncmpiW(lpFile, L"www", 3))
2304 {
2305 /* if so, prefix lpFile with http:// and call ShellExecute */
2306 WCHAR lpstrTmpFile[256];
2307 strcpyW(lpstrTmpFile, L"http://");
2308 strcatW(lpstrTmpFile, lpFile);
2309 retval = (UINT_PTR)ShellExecuteW(sei_tmp.hwnd, sei_tmp.lpVerb, lpstrTmpFile, NULL, NULL, 0);
2310 }
2311
2312 TRACE("retval %lu\n", retval);
2313
2314 if (retval <= 32 && !(sei_tmp.fMask & SEE_MASK_FLAG_NO_UI))
2315 {
2317
2318 //FIXME
2319 // need full path
2320
2321 Info.pcszFile = wszApplicationName;
2322 Info.pcszClass = NULL;
2323 Info.oaifInFlags = OAIF_ALLOW_REGISTRATION | OAIF_EXEC;
2324
2325 //if (SHOpenWithDialog(sei_tmp.hwnd, &Info) != S_OK)
2327 do_error_dialog(retval, sei_tmp.hwnd, wszApplicationName);
2328 }
2329
2330 sei->hInstApp = (HINSTANCE)(retval > 32 ? 33 : retval);
2331
2332 return retval > 32;
2333}
#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:311
INT WINAPI StrCmpNW(LPCWSTR lpszStr, LPCWSTR lpszComp, INT iLen)
Definition: string.c:504
#define lstrlenW
Definition: compat.h:750
UINT WINAPI GetWindowsDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2352
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
BOOL WINAPI PathIsDirectoryW(LPCWSTR lpszPath)
Definition: path.c:1723
BOOL WINAPI PathIsURLW(LPCWSTR lpstrPath)
Definition: url.c:2432
GLdouble s
Definition: gl.h:2039
GLuint GLuint end
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLenum src
Definition: glext.h:6340
GLuint buffer
Definition: glext.h:5915
GLenum GLenum dst
Definition: glext.h:6340
#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:1394
HRESULT WINAPI SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCITEMIDLIST *ppidlLast)
Definition: pidl.c:1350
BOOL WINAPI SHGetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath)
Definition: pidl.c:1342
#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:164
#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:1639
static HRESULT ShellExecute_ContextMenuVerb(LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:1542
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:1794
static BOOL SHELL_InvokePidl(_In_ LPSHELLEXECUTEINFOW sei, _In_ LPCITEMIDLIST pidl)
Definition: shlexec.cpp:1742
static LONG ShellExecute_FromContextMenuHandlers(LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:1595
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:746
#define SEE_MASK_CLASSALL
Definition: shlexec.cpp:30
static WCHAR * expand_environment(const WCHAR *str)
Definition: shlexec.cpp:1885
static UINT_PTR SHELL_execute_url(LPCWSTR lpFile, LPCWSTR wcmd, LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out, SHELL_ExecuteW32 execfunc)
Definition: shlexec.cpp:1830
static void do_error_dialog(UINT_PTR retval, HWND hwnd, WCHAR *filename)
Definition: shlexec.cpp:1864
HINSTANCE WINAPI ShellExecuteW(HWND hwnd, LPCWSTR lpVerb, LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd)
Definition: shlexec.cpp:2503
static BOOL SHELL_translate_idlist(LPSHELLEXECUTEINFOW sei, LPWSTR wszParameters, DWORD parametersLen, LPWSTR wszApplicationName, DWORD dwApplicationNameLen)
Definition: shlexec.cpp:1695
HRESULT hr
Definition: shlfolder.c:183
#define UrlIsFileUrlW(x)
Definition: shlwapi.h:1377
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 1639 of file shlexec.cpp.

1640{
1641 WCHAR execCmd[1024], classname[1024];
1642 /* launch a document by fileclass like 'WordPad.Document.1' */
1643 /* the Commandline contains 'c:\Path\wordpad.exe "%1"' */
1644 /* FIXME: wcmd should not be of a fixed size. Fixed to 1024, MAX_PATH is way too short! */
1645 ULONG cmask = (psei->fMask & SEE_MASK_CLASSALL);
1646 DWORD resultLen;
1647 BOOL done;
1648 UINT_PTR rslt;
1649
1650 /* FIXME: remove following block when SHELL_quote_and_execute supports hkeyClass parameter */
1651 if (cmask != SEE_MASK_CLASSNAME)
1652 {
1653 WCHAR wcmd[1024];
1655 (cmask == SEE_MASK_CLASSNAME) ? psei->lpClass : NULL,
1656 psei->lpVerb,
1657 execCmd, sizeof(execCmd));
1658
1659 /* FIXME: get the extension of lpFile, check if it fits to the lpClass */
1660 TRACE("SEE_MASK_CLASSNAME->%s, doc->%s\n", debugstr_w(execCmd), debugstr_w(wszApplicationName));
1661
1662 wcmd[0] = '\0';
1663 done = SHELL_ArgifyW(wcmd, ARRAY_SIZE(wcmd), execCmd, wszApplicationName, (LPITEMIDLIST)psei->lpIDList, NULL, &resultLen,
1664 (psei->lpDirectory && *psei->lpDirectory) ? psei->lpDirectory : NULL);
1665 if (!done && wszApplicationName[0])
1666 {
1667 strcatW(wcmd, L" ");
1668 if (*wszApplicationName != '"')
1669 {
1670 strcatW(wcmd, L"\"");
1671 strcatW(wcmd, wszApplicationName);
1672 strcatW(wcmd, L"\"");
1673 }
1674 else
1675 strcatW(wcmd, wszApplicationName);
1676 }
1677 if (resultLen > ARRAY_SIZE(wcmd))
1678 ERR("Argify buffer not large enough... truncating\n");
1679 return execfunc(wcmd, NULL, FALSE, psei, psei_out);
1680 }
1681
1682 strcpyW(classname, psei->lpClass);
1683 rslt = SHELL_FindExecutableByVerb(psei->lpVerb, NULL, classname, execCmd, sizeof(execCmd));
1684
1685 TRACE("SHELL_FindExecutableByVerb returned %u (%s, %s)\n", (unsigned int)rslt, debugstr_w(classname), debugstr_w(execCmd));
1686 if (33 > rslt)
1687 return rslt;
1688 rslt = SHELL_quote_and_execute( execCmd, L"", classname,
1689 wszApplicationName, NULL, psei,
1690 psei_out, execfunc );
1691 return rslt;
1692
1693}
WCHAR classname[128]
Definition: startup.c:15
BOOL HCR_GetExecuteCommandW(HKEY hkeyClass, LPCWSTR szClass, LPCWSTR szVerb, LPWSTR szDest, DWORD len)
Definition: classes.c:197
#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:678
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 1830 of file shlexec.cpp.

1831{
1832 UINT_PTR retval;
1834 LPCWSTR lpstrRes;
1835 INT iSize;
1836 DWORD len;
1837
1838 lpstrRes = strchrW(lpFile, ':');
1839 if (lpstrRes)
1840 iSize = lpstrRes - lpFile;
1841 else
1842 iSize = strlenW(lpFile);
1843
1844 TRACE("Got URL: %s\n", debugstr_w(lpFile));
1845 /* Looking for ...<protocol>\shell<lpVerb>\command */
1846 len = iSize + lstrlenW(L"\\shell\\") + lstrlenW(L"\\command") + 1;
1847 if (psei->lpVerb && *psei->lpVerb)
1848 len += lstrlenW(psei->lpVerb);
1849 else
1850 len += lstrlenW(L"open");
1851 lpstrProtocol.Allocate(len);
1852 memcpy(lpstrProtocol, lpFile, iSize * sizeof(WCHAR));
1853 lpstrProtocol[iSize] = '\0';
1854 strcatW(lpstrProtocol, L"\\shell\\");
1855 strcatW(lpstrProtocol, psei->lpVerb && *psei->lpVerb ? psei->lpVerb : L"open");
1856 strcatW(lpstrProtocol, L"\\command");
1857
1858 retval = execute_from_key(lpstrProtocol, lpFile, NULL, psei->lpParameters,
1859 wcmd, execfunc, psei, psei_out);
1860
1861 return retval;
1862}
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:1168

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 (psei->lpDirectory && psei->lpDirectory[0])
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 startup.lpTitle = (LPWSTR)(psei->fMask & (SEE_MASK_HASLINKNAME | SEE_MASK_HASTITLE) ? psei->lpClass : NULL);
516
517 if (psei->fMask & SEE_MASK_HASLINKNAME)
518 startup.dwFlags |= STARTF_TITLEISLINKNAME;
519
520 if (CreateProcessW(NULL, (LPWSTR)lpCmd, NULL, NULL, FALSE, dwCreationFlags, env,
522 {
523 /* Give 30 seconds to the app to come up, if desired. Probably only needed
524 when starting app immediately before making a DDE connection. */
525 if (shWait)
526 if (WaitForInputIdle(info.hProcess, 30000) == WAIT_FAILED)
527 WARN("WaitForInputIdle failed: Error %d\n", GetLastError() );
528 retval = 33;
529
530 if (psei->fMask & SEE_MASK_NOCLOSEPROCESS)
531 psei_out->hProcess = info.hProcess;
532 else
533 CloseHandle( info.hProcess );
534 CloseHandle( info.hThread );
535 }
536 else if ((retval = GetLastError()) >= 32)
537 {
538 WARN("CreateProcess returned error %ld\n", retval);
539 retval = ERROR_BAD_FORMAT;
540 }
541
542 TRACE("returning %lu\n", retval);
543
544 psei_out->hInstApp = (HINSTANCE)retval;
545
546 if (gcdret)
547 if (!SetCurrentDirectoryW(curdir))
548 ERR("cannot return to directory %s\n", debugstr_w(curdir));
549
550 return retval;
551}
static void startup(void)
#define CloseHandle
Definition: compat.h:739
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:652
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessW(LPCWSTR lpApplicationName, LPWSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4592
unsigned int UINT
Definition: ndis.h:50
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define SEE_MASK_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 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 746 of file shlexec.cpp.

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

679{
680 HKEY hkeyClass;
681 WCHAR verb[MAX_PATH];
682
683 if (RegOpenKeyExW(HKEY_CLASSES_ROOT, classname, 0, 0x02000000, &hkeyClass))
684 return SE_ERR_NOASSOC;
685 if (!HCR_GetDefaultVerbW(hkeyClass, lpVerb, verb, ARRAY_SIZE(verb)))
686 return SE_ERR_NOASSOC;
687 RegCloseKey(hkeyClass);
688
689 /* Looking for ...buffer\shell<verb>\command */
690 wcscat(classname, L"\\shell\\");
691 wcscat(classname, verb);
692 wcscat(classname, L"\\command");
693
695 &commandlen) == ERROR_SUCCESS)
696 {
697 commandlen /= sizeof(WCHAR);
698 if (key) wcscpy(key, classname);
699#if 0
700 LPWSTR tmp;
701 WCHAR param[256];
702 LONG paramlen = sizeof(param);
703
704 /* FIXME: it seems all Windows version don't behave the same here.
705 * the doc states that this ddeexec information can be found after
706 * the exec names.
707 * on Win98, it doesn't appear, but I think it does on Win2k
708 */
709 /* Get the parameters needed by the application
710 from the associated ddeexec key */
711 tmp = strstrW(classname, L"\\command");
712 tmp[0] = '\0';
713 wcscat(classname, wDdeexec);
715 &paramlen) == ERROR_SUCCESS)
716 {
717 paramlen /= sizeof(WCHAR);
718 wcscat(command, L" ");
720 commandlen += paramlen;
721 }
722#endif
723
724 command[commandlen] = '\0';
725
726 return 33; /* FIXME see SHELL_FindExecutable() */
727 }
728
729 return SE_ERR_NOASSOC;
730}
#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:133

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:384
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 1742 of file shlexec.cpp.

1745{
1746 // Bind pidl
1747 CComPtr<IShellFolder> psfFolder;
1748 LPCITEMIDLIST pidlLast;
1749 HRESULT hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &psfFolder), &pidlLast);
1751 return FALSE;
1752
1753 // Get the context menu to invoke a command
1755 hr = psfFolder->GetUIObjectOf(NULL, 1, &pidlLast, IID_NULL_PPV_ARG(IContextMenu, &pCM));
1757 return FALSE;
1758
1759 // Invoke a command
1760 CMINVOKECOMMANDINFO ici = { sizeof(ici) };
1761 ici.fMask = (sei->fMask & (SEE_MASK_NO_CONSOLE | SEE_MASK_ASYNCOK | SEE_MASK_FLAG_NO_UI));
1762 ici.nShow = sei->nShow;
1763 ici.hwnd = sei->hwnd;
1764 char szVerb[VERBKEY_CCHMAX];
1765 if (sei->lpVerb && sei->lpVerb[0])
1766 {
1767 WideCharToMultiByte(CP_ACP, 0, sei->lpVerb, -1, szVerb, _countof(szVerb), NULL, NULL);
1768 szVerb[_countof(szVerb) - 1] = ANSI_NULL; // Avoid buffer overrun
1769 ici.lpVerb = szVerb;
1770 }
1771 else // The default verb?
1772 {
1773 HMENU hMenu = CreatePopupMenu();
1774 const INT idCmdFirst = 1, idCmdLast = 0x7FFF;
1775 hr = pCM->QueryContextMenu(hMenu, 0, idCmdFirst, idCmdLast, CMF_DEFAULTONLY);
1777 {
1778 DestroyMenu(hMenu);
1779 return FALSE;
1780 }
1781
1782 INT nDefaultID = GetMenuDefaultItem(hMenu, FALSE, 0);
1783 DestroyMenu(hMenu);
1784 if (nDefaultID == -1)
1785 nDefaultID = idCmdFirst;
1786
1787 ici.lpVerb = MAKEINTRESOURCEA(nDefaultID - idCmdFirst);
1788 }
1789 hr = pCM->InvokeCommand(&ici);
1790
1791 return !FAILED_UNEXPECTEDLY(hr);
1792}
#define FAILED_UNEXPECTEDLY(hr)
Definition: precomp.h:121
#define VERBKEY_CCHMAX
Definition: precomp.h:130
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 1794 of file shlexec.cpp.

1795{
1796 UINT_PTR retval;
1797 DWORD len;
1799
1800 /* Length of quotes plus length of command plus NULL terminator */
1801 len = 2 + lstrlenW(wcmd) + 1;
1802 if (wszParameters[0])
1803 {
1804 /* Length of space plus length of parameters */
1805 len += 1 + lstrlenW(wszParameters);
1806 }
1807 wszQuotedCmd.Allocate(len);
1808 /* Must quote to handle case where cmd contains spaces,
1809 * else security hole if malicious user creates executable file "C:\\Program"
1810 */
1811 strcpyW(wszQuotedCmd, L"\"");
1812 strcatW(wszQuotedCmd, wcmd);
1813 strcatW(wszQuotedCmd, L"\"");
1814 if (wszParameters[0])
1815 {
1816 strcatW(wszQuotedCmd, L" ");
1817 strcatW(wszQuotedCmd, wszParameters);
1818 }
1819
1820 TRACE("%s/%s => %s/%s\n", debugstr_w(wszApplicationName), debugstr_w(psei->lpVerb), debugstr_w(wszQuotedCmd), debugstr_w(wszKeyname));
1821
1822 if (*wszKeyname)
1823 retval = execute_from_key(wszKeyname, wszApplicationName, env, psei->lpParameters, wcmd, execfunc, psei, psei_out);
1824 else
1825 retval = execfunc(wszQuotedCmd, env, FALSE, psei, psei_out);
1826
1827 return retval;
1828}

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

1696{
1698 BOOL appKnownSingular = FALSE;
1699
1700 /* last chance to translate IDList: now also allow CLSID paths */
1702 if (buffer[0] == ':' && buffer[1] == ':') {
1703 /* open shell folder for the specified class GUID */
1704 if (strlenW(buffer) + 1 > parametersLen)
1705 ERR("parameters len exceeds buffer size (%i > %i), truncating\n",
1706 lstrlenW(buffer) + 1, parametersLen);
1707 lstrcpynW(wszParameters, buffer, parametersLen);
1708 if (strlenW(L"explorer.exe") > dwApplicationNameLen)
1709 ERR("application len exceeds buffer size (%i), truncating\n",
1710 dwApplicationNameLen);
1711 lstrcpynW(wszApplicationName, L"explorer.exe", dwApplicationNameLen);
1712 appKnownSingular = TRUE;
1713
1714 sei->fMask &= ~SEE_MASK_INVOKEIDLIST;
1715 } else {
1717 DWORD attribs;
1718 DWORD resultLen;
1719 /* Check if we're executing a directory and if so use the
1720 handler for the Folder class */
1725 HCR_GetExecuteCommandW(0, L"Folder",
1726 sei->lpVerb,
1727 buffer, sizeof(buffer))) {
1728 SHELL_ArgifyW(wszApplicationName, dwApplicationNameLen,
1729 buffer, target, (LPITEMIDLIST)sei->lpIDList, NULL, &resultLen,
1730 (sei->lpDirectory && *sei->lpDirectory) ? sei->lpDirectory : NULL);
1731 if (resultLen > dwApplicationNameLen)
1732 ERR("Argify buffer not large enough... truncating\n");
1733 appKnownSingular = FALSE;
1734 }
1735 sei->fMask &= ~SEE_MASK_INVOKEIDLIST;
1736 }
1737 }
1738 return appKnownSingular;
1739}
#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 618 of file shlexec.cpp.

619{
620 HKEY hkApp = NULL;
621 WCHAR buffer[1024];
622 DWORD len, dwType;
623 LONG res;
624 BOOL found = FALSE;
625
626 if (env) *env = NULL;
627 wcscpy(buffer, L"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\");
630 if (res)
631 {
632 // Add ".exe" extension, if extension does not exists
633 if (PathAddExtensionW(buffer, L".exe"))
634 {
636 }
637 if (res) goto end;
638 }
639
640 len = MAX_PATH * sizeof(WCHAR);
641 res = SHRegQueryValueExW(hkApp, NULL, NULL, &dwType, (LPBYTE)lpResult, &len);
642 if (res != ERROR_SUCCESS || dwType != REG_SZ)
643 goto end;
644
645 found = TRUE;
646
647 if (env)
648 {
649 len = sizeof(buffer);
650 res = SHRegQueryValueExW(hkApp, L"Path", NULL, &dwType, (LPBYTE)buffer, &len);
651 if (res == ERROR_SUCCESS && dwType == REG_SZ && buffer[0])
653 }
654
655end:
656 if (hkApp) RegCloseKey(hkApp);
657 return found;
658}
#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:560
#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 1503 of file shlexec.cpp.

1504{
1505 CComHeapPtr<ITEMIDLIST> allocatedPidl;
1506 LPITEMIDLIST pidl = NULL;
1507
1508 if (sei->lpIDList)
1509 {
1510 pidl = (LPITEMIDLIST)sei->lpIDList;
1511 }
1512 else
1513 {
1514 SFGAOF sfga = 0;
1515 HRESULT hr = SHParseDisplayName(sei->lpFile, NULL, &allocatedPidl, SFGAO_STORAGECAPMASK, &sfga);
1516 if (FAILED(hr))
1517 {
1518 WCHAR Buffer[MAX_PATH] = {};
1519 // FIXME: MAX_PATH.....
1521 if (retval <= 32)
1522 return HRESULT_FROM_WIN32(retval);
1523
1524 hr = SHParseDisplayName(Buffer, NULL, &allocatedPidl, SFGAO_STORAGECAPMASK, &sfga);
1525 // This should not happen, we found it...
1527 return hr;
1528 }
1529
1530 pidl = allocatedPidl;
1531 }
1532
1534 LPCITEMIDLIST pidllast = NULL;
1535 HRESULT hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &shf), &pidllast);
1536 if (FAILED(hr))
1537 return hr;
1538
1539 return shf->GetUIObjectOf(NULL, 1, &pidllast, IID_NULL_PPV_ARG(IContextMenu, &cm));
1540}
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 1368 of file shlexec.cpp.

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

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

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

Referenced by ShellExecute_FromContextMenuHandlers().

◆ shellex_run_context_menu_default()

static HRESULT shellex_run_context_menu_default ( IShellExtInit obj,
LPSHELLEXECUTEINFOW  sei 
)
static

Definition at line 1400 of file shlexec.cpp.

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

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

2651{
2654 LPCWSTR pszVerb = NULL;
2655 WCHAR szFile[MAX_PATH], szFile2[MAX_PATH];
2656 HRESULT hr;
2657 LPCWSTR pchParams;
2658 LPWSTR lpCommand = NULL;
2659
2660 if (pwszCommand == NULL)
2662 1, (ULONG_PTR*)pwszCommand);
2663
2664 __SHCloneStrW(&lpCommand, pwszCommand);
2665 StrTrimW(lpCommand, L" \t");
2666
2667 if (dwSeclFlags & SECL_NO_UI)
2669 if (dwSeclFlags & SECL_LOG_USAGE)
2671 if (dwSeclFlags & SECL_USE_IDLIST)
2673
2674 if (dwSeclFlags & SECL_RUNAS)
2675 {
2676 dwSize = 0;
2677 hr = AssocQueryStringW(ASSOCF_NONE, ASSOCSTR_COMMAND, lpCommand, L"RunAs", NULL, &dwSize);
2678 if (SUCCEEDED(hr) && dwSize != 0)
2679 {
2680 pszVerb = L"runas";
2681 }
2682 }
2683
2684 if (PathIsURLW(lpCommand) || UrlIsW(lpCommand, URLIS_APPLIABLE))
2685 {
2686 StringCchCopyW(szFile, _countof(szFile), lpCommand);
2687 pchParams = NULL;
2688 }
2689 else
2690 {
2691 PCWSTR apPathList[2];
2692
2693 pchParams = SplitParams(lpCommand, szFile, _countof(szFile));
2694 if (szFile[0] != UNICODE_NULL && szFile[1] == L':' &&
2695 szFile[2] == UNICODE_NULL)
2696 {
2697 PathAddBackslashW(szFile);
2698 }
2699
2700 WCHAR szCurDir[MAX_PATH];
2701 GetCurrentDirectoryW(_countof(szCurDir), szCurDir);
2702 if (pwszStartDir)
2703 {
2704 SetCurrentDirectoryW(pwszStartDir);
2705 }
2706
2707 if (PathIsRelativeW(szFile) &&
2708 GetFullPathNameW(szFile, _countof(szFile2), szFile2, NULL) &&
2709 PathFileExistsW(szFile2))
2710 {
2711 StringCchCopyW(szFile, _countof(szFile), szFile2);
2712 }
2713
2714 apPathList[0] = pwszStartDir;
2715 apPathList[1] = NULL;
2716 PathFindOnPathExW(szFile, apPathList, WHICH_DEFAULT);
2717
2718 if (!(dwSeclFlags & SECL_ALLOW_NONEXE))
2719 {
2720 if (!GetBinaryTypeW(szFile, &dwType))
2721 {
2722 SHFree(lpCommand);
2723
2724 if (!(dwSeclFlags & SECL_NO_UI))
2725 {
2726 WCHAR szText[128 + MAX_PATH], szFormat[128];
2728 StringCchPrintfW(szText, _countof(szText), szFormat, szFile);
2729 MessageBoxW(hwnd, szText, NULL, MB_ICONERROR);
2730 }
2731 return CO_E_APPNOTFOUND;
2732 }
2733 }
2734 else
2735 {
2737 {
2738 SHFree(lpCommand);
2739
2740 if (!(dwSeclFlags & SECL_NO_UI))
2741 {
2742 WCHAR szText[128 + MAX_PATH], szFormat[128];
2744 StringCchPrintfW(szText, _countof(szText), szFormat, szFile);
2745 MessageBoxW(hwnd, szText, NULL, MB_ICONERROR);
2746 }
2748 }
2749 }
2750 }
2751
2752 ZeroMemory(&info, sizeof(info));
2753 info.cbSize = sizeof(info);
2754 info.fMask = dwFlags;
2755 info.hwnd = hwnd;
2756 info.lpVerb = pszVerb;
2757 info.lpFile = szFile;
2758 info.lpParameters = (pchParams && *pchParams) ? pchParams : NULL;
2759 info.lpDirectory = pwszStartDir;
2760 info.nShow = nShow;
2761 if (ShellExecuteExW(&info))
2762 {
2763 if (info.lpIDList)
2764 CoTaskMemFree(info.lpIDList);
2765
2766 SHFree(lpCommand);
2767
2768 return S_OK;
2769 }
2770
2771 dwError = GetLastError();
2772
2773 SHFree(lpCommand);
2774
2775 return HRESULT_FROM_WIN32(dwError);
2776}
#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:2598
@ ASSOCSTR_COMMAND
Definition: shlwapi.h:603
@ URLIS_APPLIABLE
Definition: shlwapi.h:1195
#define WHICH_DEFAULT
#define IDS_FILE_NOT_FOUND
Definition: shresdef.h:344
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 1542 of file shlexec.cpp.

1543{
1544 TRACE("%p\n", sei);
1545
1546 CCoInit coInit;
1547
1548 if (FAILED_UNEXPECTEDLY(coInit.hr))
1549 return coInit.hr;
1550
1554 return hr;
1555
1556 CComHeapPtr<char> verb, parameters;
1557 __SHCloneStrWtoA(&verb, sei->lpVerb);
1558 __SHCloneStrWtoA(&parameters, sei->lpParameters);
1559
1560 CMINVOKECOMMANDINFOEX ici = {};
1561 ici.cbSize = sizeof ici;
1563 ici.nShow = sei->nShow;
1564 ici.lpVerb = verb;
1565 ici.hwnd = sei->hwnd;
1566 ici.lpParameters = parameters;
1567
1568 HMENU hMenu = CreatePopupMenu();
1569 BOOL fDefault = !ici.lpVerb || !ici.lpVerb[0];
1570 hr = cm->QueryContextMenu(hMenu, 0, 1, 0x7fff, fDefault ? CMF_DEFAULTONLY : 0);
1571 if (!FAILED_UNEXPECTEDLY(hr))
1572 {
1573 if (fDefault)
1574 {
1575 INT uDefault = GetMenuDefaultItem(hMenu, FALSE, 0);
1576 uDefault = (uDefault != -1) ? uDefault - 1 : 0;
1577 ici.lpVerb = MAKEINTRESOURCEA(uDefault);
1578 }
1579
1580 hr = cm->InvokeCommand((LPCMINVOKECOMMANDINFO)&ici);
1581 if (!FAILED_UNEXPECTEDLY(hr))
1582 hr = S_OK;
1583 }
1584
1585 DestroyMenu(hMenu);
1586
1587 return hr;
1588}
static __inline void __SHCloneStrWtoA(char **target, const WCHAR *source)
Definition: shell32_main.h:157
static HRESULT shellex_get_contextmenu(LPSHELLEXECUTEINFOW sei, CComPtr< IContextMenu > &cm)
Definition: shlexec.cpp:1503

Referenced by SHELL_execute().

◆ ShellExecute_FromContextMenuHandlers()

static LONG ShellExecute_FromContextMenuHandlers ( LPSHELLEXECUTEINFOW  sei)
static

Definition at line 1595 of file shlexec.cpp.

1596{
1597 HKEY hkey, hkeycm = 0;
1598 WCHAR szguid[39];
1599 HRESULT hr;
1600 GUID guid;
1601 DWORD i;
1602 LONG r;
1603
1604 TRACE("%s\n", debugstr_w(sei->lpFile));
1605
1606 hkey = ShellExecute_GetClassKey(sei);
1607 if (!hkey)
1608 return ERROR_FUNCTION_FAILED;
1609
1610 r = RegOpenKeyW(hkey, L"shellex\\ContextMenuHandlers", &hkeycm);
1611 if (r == ERROR_SUCCESS)
1612 {
1613 i = 0;
1614 while (1)
1615 {
1616 r = RegEnumKeyW(hkeycm, i++, szguid, ARRAY_SIZE(szguid));
1617 if (r != ERROR_SUCCESS)
1618 break;
1619
1620 hr = CLSIDFromString(szguid, &guid);
1621 if (SUCCEEDED(hr))
1622 {
1623 /* stop at the first one that succeeds in running */
1624 hr = shellex_load_object_and_run(hkey, &guid, sei);
1625 if (SUCCEEDED(hr))
1626 break;
1627 }
1628 }
1629 RegCloseKey(hkeycm);
1630 }
1631
1632 if (hkey != sei->hkeyClass)
1633 RegCloseKey(hkey);
1634 return r;
1635}
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:1469
static HKEY ShellExecute_GetClassKey(const SHELLEXECUTEINFOW *sei)
Definition: shlexec.cpp:1322
#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 1322 of file shlexec.cpp.

1323{
1324 LPCWSTR ext = NULL, lpClass = NULL;
1326 DWORD type = 0, sz = 0;
1327 HKEY hkey = 0;
1328 LONG r;
1329
1330 if (sei->fMask & SEE_MASK_CLASSALL)
1331 return sei->hkeyClass;
1332
1333 if (sei->fMask & SEE_MASK_CLASSNAME)
1334 lpClass = sei->lpClass;
1335 else
1336 {
1338 TRACE("ext = %s\n", debugstr_w(ext));
1339 if (!ext)
1340 return hkey;
1341
1343 if (r != ERROR_SUCCESS)
1344 return hkey;
1345
1346 r = RegQueryValueExW(hkey, NULL, 0, &type, NULL, &sz);
1347 if (r == ERROR_SUCCESS && type == REG_SZ)
1348 {
1349 sz += sizeof (WCHAR);
1350 cls.Allocate(sz / sizeof(WCHAR));
1351 cls[0] = 0;
1352 RegQueryValueExW(hkey, NULL, 0, &type, (LPBYTE)(LPWSTR)cls, &sz);
1353 }
1354
1355 RegCloseKey( hkey );
1356 lpClass = cls;
1357 }
1358
1359 TRACE("class = %s\n", debugstr_w(lpClass));
1360
1361 hkey = 0;
1362 if (lpClass)
1363 RegOpenKeyW( HKEY_CLASSES_ROOT, lpClass, &hkey);
1364
1365 return hkey;
1366}
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 2366 of file shlexec.cpp.

2367{
2368 // FIXME
2370}
static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
Definition: shlexec.cpp:1906
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 2373 of file shlexec.cpp.

2377{
2378 // FIXME: Show error message
2379}

Referenced by ShellExecuteExW().

◆ ShellExecuteA()

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

Definition at line 2338 of file shlexec.cpp.

2340{
2342
2343 TRACE("%p,%s,%s,%s,%s,%d\n",
2344 hWnd, debugstr_a(lpVerb), debugstr_a(lpFile),
2345 debugstr_a(lpParameters), debugstr_a(lpDirectory), iShowCmd);
2346
2347 sei.cbSize = sizeof(sei);
2349 sei.hwnd = hWnd;
2350 sei.lpVerb = lpVerb;
2351 sei.lpFile = lpFile;
2352 sei.lpParameters = lpParameters;
2354 sei.nShow = iShowCmd;
2355 sei.lpIDList = 0;
2356 sei.lpClass = 0;
2357 sei.hkeyClass = 0;
2358 sei.dwHotKey = 0;
2359 sei.hProcess = 0;
2360
2361 ShellExecuteExA(&sei);
2362 return sei.hInstApp;
2363}
HWND hWnd
Definition: settings.c:17

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

◆ ShellExecuteExA()

Definition at line 2387 of file shlexec.cpp.

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

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

◆ ShellExecuteExW()

Definition at line 2445 of file shlexec.cpp.

2446{
2447 HRESULT hrCoInit;
2448 DWORD dwError;
2449 ULONG fOldMask;
2450
2451 if (sei->cbSize != sizeof(SHELLEXECUTEINFOW))
2452 {
2455 return FALSE;
2456 }
2457
2458 hrCoInit = SHCoInitializeAnyApartment();
2459
2460 if (SHRegGetBoolUSValueW(L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer",
2461 L"MaximizeApps", FALSE, FALSE))
2462 {
2463 switch (sei->nShow)
2464 {
2465 case SW_SHOW:
2466 case SW_SHOWDEFAULT:
2467 case SW_SHOWNORMAL:
2468 case SW_RESTORE:
2469 sei->nShow = SW_SHOWMAXIMIZED;
2470 break;
2471 default:
2472 break;
2473 }
2474 }
2475
2476 fOldMask = sei->fMask;
2477
2478 if (!(fOldMask & SEE_MASK_NOASYNC) && SHELL_InRunDllProcess())
2480
2481 dwError = ShellExecute_Normal(sei);
2482
2483 if (dwError && dwError != ERROR_DLL_NOT_FOUND && dwError != ERROR_CANCELLED)
2484 ShellExecute_ShowError(sei, NULL, dwError);
2485
2486 sei->fMask = fOldMask;
2487
2488 if (SUCCEEDED(hrCoInit))
2490
2491 if (dwError)
2492 SetLastError(dwError);
2493
2494 return dwError == ERROR_SUCCESS;
2495}
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:2366
static VOID ShellExecute_ShowError(_In_ const SHELLEXECUTEINFOW *ExecInfo, _In_opt_ LPCWSTR pszCaption, _In_ DWORD dwError)
Definition: shlexec.cpp:2373
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:770
#define SW_SHOWMAXIMIZED
Definition: winuser.h:773
#define SW_SHOWDEFAULT
Definition: winuser.h:780
#define SW_RESTORE
Definition: winuser.h:779
#define SW_SHOW
Definition: winuser.h:775

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

2505{
2507
2508 TRACE("\n");
2509 sei.cbSize = sizeof(sei);
2511 sei.hwnd = hwnd;
2512 sei.lpVerb = lpVerb;
2513 sei.lpFile = lpFile;
2514 sei.lpParameters = lpParameters;
2516 sei.nShow = nShowCmd;
2517 sei.lpIDList = 0;
2518 sei.lpClass = 0;
2519 sei.hkeyClass = 0;
2520 sei.dwHotKey = 0;
2521 sei.hProcess = 0;
2522
2524 return sei.hInstApp;
2525}

Referenced by _RunHotplug(), _RunMMCpl(), _RunPower(), _RunVolume(), Control_StartApplet(), CPlApplet(), DIALOG_EXECUTE_DlgProc(), 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(), msi_dialog_hyperlink_handler(), OnAddStartMenuItems(), OnAdvancedStartMenuItems(), CAppInfoDisplay::OnCommand(), CShellMenuCallback::OnExec(), CTrayClockWnd::OnLButtonDblClick(), OnLink(), OnNotify(), OnRemoveStartmenuItems(), CZipExtract::CCompleteSettingsPage::OnWizardFinish(), OpenShellFolder(), ProcessPage_OnOpenFileLocation(), PROGRAM_ExecuteProgram(), RegFolderContextMenuCallback(), 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 2598 of file shlexec.cpp.

2599{
2600 LPCWSTR pch;
2601 size_t ich = 0;
2602 if (*psz == L'"')
2603 {
2604 // 1st argument is quoted. the string in quotes is quoted 1st argument.
2605 // [pch] --> [pszArg0+ich]
2606 for (pch = psz + 1; *pch && ich + 1 < cchArg0; ++ich, ++pch)
2607 {
2608 if (*pch == L'"' && pch[1] == L'"')
2609 {
2610 // doubled double quotations found!
2611 pszArg0[ich] = L'"';
2612 }
2613 else if (*pch == L'"')
2614 {
2615 // single double quotation found!
2616 ++pch;
2617 break;
2618 }
2619 else
2620 {
2621 // otherwise
2622 pszArg0[ich] = *pch;
2623 }
2624 }
2625 }
2626 else
2627 {
2628 // 1st argument is unquoted. non-space sequence is 1st argument.
2629 // [pch] --> [pszArg0+ich]
2630 for (pch = psz; *pch && !iswspace(*pch) && ich + 1 < cchArg0; ++ich, ++pch)
2631 {
2632 pszArg0[ich] = *pch;
2633 }
2634 }
2635 pszArg0[ich] = 0;
2636
2637 // skip space
2638 while (iswspace(*pch))
2639 ++pch;
2640
2641 return pch;
2642}
#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 2532 of file shlexec.cpp.

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