mirror of
https://github.com/reactos/reactos.git
synced 2025-01-02 20:43:18 +00:00
[shell32]
Import some changes from Wine to shlexec.cpp patch by Ivan Rodionov see CORE-8196 svn path=/trunk/; revision=63414
This commit is contained in:
parent
1f5094f9a8
commit
ce7e55def9
4 changed files with 216 additions and 131 deletions
|
@ -34,7 +34,7 @@ BOOL HCR_MapTypeToValueW(LPCWSTR szExtension, LPWSTR szFileType, LONG len, BOOL
|
|||
|
||||
/* added because we do not want to have double dots */
|
||||
if (szExtension[0] == '.')
|
||||
bPrependDot = 0;
|
||||
bPrependDot = FALSE;
|
||||
|
||||
if (bPrependDot)
|
||||
szTemp[0] = '.';
|
||||
|
@ -66,7 +66,7 @@ BOOL HCR_MapTypeToValueA(LPCSTR szExtension, LPSTR szFileType, LONG len, BOOL bP
|
|||
|
||||
/* added because we do not want to have double dots */
|
||||
if (szExtension[0] == '.')
|
||||
bPrependDot = 0;
|
||||
bPrependDot = FALSE;
|
||||
|
||||
if (bPrependDot)
|
||||
szTemp[0] = '.';
|
||||
|
@ -109,7 +109,7 @@ BOOL HCR_GetDefaultVerbW(HKEY hkeyClass, LPCWSTR szVerb, LPWSTR szDest, DWORD le
|
|||
|
||||
TRACE("%p %s %p\n", hkeyClass, debugstr_w(szVerb), szDest);
|
||||
|
||||
if (szVerb)
|
||||
if (szVerb && *szVerb)
|
||||
{
|
||||
lstrcpynW(szDest, szVerb, len);
|
||||
return TRUE;
|
||||
|
@ -173,7 +173,7 @@ BOOL HCR_GetExecuteCommandW(HKEY hkeyClass, LPCWSTR szClass, LPCWSTR szVerb, LPW
|
|||
return FALSE;
|
||||
ret = FALSE;
|
||||
|
||||
if (HCR_GetDefaultVerbW(hkeyClass, szVerb, sTempVerb, sizeof(sTempVerb)))
|
||||
if (HCR_GetDefaultVerbW(hkeyClass, szVerb, sTempVerb, sizeof(sTempVerb)/sizeof(sTempVerb[0])))
|
||||
{
|
||||
WCHAR sTemp[MAX_PATH];
|
||||
wcscpy(sTemp, swShell);
|
||||
|
@ -420,7 +420,7 @@ BOOL HCR_GetClassNameA(REFIID riid, LPSTR szDest, DWORD len)
|
|||
}
|
||||
}
|
||||
|
||||
TRACE("-- %s\n", szDest);
|
||||
TRACE("-- (%s)\n", szDest);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1075,7 +1075,7 @@ INT_PTR CALLBACK AboutAuthorsDlgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM
|
|||
/*************************************************************************
|
||||
* AboutDlgProc (internal)
|
||||
*/
|
||||
INT_PTR CALLBACK AboutDlgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
|
||||
static INT_PTR CALLBACK AboutDlgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
|
||||
{
|
||||
static DWORD cxLogoBmp;
|
||||
static DWORD cyLogoBmp;
|
||||
|
|
|
@ -53,7 +53,6 @@ BOOL HCR_GetIconA(LPCSTR szClass, LPSTR szDest, LPCSTR sName, DWORD len, int* pi
|
|||
BOOL HCR_GetClassNameA(REFIID riid, LPSTR szDest, DWORD len);
|
||||
|
||||
BOOL HCR_GetFolderAttributes(LPCITEMIDLIST pidlFolder, LPDWORD dwAttributes);
|
||||
INT_PTR CALLBACK AboutDlgProc(HWND,UINT,WPARAM,LPARAM);
|
||||
DWORD WINAPI ParseFieldA(LPCSTR src, DWORD nField, LPSTR dst, DWORD len);
|
||||
DWORD WINAPI ParseFieldW(LPCWSTR src, DWORD nField, LPWSTR dst, DWORD len);
|
||||
|
||||
|
@ -173,11 +172,6 @@ static LPWSTR __inline __SHCloneStrAtoW(WCHAR **target, const char *source)
|
|||
#define HINSTANCE_32(h16) ((HINSTANCE)(ULONG_PTR)(h16))
|
||||
#define HINSTANCE_16(h32) (LOWORD(h32))
|
||||
|
||||
typedef UINT_PTR (*SHELL_ExecuteW32)(const WCHAR *lpCmd, WCHAR *env, BOOL shWait,
|
||||
const SHELLEXECUTEINFOW *sei, LPSHELLEXECUTEINFOW sei_out);
|
||||
|
||||
BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc);
|
||||
|
||||
extern WCHAR swShell32Name[MAX_PATH];
|
||||
|
||||
BOOL UNIXFS_is_rooted_at_desktop(void);
|
||||
|
|
|
@ -28,6 +28,9 @@ static const WCHAR wszExe[] = L".exe";
|
|||
|
||||
#define SEE_MASK_CLASSALL (SEE_MASK_CLASSNAME | SEE_MASK_CLASSKEY)
|
||||
|
||||
typedef UINT_PTR (*SHELL_ExecuteW32)(const WCHAR *lpCmd, WCHAR *env, BOOL shWait,
|
||||
const SHELLEXECUTEINFOW *sei, LPSHELLEXECUTEINFOW sei_out);
|
||||
|
||||
static void ParseNoTildeEffect(PWSTR &res, LPCWSTR &args, DWORD &len, DWORD &used, int argNum)
|
||||
{
|
||||
bool firstCharQuote = false;
|
||||
|
@ -382,7 +385,12 @@ static BOOL SHELL_ArgifyW(WCHAR* out, DWORD len, const WCHAR* fmt, const WCHAR*
|
|||
}
|
||||
}
|
||||
|
||||
*res = '\0';
|
||||
used++;
|
||||
if (res - out < static_cast<int>(len))
|
||||
*res = '\0';
|
||||
else
|
||||
out[len-1] = '\0';
|
||||
|
||||
TRACE("used %i of %i space\n", used, len);
|
||||
if (out_len)
|
||||
*out_len = used;
|
||||
|
@ -451,7 +459,7 @@ static UINT_PTR SHELL_ExecuteW(const WCHAR *lpCmd, WCHAR *env, BOOL shWait,
|
|||
startup.dwFlags = STARTF_USESHOWWINDOW;
|
||||
startup.wShowWindow = psei->nShow;
|
||||
dwCreationFlags = CREATE_UNICODE_ENVIRONMENT;
|
||||
if (psei->fMask & SEE_MASK_NO_CONSOLE)
|
||||
if (!(psei->fMask & SEE_MASK_NO_CONSOLE))
|
||||
dwCreationFlags |= CREATE_NEW_CONSOLE;
|
||||
startup.lpTitle = (LPWSTR)(psei->fMask & (SEE_MASK_HASLINKNAME | SEE_MASK_HASTITLE) ? psei->lpClass : NULL);
|
||||
|
||||
|
@ -589,28 +597,46 @@ end:
|
|||
return found;
|
||||
}
|
||||
|
||||
static UINT SHELL_FindExecutableByOperation(LPCWSTR lpOperation, LPWSTR key, LPWSTR filetype, LPWSTR command, LONG commandlen)
|
||||
/*************************************************************************
|
||||
* SHELL_FindExecutableByVerb [Internal]
|
||||
*
|
||||
* called from SHELL_FindExecutable or SHELL_execute_class
|
||||
* in/out:
|
||||
* classname a buffer, big enough, to get the key name to do actually the
|
||||
* command "WordPad.Document.1\\shell\\open\\command"
|
||||
* passed as "WordPad.Document.1"
|
||||
* in:
|
||||
* lpVerb the operation on it (open)
|
||||
* commandlen the size of command buffer (in bytes)
|
||||
* out:
|
||||
* command a buffer, to store the command to do the
|
||||
* operation on the file
|
||||
* key a buffer, big enough, to get the key name to do actually the
|
||||
* command "WordPad.Document.1\\shell\\open\\command"
|
||||
* Can be NULL
|
||||
*/
|
||||
static UINT SHELL_FindExecutableByVerb(LPCWSTR lpVerb, LPWSTR key, LPWSTR classname, LPWSTR command, LONG commandlen)
|
||||
{
|
||||
static const WCHAR wCommand[] = L"\\command";
|
||||
HKEY hkeyClass;
|
||||
WCHAR verb[MAX_PATH];
|
||||
|
||||
if (RegOpenKeyExW(HKEY_CLASSES_ROOT, filetype, 0, 0x02000000, &hkeyClass))
|
||||
if (RegOpenKeyExW(HKEY_CLASSES_ROOT, classname, 0, 0x02000000, &hkeyClass))
|
||||
return SE_ERR_NOASSOC;
|
||||
if (!HCR_GetDefaultVerbW(hkeyClass, lpOperation, verb, sizeof(verb) / sizeof(verb[0])))
|
||||
if (!HCR_GetDefaultVerbW(hkeyClass, lpVerb, verb, sizeof(verb) / sizeof(verb[0])))
|
||||
return SE_ERR_NOASSOC;
|
||||
RegCloseKey(hkeyClass);
|
||||
|
||||
/* Looking for ...buffer\shell\<verb>\command */
|
||||
wcscat(filetype, L"\\shell\\");
|
||||
wcscat(filetype, verb);
|
||||
wcscat(filetype, wCommand);
|
||||
wcscat(classname, L"\\shell\\");
|
||||
wcscat(classname, verb);
|
||||
wcscat(classname, wCommand);
|
||||
|
||||
if (RegQueryValueW(HKEY_CLASSES_ROOT, filetype, command,
|
||||
if (RegQueryValueW(HKEY_CLASSES_ROOT, classname, command,
|
||||
&commandlen) == ERROR_SUCCESS)
|
||||
{
|
||||
commandlen /= sizeof(WCHAR);
|
||||
if (key) wcscpy(key, filetype);
|
||||
if (key) wcscpy(key, classname);
|
||||
#if 0
|
||||
LPWSTR tmp;
|
||||
WCHAR param[256];
|
||||
|
@ -624,10 +650,10 @@ static UINT SHELL_FindExecutableByOperation(LPCWSTR lpOperation, LPWSTR key, LPW
|
|||
*/
|
||||
/* Get the parameters needed by the application
|
||||
from the associated ddeexec key */
|
||||
tmp = strstrW(filetype, wCommand);
|
||||
tmp = strstrW(classname, wCommand);
|
||||
tmp[0] = '\0';
|
||||
wcscat(filetype, wDdeexec);
|
||||
if (RegQueryValueW(HKEY_CLASSES_ROOT, filetype, param,
|
||||
wcscat(classname, wDdeexec);
|
||||
if (RegQueryValueW(HKEY_CLASSES_ROOT, classname, param,
|
||||
¶mlen) == ERROR_SUCCESS)
|
||||
{
|
||||
paramlen /= sizeof(WCHAR);
|
||||
|
@ -651,7 +677,7 @@ static UINT SHELL_FindExecutableByOperation(LPCWSTR lpOperation, LPWSTR key, LPW
|
|||
* Utility for code sharing between FindExecutable and ShellExecute
|
||||
* in:
|
||||
* lpFile the name of a file
|
||||
* lpOperation the operation on it (open)
|
||||
* lpVerb the operation on it (open)
|
||||
* out:
|
||||
* lpResult a buffer, big enough :-(, to store the command to do the
|
||||
* operation on the file
|
||||
|
@ -659,12 +685,12 @@ static UINT SHELL_FindExecutableByOperation(LPCWSTR lpOperation, LPWSTR key, LPW
|
|||
* command (it'll be used afterwards for more information
|
||||
* on the operation)
|
||||
*/
|
||||
static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpOperation,
|
||||
static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpVerb,
|
||||
LPWSTR lpResult, DWORD resultLen, LPWSTR key, WCHAR **env, LPITEMIDLIST pidl, LPCWSTR args)
|
||||
{
|
||||
WCHAR *extension = NULL; /* pointer to file extension */
|
||||
WCHAR filetype[256]; /* registry name for this filetype */
|
||||
LONG filetypelen = sizeof(filetype); /* length of above */
|
||||
WCHAR classname[256]; /* registry name for this file type */
|
||||
LONG classnamelen = sizeof(classname); /* length of above */
|
||||
WCHAR command[1024]; /* command from registry */
|
||||
WCHAR wBuffer[256]; /* Used to GetProfileString */
|
||||
UINT retval = SE_ERR_NOASSOC;
|
||||
|
@ -699,7 +725,7 @@ static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpOpera
|
|||
{
|
||||
TRACE("SearchPathW returned non-zero\n");
|
||||
lpFile = xlpFile;
|
||||
/* Hey, isn't this value ignored? Why make this call? Shouldn't we return here? --dank*/
|
||||
/* The file was found in the application-supplied default directory (or the system search path) */
|
||||
}
|
||||
else if (lpPath && SearchPathW(NULL, lpFile, wszExe, sizeof(xlpFile)/sizeof(WCHAR), xlpFile, NULL))
|
||||
{
|
||||
|
@ -711,8 +737,7 @@ static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpOpera
|
|||
attribs = GetFileAttributesW(lpFile);
|
||||
if (attribs != INVALID_FILE_ATTRIBUTES && (attribs & FILE_ATTRIBUTE_DIRECTORY))
|
||||
{
|
||||
wcscpy(filetype, L"Folder");
|
||||
filetypelen = 6; /* strlen("Folder") */
|
||||
wcscpy(classname, L"Folder");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -736,7 +761,7 @@ static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpOpera
|
|||
|
||||
/* Three places to check: */
|
||||
/* 1. win.ini, [windows], programs (NB no leading '.') */
|
||||
/* 2. Registry, HKEY_CLASS_ROOT\<filetype>\shell\open\command */
|
||||
/* 2. Registry, HKEY_CLASS_ROOT\<classname>\shell\open\command */
|
||||
/* 3. win.ini, [extensions], extension (NB no leading '.' */
|
||||
/* All I know of the order is that registry is checked before */
|
||||
/* extensions; however, it'd make sense to check the programs */
|
||||
|
@ -773,28 +798,26 @@ static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpOpera
|
|||
}
|
||||
|
||||
/* Check registry */
|
||||
if (RegQueryValueW(HKEY_CLASSES_ROOT, extension, filetype,
|
||||
&filetypelen) == ERROR_SUCCESS)
|
||||
if (RegQueryValueW(HKEY_CLASSES_ROOT, extension, classname,
|
||||
&classnamelen) == ERROR_SUCCESS)
|
||||
{
|
||||
filetypelen /= sizeof(WCHAR);
|
||||
if (filetypelen == sizeof(filetype) / sizeof(WCHAR))
|
||||
filetypelen--;
|
||||
classnamelen /= sizeof(WCHAR);
|
||||
if (classnamelen == sizeof(classname) / sizeof(WCHAR))
|
||||
classnamelen--;
|
||||
|
||||
filetype[filetypelen] = '\0';
|
||||
TRACE("File type: %s\n", debugstr_w(filetype));
|
||||
classname[classnamelen] = '\0';
|
||||
TRACE("File type: %s\n", debugstr_w(classname));
|
||||
}
|
||||
else
|
||||
{
|
||||
*filetype = '\0';
|
||||
filetypelen = 0;
|
||||
*classname = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
if (*filetype)
|
||||
if (*classname)
|
||||
{
|
||||
/* pass the operation string to SHELL_FindExecutableByOperation() */
|
||||
filetype[filetypelen] = '\0';
|
||||
retval = SHELL_FindExecutableByOperation(lpOperation, key, filetype, command, sizeof(command));
|
||||
/* pass the verb string to SHELL_FindExecutableByVerb() */
|
||||
retval = SHELL_FindExecutableByVerb(lpVerb, key, classname, command, sizeof(command));
|
||||
|
||||
if (retval > 32)
|
||||
{
|
||||
|
@ -882,20 +905,34 @@ static unsigned dde_connect(const WCHAR* key, const WCHAR* start, WCHAR* ddeexec
|
|||
{
|
||||
WCHAR regkey[256];
|
||||
WCHAR * endkey = regkey + wcslen(key);
|
||||
WCHAR app[256], topic[256], ifexec[256], res[256];
|
||||
WCHAR app[256], topic[256], ifexec[256], static_res[256];
|
||||
WCHAR * dynamic_res=NULL;
|
||||
WCHAR * res;
|
||||
LONG applen, topiclen, ifexeclen;
|
||||
WCHAR * exec;
|
||||
DWORD ddeInst = 0;
|
||||
DWORD tid;
|
||||
DWORD resultLen;
|
||||
DWORD resultLen, endkeyLen;
|
||||
HSZ hszApp, hszTopic;
|
||||
HCONV hConv;
|
||||
HDDEDATA hDdeData;
|
||||
unsigned ret = SE_ERR_NOASSOC;
|
||||
BOOL unicode = !(GetVersion() & 0x80000000);
|
||||
|
||||
if (strlenW(key) + 1 > sizeof(regkey) / sizeof(regkey[0]))
|
||||
{
|
||||
FIXME("input parameter %s larger than buffer\n", debugstr_w(key));
|
||||
return 2;
|
||||
}
|
||||
wcscpy(regkey, key);
|
||||
wcscpy(endkey, L"\\application");
|
||||
static const WCHAR wApplication[] = L"\\application";
|
||||
endkeyLen = sizeof(regkey) / sizeof(regkey[0]) - (endkey - regkey);
|
||||
if (strlenW(wApplication) + 1 > endkeyLen)
|
||||
{
|
||||
FIXME("endkey %s overruns buffer\n", debugstr_w(wApplication));
|
||||
return 2;
|
||||
}
|
||||
wcscpy(endkey, wApplication);
|
||||
applen = sizeof(app);
|
||||
if (RegQueryValueW(HKEY_CLASSES_ROOT, regkey, app, &applen) != ERROR_SUCCESS)
|
||||
{
|
||||
|
@ -908,6 +945,12 @@ static unsigned dde_connect(const WCHAR* key, const WCHAR* start, WCHAR* ddeexec
|
|||
/* Get application command from start string and find filename of application */
|
||||
if (*start == '"')
|
||||
{
|
||||
if (strlenW(start + 1) + 1 > sizeof(command) / sizeof(command[0]))
|
||||
{
|
||||
FIXME("size of input parameter %s larger than buffer\n",
|
||||
debugstr_w(start + 1));
|
||||
return 2;
|
||||
}
|
||||
wcscpy(command, start + 1);
|
||||
if ((ptr = wcschr(command, '"')))
|
||||
* ptr = 0;
|
||||
|
@ -915,8 +958,9 @@ static unsigned dde_connect(const WCHAR* key, const WCHAR* start, WCHAR* ddeexec
|
|||
}
|
||||
else
|
||||
{
|
||||
LPWSTR p, space;
|
||||
for (p = (LPWSTR)start; (space = const_cast<LPWSTR>(strchrW(p, ' '))); p = space + 1)
|
||||
LPCWSTR p;
|
||||
LPWSTR space;
|
||||
for (p = start; (space = const_cast<LPWSTR>(strchrW(p, ' '))); p = space + 1)
|
||||
{
|
||||
int idx = space - start;
|
||||
memcpy(command, start, idx * sizeof(WCHAR));
|
||||
|
@ -933,6 +977,11 @@ static unsigned dde_connect(const WCHAR* key, const WCHAR* start, WCHAR* ddeexec
|
|||
ERR("Unable to find application path for command %s\n", debugstr_w(start));
|
||||
return ERROR_ACCESS_DENIED;
|
||||
}
|
||||
if (strlenW(ptr) + 1 > sizeof(app) / sizeof(app[0]))
|
||||
{
|
||||
FIXME("size of found path %s larger than buffer\n", debugstr_w(ptr));
|
||||
return 2;
|
||||
}
|
||||
wcscpy(app, ptr);
|
||||
|
||||
/* Remove extensions (including .so) */
|
||||
|
@ -945,8 +994,14 @@ static unsigned dde_connect(const WCHAR* key, const WCHAR* start, WCHAR* ddeexec
|
|||
assert(ptr);
|
||||
*ptr = 0;
|
||||
}
|
||||
|
||||
wcscpy(endkey, L"\\topic");
|
||||
|
||||
static const WCHAR wTopic[] = L"\\topic";
|
||||
if (strlenW(wTopic) + 1 > endkeyLen)
|
||||
{
|
||||
FIXME("endkey %s overruns buffer\n", debugstr_w(wTopic));
|
||||
return 2;
|
||||
}
|
||||
wcscpy(endkey, wTopic);
|
||||
topiclen = sizeof(topic);
|
||||
if (RegQueryValueW(HKEY_CLASSES_ROOT, regkey, topic, &topiclen) != ERROR_SUCCESS)
|
||||
{
|
||||
|
@ -986,7 +1041,13 @@ static unsigned dde_connect(const WCHAR* key, const WCHAR* start, WCHAR* ddeexec
|
|||
SetLastError(ERROR_DDE_FAIL);
|
||||
return 30; /* whatever */
|
||||
}
|
||||
strcpyW(endkey, L"\\ifexec");
|
||||
static const WCHAR wIfexec[] = L"\\ifexec";
|
||||
if (strlenW(wIfexec) + 1 > endkeyLen)
|
||||
{
|
||||
FIXME("endkey %s overruns buffer\n", debugstr_w(wIfexec));
|
||||
return 2;
|
||||
}
|
||||
strcpyW(endkey, wIfexec);
|
||||
ifexeclen = sizeof(ifexec);
|
||||
if (RegQueryValueW(HKEY_CLASSES_ROOT, regkey, ifexec, &ifexeclen) == ERROR_SUCCESS)
|
||||
{
|
||||
|
@ -994,9 +1055,14 @@ static unsigned dde_connect(const WCHAR* key, const WCHAR* start, WCHAR* ddeexec
|
|||
}
|
||||
}
|
||||
|
||||
SHELL_ArgifyW(res, sizeof(res) / sizeof(WCHAR), exec, lpFile, pidl, szCommandline, &resultLen);
|
||||
if (resultLen > sizeof(res) / sizeof(WCHAR))
|
||||
ERR("Argify buffer not large enough, truncated\n");
|
||||
SHELL_ArgifyW(static_res, sizeof(static_res)/sizeof(WCHAR), exec, lpFile, pidl, szCommandline, &resultLen);
|
||||
if (resultLen > sizeof(static_res)/sizeof(WCHAR))
|
||||
{
|
||||
res = dynamic_res = static_cast<WCHAR *>(HeapAlloc(GetProcessHeap(), 0, resultLen * sizeof(WCHAR)));
|
||||
SHELL_ArgifyW(dynamic_res, resultLen, exec, lpFile, pidl, szCommandline, NULL);
|
||||
}
|
||||
else
|
||||
res = static_res;
|
||||
TRACE("%s %s => %s\n", debugstr_w(exec), debugstr_w(lpFile), debugstr_w(res));
|
||||
|
||||
/* It's documented in the KB 330337 that IE has a bug and returns
|
||||
|
@ -1019,6 +1085,8 @@ static unsigned dde_connect(const WCHAR* key, const WCHAR* start, WCHAR* ddeexec
|
|||
WARN("DdeClientTransaction failed with error %04x\n", DdeGetLastError(ddeInst));
|
||||
ret = 33;
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, dynamic_res);
|
||||
|
||||
DdeDisconnect(hConv);
|
||||
|
||||
error:
|
||||
|
@ -1296,7 +1364,7 @@ static HRESULT shellex_run_context_menu_default(IShellExtInit *obj,
|
|||
|
||||
memset(&ici, 0, sizeof ici);
|
||||
ici.cbSize = sizeof ici;
|
||||
ici.fMask = CMIC_MASK_UNICODE | (sei->fMask & (SEE_MASK_NOASYNC | SEE_MASK_ASYNCOK | SEE_MASK_FLAG_NO_UI));
|
||||
ici.fMask = CMIC_MASK_UNICODE | (sei->fMask & (SEE_MASK_NO_CONSOLE | SEE_MASK_NOASYNC | SEE_MASK_ASYNCOK | SEE_MASK_FLAG_NO_UI));
|
||||
ici.nShow = sei->nShow;
|
||||
ici.lpVerb = MAKEINTRESOURCEA(def);
|
||||
ici.hwnd = sei->hwnd;
|
||||
|
@ -1411,34 +1479,61 @@ static LONG ShellExecute_FromContextMenu( LPSHELLEXECUTEINFOW sei )
|
|||
return r;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
WCHAR execCmd[1024], wcmd[1024];
|
||||
WCHAR execCmd[1024], classname[1024];
|
||||
/* launch a document by fileclass like 'WordPad.Document.1' */
|
||||
/* the Commandline contains 'c:\Path\wordpad.exe "%1"' */
|
||||
/* FIXME: wcmd should not be of a fixed size. Fixed to 1024, MAX_PATH is way too short! */
|
||||
ULONG cmask = (psei->fMask & SEE_MASK_CLASSALL);
|
||||
DWORD resultLen;
|
||||
BOOL done;
|
||||
|
||||
HCR_GetExecuteCommandW((cmask == SEE_MASK_CLASSKEY) ? psei->hkeyClass : NULL,
|
||||
(cmask == SEE_MASK_CLASSNAME) ? psei->lpClass : NULL,
|
||||
psei->lpVerb,
|
||||
execCmd, sizeof(execCmd));
|
||||
|
||||
/* FIXME: get the extension of lpFile, check if it fits to the lpClass */
|
||||
TRACE("SEE_MASK_CLASSNAME->%s, doc->%s\n", debugstr_w(execCmd), debugstr_w(wszApplicationName));
|
||||
|
||||
wcmd[0] = '\0';
|
||||
done = SHELL_ArgifyW(wcmd, sizeof(wcmd) / sizeof(WCHAR), execCmd, wszApplicationName, (LPITEMIDLIST)psei->lpIDList, NULL, &resultLen);
|
||||
if (!done && wszApplicationName[0])
|
||||
UINT_PTR rslt;
|
||||
|
||||
/* FIXME: remove following block when SHELL_quote_and_execute supports hkeyClass parameter */
|
||||
if (cmask != SEE_MASK_CLASSNAME)
|
||||
{
|
||||
strcatW(wcmd, L" ");
|
||||
strcatW(wcmd, wszApplicationName);
|
||||
WCHAR wcmd[1024];
|
||||
HCR_GetExecuteCommandW((cmask == SEE_MASK_CLASSKEY) ? psei->hkeyClass : NULL,
|
||||
(cmask == SEE_MASK_CLASSNAME) ? psei->lpClass : NULL,
|
||||
psei->lpVerb,
|
||||
execCmd, sizeof(execCmd));
|
||||
|
||||
/* FIXME: get the extension of lpFile, check if it fits to the lpClass */
|
||||
TRACE("SEE_MASK_CLASSNAME->%s, doc->%s\n", debugstr_w(execCmd), debugstr_w(wszApplicationName));
|
||||
|
||||
wcmd[0] = '\0';
|
||||
done = SHELL_ArgifyW(wcmd, sizeof(wcmd) / sizeof(WCHAR), execCmd, wszApplicationName, (LPITEMIDLIST)psei->lpIDList, NULL, &resultLen);
|
||||
if (!done && wszApplicationName[0])
|
||||
{
|
||||
strcatW(wcmd, L" ");
|
||||
if (*wszApplicationName != '"')
|
||||
{
|
||||
strcatW(wcmd, L"\"");
|
||||
strcatW(wcmd, wszApplicationName);
|
||||
strcatW(wcmd, L"\"");
|
||||
}
|
||||
else
|
||||
strcatW(wcmd, wszApplicationName);
|
||||
}
|
||||
if (resultLen > sizeof(wcmd) / sizeof(WCHAR))
|
||||
ERR("Argify buffer not large enough... truncating\n");
|
||||
return execfunc(wcmd, NULL, FALSE, psei, psei_out);
|
||||
}
|
||||
if (resultLen > sizeof(wcmd) / sizeof(WCHAR))
|
||||
ERR("Argify buffer not large enough... truncating\n");
|
||||
return execfunc(wcmd, NULL, FALSE, psei, psei_out);
|
||||
|
||||
strcpyW(classname, psei->lpClass);
|
||||
rslt = SHELL_FindExecutableByVerb(psei->lpVerb, NULL, classname, execCmd, sizeof(execCmd));
|
||||
|
||||
TRACE("SHELL_FindExecutableByVerb returned %u (%s, %s)\n", (unsigned int)rslt, debugstr_w(classname), debugstr_w(execCmd));
|
||||
if (33 > rslt)
|
||||
return rslt;
|
||||
rslt = SHELL_quote_and_execute( execCmd, L"", classname,
|
||||
wszApplicationName, NULL, psei,
|
||||
psei_out, execfunc );
|
||||
return rslt;
|
||||
|
||||
}
|
||||
|
||||
static BOOL SHELL_translate_idlist(LPSHELLEXECUTEINFOW sei, LPWSTR wszParameters, DWORD parametersLen, LPWSTR wszApplicationName, DWORD dwApplicationNameLen)
|
||||
|
@ -1448,7 +1543,7 @@ static BOOL SHELL_translate_idlist(LPSHELLEXECUTEINFOW sei, LPWSTR wszParameters
|
|||
BOOL appKnownSingular = FALSE;
|
||||
|
||||
/* last chance to translate IDList: now also allow CLSID paths */
|
||||
if (SUCCEEDED(SHELL_GetPathFromIDListForExecuteW((LPCITEMIDLIST)sei->lpIDList, buffer, sizeof(buffer)))) {
|
||||
if (SUCCEEDED(SHELL_GetPathFromIDListForExecuteW((LPCITEMIDLIST)sei->lpIDList, buffer, sizeof(buffer)/sizeof(WCHAR)))) {
|
||||
if (buffer[0] == ':' && buffer[1] == ':') {
|
||||
/* open shell folder for the specified class GUID */
|
||||
if (strlenW(buffer) + 1 > parametersLen)
|
||||
|
@ -1487,7 +1582,7 @@ static BOOL SHELL_translate_idlist(LPSHELLEXECUTEINFOW sei, LPWSTR wszParameters
|
|||
return appKnownSingular;
|
||||
}
|
||||
|
||||
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_quote_and_execute(LPCWSTR wcmd, LPCWSTR wszParameters, LPCWSTR wszKeyname, LPCWSTR wszApplicationName, LPWSTR env, LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out, SHELL_ExecuteW32 execfunc)
|
||||
{
|
||||
UINT_PTR retval;
|
||||
DWORD len;
|
||||
|
@ -1513,17 +1608,17 @@ static UINT_PTR SHELL_quote_and_execute(LPCWSTR wcmd, LPCWSTR wszParameters, LPC
|
|||
strcatW(wszQuotedCmd, wszParameters);
|
||||
}
|
||||
|
||||
TRACE("%s/%s => %s/%s\n", debugstr_w(wszApplicationName), debugstr_w(psei->lpVerb), debugstr_w(wszQuotedCmd), debugstr_w(lpstrProtocol));
|
||||
TRACE("%s/%s => %s/%s\n", debugstr_w(wszApplicationName), debugstr_w(psei->lpVerb), debugstr_w(wszQuotedCmd), debugstr_w(wszKeyname));
|
||||
|
||||
if (*lpstrProtocol)
|
||||
retval = execute_from_key(lpstrProtocol, wszApplicationName, env, psei->lpParameters, wcmd, execfunc, psei, psei_out);
|
||||
if (*wszKeyname)
|
||||
retval = execute_from_key(wszKeyname, wszApplicationName, env, psei->lpParameters, wcmd, execfunc, psei, psei_out);
|
||||
else
|
||||
retval = execfunc(wszQuotedCmd, env, FALSE, psei, psei_out);
|
||||
HeapFree(GetProcessHeap(), 0, wszQuotedCmd);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static UINT_PTR SHELL_execute_url(LPCWSTR lpFile, LPCWSTR wFile, LPCWSTR wcmd, LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out, SHELL_ExecuteW32 execfunc)
|
||||
static UINT_PTR SHELL_execute_url(LPCWSTR lpFile, LPCWSTR wcmd, LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out, SHELL_ExecuteW32 execfunc)
|
||||
{
|
||||
static const WCHAR wShell[] = L"\\shell\\";
|
||||
static const WCHAR wCommand[] = L"\\command";
|
||||
|
@ -1540,9 +1635,9 @@ static UINT_PTR SHELL_execute_url(LPCWSTR lpFile, LPCWSTR wFile, LPCWSTR wcmd, L
|
|||
iSize = strlenW(lpFile);
|
||||
|
||||
TRACE("Got URL: %s\n", debugstr_w(lpFile));
|
||||
/* Looking for ...protocol\shell\lpOperation\command */
|
||||
/* Looking for ...<protocol>\shell\<lpVerb>\command */
|
||||
len = iSize + lstrlenW(wShell) + lstrlenW(wCommand) + 1;
|
||||
if (psei->lpVerb)
|
||||
if (psei->lpVerb && *psei->lpVerb)
|
||||
len += lstrlenW(psei->lpVerb);
|
||||
else
|
||||
len += lstrlenW(wszOpen);
|
||||
|
@ -1550,23 +1645,16 @@ static UINT_PTR SHELL_execute_url(LPCWSTR lpFile, LPCWSTR wFile, LPCWSTR wcmd, L
|
|||
memcpy(lpstrProtocol, lpFile, iSize * sizeof(WCHAR));
|
||||
lpstrProtocol[iSize] = '\0';
|
||||
strcatW(lpstrProtocol, wShell);
|
||||
strcatW(lpstrProtocol, psei->lpVerb ? psei->lpVerb : wszOpen);
|
||||
strcatW(lpstrProtocol, psei->lpVerb && *psei->lpVerb ? psei->lpVerb : wszOpen);
|
||||
strcatW(lpstrProtocol, wCommand);
|
||||
|
||||
/* Remove File Protocol from lpFile */
|
||||
/* In the case file://path/file */
|
||||
if (!strncmpiW(lpFile, wFile, iSize))
|
||||
{
|
||||
lpFile += iSize;
|
||||
while (*lpFile == ':') lpFile++;
|
||||
}
|
||||
retval = execute_from_key(lpstrProtocol, lpFile, NULL, psei->lpParameters,
|
||||
wcmd, execfunc, psei, psei_out);
|
||||
HeapFree(GetProcessHeap(), 0, lpstrProtocol);
|
||||
return retval;
|
||||
}
|
||||
|
||||
void do_error_dialog(UINT_PTR retval, HWND hwnd, WCHAR* filename)
|
||||
static void do_error_dialog(UINT_PTR retval, HWND hwnd, WCHAR* filename)
|
||||
{
|
||||
WCHAR msg[2048];
|
||||
DWORD_PTR msgArguments[3] = { (DWORD_PTR)filename, 0, 0 };
|
||||
|
@ -1591,7 +1679,7 @@ void do_error_dialog(UINT_PTR retval, HWND hwnd, WCHAR* filename)
|
|||
/*************************************************************************
|
||||
* SHELL_execute [Internal]
|
||||
*/
|
||||
BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
|
||||
static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
|
||||
{
|
||||
static const DWORD unsupportedFlags =
|
||||
SEE_MASK_INVOKEIDLIST | SEE_MASK_ICON | SEE_MASK_HOTKEY |
|
||||
|
@ -1608,7 +1696,7 @@ BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
|
|||
SHELLEXECUTEINFOW sei_tmp; /* modifiable copy of SHELLEXECUTEINFO struct */
|
||||
WCHAR wfileName[MAX_PATH];
|
||||
WCHAR *env;
|
||||
WCHAR lpstrProtocol[256];
|
||||
WCHAR wszKeyname[256];
|
||||
LPCWSTR lpFile;
|
||||
UINT_PTR retval = SE_ERR_NOASSOC;
|
||||
BOOL appKnownSingular = FALSE;
|
||||
|
@ -1766,36 +1854,40 @@ BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
|
|||
dwApplicationNameLen );
|
||||
}
|
||||
|
||||
/* expand environment strings */
|
||||
len = ExpandEnvironmentStringsW(sei_tmp.lpFile, NULL, 0);
|
||||
if (len > 0)
|
||||
/* convert file URLs */
|
||||
if (UrlIsFileUrlW(sei_tmp.lpFile))
|
||||
{
|
||||
LPWSTR buf;
|
||||
buf = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
|
||||
DWORD size;
|
||||
|
||||
size = MAX_PATH;
|
||||
buf = static_cast<LPWSTR>(HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR)));
|
||||
if (!buf || FAILED(PathCreateFromUrlW(sei_tmp.lpFile, buf, &size, 0)))
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, buf);
|
||||
return SE_ERR_OOM;
|
||||
}
|
||||
|
||||
ExpandEnvironmentStringsW(sei_tmp.lpFile, buf, len + 1);
|
||||
HeapFree(GetProcessHeap(), 0, wszApplicationName);
|
||||
dwApplicationNameLen = len + 1;
|
||||
dwApplicationNameLen = lstrlenW(buf) + 1;
|
||||
wszApplicationName = buf;
|
||||
/* appKnownSingular unmodified */
|
||||
|
||||
sei_tmp.lpFile = wszApplicationName;
|
||||
}
|
||||
|
||||
if (*sei_tmp.lpParameters)
|
||||
else /* or expand environment strings (not both!) */
|
||||
{
|
||||
len = ExpandEnvironmentStringsW(sei_tmp.lpParameters, NULL, 0);
|
||||
len = ExpandEnvironmentStringsW(sei_tmp.lpFile, NULL, 0);
|
||||
if (len > 0)
|
||||
{
|
||||
LPWSTR buf;
|
||||
len++;
|
||||
buf = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
|
||||
ExpandEnvironmentStringsW(sei_tmp.lpParameters, buf, len);
|
||||
if (wszParameters != parametersBuffer)
|
||||
HeapFree(GetProcessHeap(), 0, wszParameters);
|
||||
wszParameters = buf;
|
||||
parametersLen = len;
|
||||
sei_tmp.lpParameters = wszParameters;
|
||||
buf = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
|
||||
|
||||
ExpandEnvironmentStringsW(sei_tmp.lpFile, buf, len + 1);
|
||||
HeapFree(GetProcessHeap(), 0, wszApplicationName);
|
||||
dwApplicationNameLen = len + 1;
|
||||
wszApplicationName = buf;
|
||||
/* appKnownSingular unmodified */
|
||||
|
||||
sei_tmp.lpFile = wszApplicationName;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1849,6 +1941,7 @@ BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
|
|||
|
||||
/* terminate previous command string after the quote character */
|
||||
*end = L'\0';
|
||||
lpFile = wfileName;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1880,13 +1973,11 @@ BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
|
|||
}
|
||||
}
|
||||
|
||||
lstrcpynW(wfileName, sei_tmp.lpFile, sizeof(wfileName) / sizeof(WCHAR));
|
||||
lpFile = sei_tmp.lpFile;
|
||||
}
|
||||
}
|
||||
else
|
||||
lstrcpynW(wfileName, sei_tmp.lpFile, sizeof(wfileName) / sizeof(WCHAR));
|
||||
|
||||
lpFile = wfileName;
|
||||
lpFile = sei_tmp.lpFile;
|
||||
|
||||
wcmd = wcmdBuffer;
|
||||
len = lstrlenW(wszApplicationName) + 3;
|
||||
|
@ -1919,10 +2010,10 @@ BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
|
|||
|
||||
/* Else, try to find the executable */
|
||||
wcmd[0] = L'\0';
|
||||
retval = SHELL_FindExecutable(sei_tmp.lpDirectory, lpFile, sei_tmp.lpVerb, wcmd, wcmdLen, lpstrProtocol, &env, (LPITEMIDLIST)sei_tmp.lpIDList, sei_tmp.lpParameters);
|
||||
retval = SHELL_FindExecutable(sei_tmp.lpDirectory, lpFile, sei_tmp.lpVerb, wcmd, wcmdLen, wszKeyname, &env, (LPITEMIDLIST)sei_tmp.lpIDList, sei_tmp.lpParameters);
|
||||
if (retval > 32) /* Found */
|
||||
{
|
||||
retval = SHELL_quote_and_execute(wcmd, wszParameters, lpstrProtocol,
|
||||
retval = SHELL_quote_and_execute(wcmd, wszParameters, wszKeyname,
|
||||
wszApplicationName, env, &sei_tmp,
|
||||
sei, execfunc);
|
||||
HeapFree(GetProcessHeap(), 0, env);
|
||||
|
@ -1941,7 +2032,7 @@ BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
|
|||
{
|
||||
swprintf(lpQuotedFile, L"\"%s\"", lpFile);
|
||||
retval = SHELL_quote_and_execute(wExec, lpQuotedFile,
|
||||
lpstrProtocol,
|
||||
wszKeyname,
|
||||
wszApplicationName, env,
|
||||
&sei_tmp, sei, execfunc);
|
||||
HeapFree(GetProcessHeap(), 0, env);
|
||||
|
@ -1953,12 +2044,12 @@ BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
|
|||
}
|
||||
else if (PathIsURLW(lpFile)) /* File not found, check for URL */
|
||||
{
|
||||
retval = SHELL_execute_url(lpFile, L"file", wcmd, &sei_tmp, sei, execfunc );
|
||||
retval = SHELL_execute_url(lpFile, wcmd, &sei_tmp, sei, execfunc );
|
||||
}
|
||||
/* Check if file specified is in the form www.??????.*** */
|
||||
else if (!strncmpiW(lpFile, L"www", 3))
|
||||
{
|
||||
/* if so, append lpFile http:// and call ShellExecute */
|
||||
/* if so, prefix lpFile with http:// and call ShellExecute */
|
||||
WCHAR lpstrTmpFile[256];
|
||||
strcpyW(lpstrTmpFile, L"http://");
|
||||
strcatW(lpstrTmpFile, lpFile);
|
||||
|
@ -1998,19 +2089,19 @@ BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
|
|||
/*************************************************************************
|
||||
* ShellExecuteA [SHELL32.290]
|
||||
*/
|
||||
HINSTANCE WINAPI ShellExecuteA(HWND hWnd, LPCSTR lpOperation, LPCSTR lpFile,
|
||||
HINSTANCE WINAPI ShellExecuteA(HWND hWnd, LPCSTR lpVerb, LPCSTR lpFile,
|
||||
LPCSTR lpParameters, LPCSTR lpDirectory, INT iShowCmd)
|
||||
{
|
||||
SHELLEXECUTEINFOA sei;
|
||||
|
||||
TRACE("%p,%s,%s,%s,%s,%d\n",
|
||||
hWnd, debugstr_a(lpOperation), debugstr_a(lpFile),
|
||||
hWnd, debugstr_a(lpVerb), debugstr_a(lpFile),
|
||||
debugstr_a(lpParameters), debugstr_a(lpDirectory), iShowCmd);
|
||||
|
||||
sei.cbSize = sizeof(sei);
|
||||
sei.fMask = SEE_MASK_FLAG_NO_UI;
|
||||
sei.hwnd = hWnd;
|
||||
sei.lpVerb = lpOperation;
|
||||
sei.lpVerb = lpVerb;
|
||||
sei.lpFile = lpFile;
|
||||
sei.lpParameters = lpParameters;
|
||||
sei.lpDirectory = lpDirectory;
|
||||
|
@ -2090,10 +2181,10 @@ ShellExecuteExW(LPSHELLEXECUTEINFOW sei)
|
|||
/*************************************************************************
|
||||
* ShellExecuteW [SHELL32.294]
|
||||
* from shellapi.h
|
||||
* WINSHELLAPI HINSTANCE APIENTRY ShellExecuteW(HWND hwnd, LPCWSTR lpOperation,
|
||||
* WINSHELLAPI HINSTANCE APIENTRY ShellExecuteW(HWND hwnd, LPCWSTR lpVerb,
|
||||
* LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd);
|
||||
*/
|
||||
HINSTANCE WINAPI ShellExecuteW(HWND hwnd, LPCWSTR lpOperation, LPCWSTR lpFile,
|
||||
HINSTANCE WINAPI ShellExecuteW(HWND hwnd, LPCWSTR lpVerb, LPCWSTR lpFile,
|
||||
LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd)
|
||||
{
|
||||
SHELLEXECUTEINFOW sei;
|
||||
|
@ -2102,7 +2193,7 @@ HINSTANCE WINAPI ShellExecuteW(HWND hwnd, LPCWSTR lpOperation, LPCWSTR lpFile,
|
|||
sei.cbSize = sizeof(sei);
|
||||
sei.fMask = SEE_MASK_FLAG_NO_UI;
|
||||
sei.hwnd = hwnd;
|
||||
sei.lpVerb = lpOperation;
|
||||
sei.lpVerb = lpVerb;
|
||||
sei.lpFile = lpFile;
|
||||
sei.lpParameters = lpParameters;
|
||||
sei.lpDirectory = lpDirectory;
|
||||
|
@ -2122,14 +2213,14 @@ HINSTANCE WINAPI ShellExecuteW(HWND hwnd, LPCWSTR lpOperation, LPCWSTR lpFile,
|
|||
*
|
||||
* FIXME: the callback function most likely doesn't work the same way on Windows.
|
||||
*/
|
||||
EXTERN_C HINSTANCE WINAPI WOWShellExecute(HWND hWnd, LPCSTR lpOperation, LPCSTR lpFile,
|
||||
EXTERN_C HINSTANCE WINAPI WOWShellExecute(HWND hWnd, LPCSTR lpVerb, LPCSTR lpFile,
|
||||
LPCSTR lpParameters, LPCSTR lpDirectory, INT iShowCmd, void *callback)
|
||||
{
|
||||
SHELLEXECUTEINFOW seiW;
|
||||
WCHAR *wVerb = NULL, *wFile = NULL, *wParameters = NULL, *wDirectory = NULL;
|
||||
HANDLE hProcess = 0;
|
||||
|
||||
seiW.lpVerb = lpOperation ? __SHCloneStrAtoW(&wVerb, lpOperation) : NULL;
|
||||
seiW.lpVerb = lpVerb ? __SHCloneStrAtoW(&wVerb, lpVerb) : NULL;
|
||||
seiW.lpFile = lpFile ? __SHCloneStrAtoW(&wFile, lpFile) : NULL;
|
||||
seiW.lpParameters = lpParameters ? __SHCloneStrAtoW(&wParameters, lpParameters) : NULL;
|
||||
seiW.lpDirectory = lpDirectory ? __SHCloneStrAtoW(&wDirectory, lpDirectory) : NULL;
|
||||
|
|
Loading…
Reference in a new issue