mirror of
https://github.com/reactos/reactos.git
synced 2025-06-07 02:10:36 +00:00
[SHELL32] shlexec.cpp: Automate buffer alloc/free (#7068)
Reduce code. Simplify code logic. Ensure leak zero. JIRA issue: CORE-17482 - Use CHeapPtr<WCHAR, CLocalAllocator> for allocation/freeing.
This commit is contained in:
parent
b41332349a
commit
06b6833cf1
1 changed files with 75 additions and 141 deletions
|
@ -559,8 +559,8 @@ static UINT_PTR SHELL_ExecuteW(const WCHAR *lpCmd, WCHAR *env, BOOL shWait,
|
||||||
*/
|
*/
|
||||||
static LPWSTR SHELL_BuildEnvW( const WCHAR *path )
|
static LPWSTR SHELL_BuildEnvW( const WCHAR *path )
|
||||||
{
|
{
|
||||||
WCHAR *strings, *new_env;
|
CHeapPtr<WCHAR, CLocalAllocator> new_env;
|
||||||
WCHAR *p, *p2;
|
WCHAR *strings, *p, *p2;
|
||||||
int total = wcslen(path) + 1;
|
int total = wcslen(path) + 1;
|
||||||
BOOL got_path = FALSE;
|
BOOL got_path = FALSE;
|
||||||
|
|
||||||
|
@ -576,7 +576,7 @@ static LPWSTR SHELL_BuildEnvW( const WCHAR *path )
|
||||||
if (!got_path) total += 5; /* we need to create PATH */
|
if (!got_path) total += 5; /* we need to create PATH */
|
||||||
total++; /* terminating null */
|
total++; /* terminating null */
|
||||||
|
|
||||||
if (!(new_env = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, total * sizeof(WCHAR))))
|
if (!new_env.Allocate(total))
|
||||||
{
|
{
|
||||||
FreeEnvironmentStringsW(strings);
|
FreeEnvironmentStringsW(strings);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -604,7 +604,7 @@ static LPWSTR SHELL_BuildEnvW( const WCHAR *path )
|
||||||
}
|
}
|
||||||
*p2 = 0;
|
*p2 = 0;
|
||||||
FreeEnvironmentStringsW(strings);
|
FreeEnvironmentStringsW(strings);
|
||||||
return new_env;
|
return new_env.Detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -964,7 +964,7 @@ static unsigned dde_connect(const WCHAR* key, const WCHAR* start, WCHAR* ddeexec
|
||||||
WCHAR regkey[256];
|
WCHAR regkey[256];
|
||||||
WCHAR * endkey = regkey + wcslen(key);
|
WCHAR * endkey = regkey + wcslen(key);
|
||||||
WCHAR app[256], topic[256], ifexec[256], static_res[256];
|
WCHAR app[256], topic[256], ifexec[256], static_res[256];
|
||||||
WCHAR * dynamic_res=NULL;
|
CHeapPtr<WCHAR, CLocalAllocator> dynamic_res;
|
||||||
WCHAR * res;
|
WCHAR * res;
|
||||||
LONG applen, topiclen, ifexeclen;
|
LONG applen, topiclen, ifexeclen;
|
||||||
WCHAR * exec;
|
WCHAR * exec;
|
||||||
|
@ -1126,7 +1126,8 @@ static unsigned dde_connect(const WCHAR* key, const WCHAR* start, WCHAR* ddeexec
|
||||||
SHELL_ArgifyW(static_res, ARRAY_SIZE(static_res), exec, lpFile, pidl, szCommandline, &resultLen, NULL);
|
SHELL_ArgifyW(static_res, ARRAY_SIZE(static_res), exec, lpFile, pidl, szCommandline, &resultLen, NULL);
|
||||||
if (resultLen > ARRAY_SIZE(static_res))
|
if (resultLen > ARRAY_SIZE(static_res))
|
||||||
{
|
{
|
||||||
res = dynamic_res = static_cast<WCHAR *>(HeapAlloc(GetProcessHeap(), 0, resultLen * sizeof(WCHAR)));
|
dynamic_res.Allocate(resultLen);
|
||||||
|
res = dynamic_res;
|
||||||
SHELL_ArgifyW(dynamic_res, resultLen, exec, lpFile, pidl, szCommandline, NULL, NULL);
|
SHELL_ArgifyW(dynamic_res, resultLen, exec, lpFile, pidl, szCommandline, NULL, NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1141,11 +1142,11 @@ static unsigned dde_connect(const WCHAR* key, const WCHAR* start, WCHAR* ddeexec
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DWORD lenA = WideCharToMultiByte(CP_ACP, 0, res, -1, NULL, 0, NULL, NULL);
|
DWORD lenA = WideCharToMultiByte(CP_ACP, 0, res, -1, NULL, 0, NULL, NULL);
|
||||||
char *resA = (LPSTR)HeapAlloc(GetProcessHeap(), 0, lenA);
|
CHeapPtr<char, CLocalAllocator> resA;
|
||||||
|
resA.Allocate(lenA);
|
||||||
WideCharToMultiByte(CP_ACP, 0, res, -1, resA, lenA, NULL, NULL);
|
WideCharToMultiByte(CP_ACP, 0, res, -1, resA, lenA, NULL, NULL);
|
||||||
hDdeData = DdeClientTransaction( (LPBYTE)resA, lenA, hConv, 0L, 0,
|
hDdeData = DdeClientTransaction( (LPBYTE)(LPSTR)resA, lenA, hConv, 0L, 0,
|
||||||
XTYP_EXECUTE, 10000, &tid );
|
XTYP_EXECUTE, 10000, &tid );
|
||||||
HeapFree(GetProcessHeap(), 0, resA);
|
|
||||||
}
|
}
|
||||||
if (hDdeData)
|
if (hDdeData)
|
||||||
DdeFreeDataHandle(hDdeData);
|
DdeFreeDataHandle(hDdeData);
|
||||||
|
@ -1153,8 +1154,6 @@ static unsigned dde_connect(const WCHAR* key, const WCHAR* start, WCHAR* ddeexec
|
||||||
WARN("DdeClientTransaction failed with error %04x\n", DdeGetLastError(ddeInst));
|
WARN("DdeClientTransaction failed with error %04x\n", DdeGetLastError(ddeInst));
|
||||||
ret = 33;
|
ret = 33;
|
||||||
|
|
||||||
HeapFree(GetProcessHeap(), 0, dynamic_res);
|
|
||||||
|
|
||||||
DdeDisconnect(hConv);
|
DdeDisconnect(hConv);
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
@ -1323,7 +1322,7 @@ HINSTANCE WINAPI FindExecutableW(LPCWSTR lpFile, LPCWSTR lpDirectory, LPWSTR lpR
|
||||||
static HKEY ShellExecute_GetClassKey(const SHELLEXECUTEINFOW *sei)
|
static HKEY ShellExecute_GetClassKey(const SHELLEXECUTEINFOW *sei)
|
||||||
{
|
{
|
||||||
LPCWSTR ext = NULL, lpClass = NULL;
|
LPCWSTR ext = NULL, lpClass = NULL;
|
||||||
LPWSTR cls = NULL;
|
CHeapPtr<WCHAR, CLocalAllocator> cls;
|
||||||
DWORD type = 0, sz = 0;
|
DWORD type = 0, sz = 0;
|
||||||
HKEY hkey = 0;
|
HKEY hkey = 0;
|
||||||
LONG r;
|
LONG r;
|
||||||
|
@ -1348,9 +1347,9 @@ static HKEY ShellExecute_GetClassKey(const SHELLEXECUTEINFOW *sei)
|
||||||
if (r == ERROR_SUCCESS && type == REG_SZ)
|
if (r == ERROR_SUCCESS && type == REG_SZ)
|
||||||
{
|
{
|
||||||
sz += sizeof (WCHAR);
|
sz += sizeof (WCHAR);
|
||||||
cls = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, sz);
|
cls.Allocate(sz / sizeof(WCHAR));
|
||||||
cls[0] = 0;
|
cls[0] = 0;
|
||||||
RegQueryValueExW(hkey, NULL, 0, &type, (LPBYTE) cls, &sz);
|
RegQueryValueExW(hkey, NULL, 0, &type, (LPBYTE)(LPWSTR)cls, &sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
RegCloseKey( hkey );
|
RegCloseKey( hkey );
|
||||||
|
@ -1363,8 +1362,6 @@ static HKEY ShellExecute_GetClassKey(const SHELLEXECUTEINFOW *sei)
|
||||||
if (lpClass)
|
if (lpClass)
|
||||||
RegOpenKeyW( HKEY_CLASSES_ROOT, lpClass, &hkey);
|
RegOpenKeyW( HKEY_CLASSES_ROOT, lpClass, &hkey);
|
||||||
|
|
||||||
HeapFree(GetProcessHeap(), 0, cls);
|
|
||||||
|
|
||||||
return hkey;
|
return hkey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1745,7 +1742,7 @@ static UINT_PTR SHELL_quote_and_execute(LPCWSTR wcmd, LPCWSTR wszParameters, LPC
|
||||||
{
|
{
|
||||||
UINT_PTR retval;
|
UINT_PTR retval;
|
||||||
DWORD len;
|
DWORD len;
|
||||||
WCHAR *wszQuotedCmd;
|
CHeapPtr<WCHAR, CLocalAllocator> wszQuotedCmd;
|
||||||
|
|
||||||
/* Length of quotes plus length of command plus NULL terminator */
|
/* Length of quotes plus length of command plus NULL terminator */
|
||||||
len = 2 + lstrlenW(wcmd) + 1;
|
len = 2 + lstrlenW(wcmd) + 1;
|
||||||
|
@ -1754,7 +1751,7 @@ static UINT_PTR SHELL_quote_and_execute(LPCWSTR wcmd, LPCWSTR wszParameters, LPC
|
||||||
/* Length of space plus length of parameters */
|
/* Length of space plus length of parameters */
|
||||||
len += 1 + lstrlenW(wszParameters);
|
len += 1 + lstrlenW(wszParameters);
|
||||||
}
|
}
|
||||||
wszQuotedCmd = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
|
wszQuotedCmd.Allocate(len);
|
||||||
/* Must quote to handle case where cmd contains spaces,
|
/* Must quote to handle case where cmd contains spaces,
|
||||||
* else security hole if malicious user creates executable file "C:\\Program"
|
* else security hole if malicious user creates executable file "C:\\Program"
|
||||||
*/
|
*/
|
||||||
|
@ -1773,14 +1770,14 @@ static UINT_PTR SHELL_quote_and_execute(LPCWSTR wcmd, LPCWSTR wszParameters, LPC
|
||||||
retval = execute_from_key(wszKeyname, wszApplicationName, env, psei->lpParameters, wcmd, execfunc, psei, psei_out);
|
retval = execute_from_key(wszKeyname, wszApplicationName, env, psei->lpParameters, wcmd, execfunc, psei, psei_out);
|
||||||
else
|
else
|
||||||
retval = execfunc(wszQuotedCmd, env, FALSE, psei, psei_out);
|
retval = execfunc(wszQuotedCmd, env, FALSE, psei, psei_out);
|
||||||
HeapFree(GetProcessHeap(), 0, wszQuotedCmd);
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static UINT_PTR SHELL_execute_url(LPCWSTR lpFile, 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)
|
||||||
{
|
{
|
||||||
UINT_PTR retval;
|
UINT_PTR retval;
|
||||||
WCHAR *lpstrProtocol;
|
CHeapPtr<WCHAR, CLocalAllocator> lpstrProtocol;
|
||||||
LPCWSTR lpstrRes;
|
LPCWSTR lpstrRes;
|
||||||
INT iSize;
|
INT iSize;
|
||||||
DWORD len;
|
DWORD len;
|
||||||
|
@ -1798,7 +1795,7 @@ static UINT_PTR SHELL_execute_url(LPCWSTR lpFile, LPCWSTR wcmd, LPSHELLEXECUTEIN
|
||||||
len += lstrlenW(psei->lpVerb);
|
len += lstrlenW(psei->lpVerb);
|
||||||
else
|
else
|
||||||
len += lstrlenW(L"open");
|
len += lstrlenW(L"open");
|
||||||
lpstrProtocol = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
|
lpstrProtocol.Allocate(len);
|
||||||
memcpy(lpstrProtocol, lpFile, iSize * sizeof(WCHAR));
|
memcpy(lpstrProtocol, lpFile, iSize * sizeof(WCHAR));
|
||||||
lpstrProtocol[iSize] = '\0';
|
lpstrProtocol[iSize] = '\0';
|
||||||
strcatW(lpstrProtocol, L"\\shell\\");
|
strcatW(lpstrProtocol, L"\\shell\\");
|
||||||
|
@ -1807,7 +1804,7 @@ static UINT_PTR SHELL_execute_url(LPCWSTR lpFile, LPCWSTR wcmd, LPSHELLEXECUTEIN
|
||||||
|
|
||||||
retval = execute_from_key(lpstrProtocol, lpFile, NULL, psei->lpParameters,
|
retval = execute_from_key(lpstrProtocol, lpFile, NULL, psei->lpParameters,
|
||||||
wcmd, execfunc, psei, psei_out);
|
wcmd, execfunc, psei, psei_out);
|
||||||
HeapFree(GetProcessHeap(), 0, lpstrProtocol);
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1834,22 +1831,20 @@ static void do_error_dialog(UINT_PTR retval, HWND hwnd, WCHAR* filename)
|
||||||
|
|
||||||
static WCHAR *expand_environment( const WCHAR *str )
|
static WCHAR *expand_environment( const WCHAR *str )
|
||||||
{
|
{
|
||||||
WCHAR *buf;
|
CHeapPtr<WCHAR, CLocalAllocator> buf;
|
||||||
DWORD len;
|
DWORD len;
|
||||||
|
|
||||||
len = ExpandEnvironmentStringsW(str, NULL, 0);
|
len = ExpandEnvironmentStringsW(str, NULL, 0);
|
||||||
if (!len) return NULL;
|
if (!len) return NULL;
|
||||||
|
|
||||||
buf = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
|
if (!buf.Allocate(len))
|
||||||
if (!buf) return NULL;
|
return NULL;
|
||||||
|
|
||||||
len = ExpandEnvironmentStringsW(str, buf, len);
|
len = ExpandEnvironmentStringsW(str, buf, len);
|
||||||
if (!len)
|
if (!len)
|
||||||
{
|
|
||||||
HeapFree(GetProcessHeap(), 0, buf);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
return buf;
|
return buf.Detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
|
@ -1862,23 +1857,12 @@ static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
|
||||||
SEE_MASK_CONNECTNETDRV | SEE_MASK_FLAG_DDEWAIT |
|
SEE_MASK_CONNECTNETDRV | SEE_MASK_FLAG_DDEWAIT |
|
||||||
SEE_MASK_ASYNCOK | SEE_MASK_HMONITOR;
|
SEE_MASK_ASYNCOK | SEE_MASK_HMONITOR;
|
||||||
|
|
||||||
WCHAR parametersBuffer[1024], dirBuffer[MAX_PATH], wcmdBuffer[1024];
|
|
||||||
WCHAR *wszApplicationName, *wszParameters, *wszDir, *wcmd;
|
|
||||||
DWORD dwApplicationNameLen = MAX_PATH + 2;
|
|
||||||
DWORD parametersLen = ARRAY_SIZE(parametersBuffer);
|
|
||||||
DWORD dirLen = ARRAY_SIZE(dirBuffer);
|
|
||||||
DWORD wcmdLen = ARRAY_SIZE(wcmdBuffer);
|
|
||||||
DWORD len;
|
DWORD len;
|
||||||
SHELLEXECUTEINFOW sei_tmp; /* modifiable copy of SHELLEXECUTEINFO struct */
|
|
||||||
WCHAR wfileName[MAX_PATH];
|
|
||||||
WCHAR *env;
|
|
||||||
WCHAR wszKeyname[256];
|
|
||||||
LPCWSTR lpFile;
|
|
||||||
UINT_PTR retval = SE_ERR_NOASSOC;
|
UINT_PTR retval = SE_ERR_NOASSOC;
|
||||||
BOOL appKnownSingular = FALSE;
|
BOOL appKnownSingular = FALSE;
|
||||||
|
|
||||||
/* make a local copy of the LPSHELLEXECUTEINFO structure and work with this from now on */
|
/* make a local copy of the LPSHELLEXECUTEINFO structure and work with this from now on */
|
||||||
sei_tmp = *sei;
|
SHELLEXECUTEINFOW sei_tmp = *sei;
|
||||||
|
|
||||||
TRACE("mask=0x%08x hwnd=%p verb=%s file=%s parm=%s dir=%s show=0x%08x class=%s\n",
|
TRACE("mask=0x%08x hwnd=%p verb=%s file=%s parm=%s dir=%s show=0x%08x class=%s\n",
|
||||||
sei_tmp.fMask, sei_tmp.hwnd, debugstr_w(sei_tmp.lpVerb),
|
sei_tmp.fMask, sei_tmp.hwnd, debugstr_w(sei_tmp.lpVerb),
|
||||||
|
@ -1890,9 +1874,11 @@ static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
|
||||||
sei->hProcess = NULL;
|
sei->hProcess = NULL;
|
||||||
|
|
||||||
/* make copies of all path/command strings */
|
/* make copies of all path/command strings */
|
||||||
|
CHeapPtr<WCHAR, CLocalAllocator> wszApplicationName;
|
||||||
|
DWORD dwApplicationNameLen = MAX_PATH + 2;
|
||||||
if (!sei_tmp.lpFile)
|
if (!sei_tmp.lpFile)
|
||||||
{
|
{
|
||||||
wszApplicationName = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, dwApplicationNameLen * sizeof(WCHAR));
|
wszApplicationName.Allocate(dwApplicationNameLen);
|
||||||
*wszApplicationName = '\0';
|
*wszApplicationName = '\0';
|
||||||
}
|
}
|
||||||
else if (*sei_tmp.lpFile == '\"' && sei_tmp.lpFile[(len = strlenW(sei_tmp.lpFile))-1] == '\"')
|
else if (*sei_tmp.lpFile == '\"' && sei_tmp.lpFile[(len = strlenW(sei_tmp.lpFile))-1] == '\"')
|
||||||
|
@ -1900,7 +1886,7 @@ static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
|
||||||
if(len-1 >= dwApplicationNameLen)
|
if(len-1 >= dwApplicationNameLen)
|
||||||
dwApplicationNameLen = len;
|
dwApplicationNameLen = len;
|
||||||
|
|
||||||
wszApplicationName = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, dwApplicationNameLen * sizeof(WCHAR));
|
wszApplicationName.Allocate(dwApplicationNameLen);
|
||||||
memcpy(wszApplicationName, sei_tmp.lpFile + 1, len * sizeof(WCHAR));
|
memcpy(wszApplicationName, sei_tmp.lpFile + 1, len * sizeof(WCHAR));
|
||||||
|
|
||||||
if(len > 2)
|
if(len > 2)
|
||||||
|
@ -1913,7 +1899,7 @@ static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
|
||||||
{
|
{
|
||||||
DWORD l = strlenW(sei_tmp.lpFile) + 1;
|
DWORD l = strlenW(sei_tmp.lpFile) + 1;
|
||||||
if(l > dwApplicationNameLen) dwApplicationNameLen = l + 1;
|
if(l > dwApplicationNameLen) dwApplicationNameLen = l + 1;
|
||||||
wszApplicationName = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, dwApplicationNameLen * sizeof(WCHAR));
|
wszApplicationName.Allocate(dwApplicationNameLen);
|
||||||
memcpy(wszApplicationName, sei_tmp.lpFile, l * sizeof(WCHAR));
|
memcpy(wszApplicationName, sei_tmp.lpFile, l * sizeof(WCHAR));
|
||||||
|
|
||||||
if (wszApplicationName[2] == 0 && wszApplicationName[1] == L':' &&
|
if (wszApplicationName[2] == 0 && wszApplicationName[1] == L':' &&
|
||||||
|
@ -1925,13 +1911,18 @@ static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wszParameters = parametersBuffer;
|
WCHAR parametersBuffer[1024];
|
||||||
|
LPWSTR wszParameters = parametersBuffer;
|
||||||
|
CHeapPtr<WCHAR, CLocalAllocator> wszParamAlloc;
|
||||||
|
DWORD parametersLen = _countof(parametersBuffer);
|
||||||
|
|
||||||
if (sei_tmp.lpParameters)
|
if (sei_tmp.lpParameters)
|
||||||
{
|
{
|
||||||
len = lstrlenW(sei_tmp.lpParameters) + 1;
|
len = lstrlenW(sei_tmp.lpParameters) + 1;
|
||||||
if (len > parametersLen)
|
if (len > parametersLen)
|
||||||
{
|
{
|
||||||
wszParameters = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
|
wszParamAlloc.Allocate(len);
|
||||||
|
wszParameters = wszParamAlloc;
|
||||||
parametersLen = len;
|
parametersLen = len;
|
||||||
}
|
}
|
||||||
strcpyW(wszParameters, sei_tmp.lpParameters);
|
strcpyW(wszParameters, sei_tmp.lpParameters);
|
||||||
|
@ -1939,14 +1930,16 @@ static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
|
||||||
else
|
else
|
||||||
*wszParameters = L'\0';
|
*wszParameters = L'\0';
|
||||||
|
|
||||||
wszDir = dirBuffer;
|
WCHAR dirBuffer[MAX_PATH];
|
||||||
|
LPWSTR wszDir = dirBuffer;
|
||||||
|
CHeapPtr<WCHAR, CLocalAllocator> wszDirAlloc;
|
||||||
if (sei_tmp.lpDirectory)
|
if (sei_tmp.lpDirectory)
|
||||||
{
|
{
|
||||||
len = lstrlenW(sei_tmp.lpDirectory) + 1;
|
len = lstrlenW(sei_tmp.lpDirectory) + 1;
|
||||||
if (len > dirLen)
|
if (len > _countof(dirBuffer))
|
||||||
{
|
{
|
||||||
wszDir = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
|
wszDirAlloc.Allocate(len);
|
||||||
dirLen = len;
|
wszDir = wszDirAlloc;
|
||||||
}
|
}
|
||||||
strcpyW(wszDir, sei_tmp.lpDirectory);
|
strcpyW(wszDir, sei_tmp.lpDirectory);
|
||||||
}
|
}
|
||||||
|
@ -1974,16 +1967,8 @@ static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
hr = pSEH->Execute(&sei_tmp);
|
hr = pSEH->Execute(&sei_tmp);
|
||||||
|
|
||||||
if (hr == S_OK)
|
if (hr == S_OK)
|
||||||
{
|
|
||||||
HeapFree(GetProcessHeap(), 0, wszApplicationName);
|
|
||||||
if (wszParameters != parametersBuffer)
|
|
||||||
HeapFree(GetProcessHeap(), 0, wszParameters);
|
|
||||||
if (wszDir != dirBuffer)
|
|
||||||
HeapFree(GetProcessHeap(), 0, wszDir);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SHGetPathFromIDListW((LPCITEMIDLIST)sei_tmp.lpIDList, wszApplicationName);
|
SHGetPathFromIDListW((LPCITEMIDLIST)sei_tmp.lpIDList, wszApplicationName);
|
||||||
|
@ -1993,23 +1978,19 @@ static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
|
||||||
|
|
||||||
if (sei_tmp.fMask & SEE_MASK_DOENVSUBST)
|
if (sei_tmp.fMask & SEE_MASK_DOENVSUBST)
|
||||||
{
|
{
|
||||||
WCHAR *tmp;
|
WCHAR *tmp = expand_environment(sei_tmp.lpFile);
|
||||||
|
if (tmp)
|
||||||
tmp = expand_environment(sei_tmp.lpFile);
|
|
||||||
if (!tmp)
|
|
||||||
{
|
{
|
||||||
return FALSE;
|
wszApplicationName.Attach(tmp);
|
||||||
|
sei_tmp.lpFile = wszApplicationName;
|
||||||
}
|
}
|
||||||
HeapFree(GetProcessHeap(), 0, wszApplicationName);
|
|
||||||
sei_tmp.lpFile = wszApplicationName = tmp;
|
|
||||||
|
|
||||||
tmp = expand_environment(sei_tmp.lpDirectory);
|
tmp = expand_environment(sei_tmp.lpDirectory);
|
||||||
if (!tmp)
|
if (tmp)
|
||||||
{
|
{
|
||||||
return FALSE;
|
wszDirAlloc.Attach(tmp);
|
||||||
|
sei_tmp.lpDirectory = wszDir = wszDirAlloc;
|
||||||
}
|
}
|
||||||
if (wszDir != dirBuffer) HeapFree(GetProcessHeap(), 0, wszDir);
|
|
||||||
sei_tmp.lpDirectory = wszDir = tmp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((sei_tmp.fMask & SEE_MASK_INVOKEIDLIST) == SEE_MASK_INVOKEIDLIST)
|
if ((sei_tmp.fMask & SEE_MASK_INVOKEIDLIST) == SEE_MASK_INVOKEIDLIST)
|
||||||
|
@ -2018,11 +1999,6 @@ static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
sei->hInstApp = (HINSTANCE)42;
|
sei->hInstApp = (HINSTANCE)42;
|
||||||
HeapFree(GetProcessHeap(), 0, wszApplicationName);
|
|
||||||
if (wszParameters != parametersBuffer)
|
|
||||||
HeapFree(GetProcessHeap(), 0, wszParameters);
|
|
||||||
if (wszDir != dirBuffer)
|
|
||||||
HeapFree(GetProcessHeap(), 0, wszDir);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2031,11 +2007,6 @@ static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
|
||||||
if (ERROR_SUCCESS == ShellExecute_FromContextMenuHandlers(&sei_tmp))
|
if (ERROR_SUCCESS == ShellExecute_FromContextMenuHandlers(&sei_tmp))
|
||||||
{
|
{
|
||||||
sei->hInstApp = (HINSTANCE) 33;
|
sei->hInstApp = (HINSTANCE) 33;
|
||||||
HeapFree(GetProcessHeap(), 0, wszApplicationName);
|
|
||||||
if (wszParameters != parametersBuffer)
|
|
||||||
HeapFree(GetProcessHeap(), 0, wszParameters);
|
|
||||||
if (wszDir != dirBuffer)
|
|
||||||
HeapFree(GetProcessHeap(), 0, wszDir);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2057,11 +2028,6 @@ static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
|
||||||
DBG_UNREFERENCED_LOCAL_VARIABLE(Info);
|
DBG_UNREFERENCED_LOCAL_VARIABLE(Info);
|
||||||
do_error_dialog(retval, sei_tmp.hwnd, wszApplicationName);
|
do_error_dialog(retval, sei_tmp.hwnd, wszApplicationName);
|
||||||
}
|
}
|
||||||
HeapFree(GetProcessHeap(), 0, wszApplicationName);
|
|
||||||
if (wszParameters != parametersBuffer)
|
|
||||||
HeapFree(GetProcessHeap(), 0, wszParameters);
|
|
||||||
if (wszDir != dirBuffer)
|
|
||||||
HeapFree(GetProcessHeap(), 0, wszDir);
|
|
||||||
return retval > 32;
|
return retval > 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2077,51 +2043,32 @@ static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
|
||||||
/* convert file URLs */
|
/* convert file URLs */
|
||||||
if (UrlIsFileUrlW(sei_tmp.lpFile))
|
if (UrlIsFileUrlW(sei_tmp.lpFile))
|
||||||
{
|
{
|
||||||
LPWSTR buf;
|
CHeapPtr<WCHAR, CLocalAllocator> buf;
|
||||||
DWORD size;
|
DWORD size = MAX_PATH;
|
||||||
|
if (!buf.Allocate(size) || FAILED(PathCreateFromUrlW(sei_tmp.lpFile, buf, &size, 0)))
|
||||||
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;
|
return SE_ERR_OOM;
|
||||||
}
|
|
||||||
|
|
||||||
HeapFree(GetProcessHeap(), 0, wszApplicationName);
|
wszApplicationName.Attach(buf.Detach());
|
||||||
wszApplicationName = buf;
|
|
||||||
sei_tmp.lpFile = wszApplicationName;
|
sei_tmp.lpFile = wszApplicationName;
|
||||||
}
|
}
|
||||||
else /* or expand environment strings (not both!) */
|
else /* or expand environment strings (not both!) */
|
||||||
{
|
{
|
||||||
len = ExpandEnvironmentStringsW(sei_tmp.lpFile, NULL, 0);
|
LPWSTR tmp = expand_environment(sei_tmp.lpFile);
|
||||||
if (len > 0)
|
if (tmp)
|
||||||
{
|
{
|
||||||
LPWSTR buf;
|
wszApplicationName.Attach(tmp);
|
||||||
buf = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
|
|
||||||
|
|
||||||
ExpandEnvironmentStringsW(sei_tmp.lpFile, buf, len + 1);
|
|
||||||
HeapFree(GetProcessHeap(), 0, wszApplicationName);
|
|
||||||
wszApplicationName = buf;
|
|
||||||
/* appKnownSingular unmodified */
|
/* appKnownSingular unmodified */
|
||||||
|
|
||||||
sei_tmp.lpFile = wszApplicationName;
|
sei_tmp.lpFile = wszApplicationName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*sei_tmp.lpDirectory)
|
if (*sei_tmp.lpDirectory)
|
||||||
{
|
{
|
||||||
len = ExpandEnvironmentStringsW(sei_tmp.lpDirectory, NULL, 0);
|
LPWSTR tmp = expand_environment(sei_tmp.lpDirectory);
|
||||||
if (len > 0)
|
if (tmp)
|
||||||
{
|
{
|
||||||
LPWSTR buf;
|
wszDirAlloc.Attach(tmp);
|
||||||
len++;
|
sei_tmp.lpDirectory = wszDir = wszDirAlloc;
|
||||||
buf = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
|
|
||||||
ExpandEnvironmentStringsW(sei_tmp.lpDirectory, buf, len);
|
|
||||||
if (wszDir != dirBuffer)
|
|
||||||
HeapFree(GetProcessHeap(), 0, wszDir);
|
|
||||||
wszDir = buf;
|
|
||||||
sei_tmp.lpDirectory = wszDir;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2129,6 +2076,8 @@ static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
|
||||||
TRACE("execute: %s,%s,%s\n", debugstr_w(wszApplicationName), debugstr_w(wszParameters), debugstr_w(wszDir));
|
TRACE("execute: %s,%s,%s\n", debugstr_w(wszApplicationName), debugstr_w(wszParameters), debugstr_w(wszDir));
|
||||||
|
|
||||||
/* separate out command line arguments from executable file name */
|
/* separate out command line arguments from executable file name */
|
||||||
|
LPCWSTR lpFile;
|
||||||
|
WCHAR wfileName[MAX_PATH];
|
||||||
if (!*sei_tmp.lpParameters && !appKnownSingular)
|
if (!*sei_tmp.lpParameters && !appKnownSingular)
|
||||||
{
|
{
|
||||||
/* If the executable path is quoted, handle the rest of the command line as parameters. */
|
/* If the executable path is quoted, handle the rest of the command line as parameters. */
|
||||||
|
@ -2202,7 +2151,10 @@ static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
|
||||||
else
|
else
|
||||||
lpFile = sei_tmp.lpFile;
|
lpFile = sei_tmp.lpFile;
|
||||||
|
|
||||||
wcmd = wcmdBuffer;
|
WCHAR wcmdBuffer[1024];
|
||||||
|
LPWSTR wcmd = wcmdBuffer;
|
||||||
|
DWORD wcmdLen = _countof(wcmdBuffer);
|
||||||
|
CHeapPtr<WCHAR, CLocalAllocator> wcmdAlloc;
|
||||||
|
|
||||||
/* Only execute if it has an executable extension */
|
/* Only execute if it has an executable extension */
|
||||||
if (PathIsExeW(lpFile))
|
if (PathIsExeW(lpFile))
|
||||||
|
@ -2212,10 +2164,11 @@ static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
|
||||||
len += 1 + lstrlenW(wszParameters);
|
len += 1 + lstrlenW(wszParameters);
|
||||||
if (len > wcmdLen)
|
if (len > wcmdLen)
|
||||||
{
|
{
|
||||||
wcmd = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
|
wcmdAlloc.Allocate(len);
|
||||||
|
wcmd = wcmdAlloc;
|
||||||
wcmdLen = len;
|
wcmdLen = len;
|
||||||
}
|
}
|
||||||
swprintf(wcmd, L"\"%s\"", wszApplicationName);
|
swprintf(wcmd, L"\"%s\"", (LPWSTR)wszApplicationName);
|
||||||
if (sei_tmp.lpParameters[0])
|
if (sei_tmp.lpParameters[0])
|
||||||
{
|
{
|
||||||
strcatW(wcmd, L" ");
|
strcatW(wcmd, L" ");
|
||||||
|
@ -2224,34 +2177,25 @@ static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
|
||||||
|
|
||||||
retval = execfunc(wcmd, NULL, FALSE, &sei_tmp, sei);
|
retval = execfunc(wcmd, NULL, FALSE, &sei_tmp, sei);
|
||||||
if (retval > 32)
|
if (retval > 32)
|
||||||
{
|
|
||||||
HeapFree(GetProcessHeap(), 0, wszApplicationName);
|
|
||||||
if (wszParameters != parametersBuffer)
|
|
||||||
HeapFree(GetProcessHeap(), 0, wszParameters);
|
|
||||||
if (wszDir != dirBuffer)
|
|
||||||
HeapFree(GetProcessHeap(), 0, wszDir);
|
|
||||||
if (wcmd != wcmdBuffer)
|
|
||||||
HeapFree(GetProcessHeap(), 0, wcmd);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Else, try to find the executable */
|
/* Else, try to find the executable */
|
||||||
wcmd[0] = L'\0';
|
WCHAR wszKeyname[256];
|
||||||
|
CHeapPtr<WCHAR, CLocalAllocator> env;
|
||||||
|
wcmd[0] = UNICODE_NULL;
|
||||||
retval = SHELL_FindExecutable(sei_tmp.lpDirectory, lpFile, sei_tmp.lpVerb, wcmd, wcmdLen, wszKeyname, &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 */
|
if (retval > 32) /* Found */
|
||||||
{
|
{
|
||||||
retval = SHELL_quote_and_execute(wcmd, wszParameters, wszKeyname,
|
retval = SHELL_quote_and_execute(wcmd, wszParameters, wszKeyname,
|
||||||
wszApplicationName, env, &sei_tmp,
|
wszApplicationName, env, &sei_tmp,
|
||||||
sei, execfunc);
|
sei, execfunc);
|
||||||
HeapFree(GetProcessHeap(), 0, env);
|
|
||||||
}
|
}
|
||||||
else if (PathIsDirectoryW(lpFile))
|
else if (PathIsDirectoryW(lpFile))
|
||||||
{
|
{
|
||||||
WCHAR wExec[MAX_PATH];
|
WCHAR wExec[MAX_PATH];
|
||||||
WCHAR * lpQuotedFile = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * (strlenW(lpFile) + 3));
|
CHeapPtr<WCHAR, CLocalAllocator> lpQuotedFile;
|
||||||
|
if (lpQuotedFile.Allocate(strlenW(lpFile) + 3))
|
||||||
if (lpQuotedFile)
|
|
||||||
{
|
{
|
||||||
retval = SHELL_FindExecutable(sei_tmp.lpDirectory, L"explorer",
|
retval = SHELL_FindExecutable(sei_tmp.lpDirectory, L"explorer",
|
||||||
L"open", wExec, MAX_PATH,
|
L"open", wExec, MAX_PATH,
|
||||||
|
@ -2263,9 +2207,7 @@ static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
|
||||||
wszKeyname,
|
wszKeyname,
|
||||||
wszApplicationName, env,
|
wszApplicationName, env,
|
||||||
&sei_tmp, sei, execfunc);
|
&sei_tmp, sei, execfunc);
|
||||||
HeapFree(GetProcessHeap(), 0, env);
|
|
||||||
}
|
}
|
||||||
HeapFree(GetProcessHeap(), 0, lpQuotedFile);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
retval = 0; /* Out of memory */
|
retval = 0; /* Out of memory */
|
||||||
|
@ -2302,14 +2244,6 @@ static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
|
||||||
do_error_dialog(retval, sei_tmp.hwnd, wszApplicationName);
|
do_error_dialog(retval, sei_tmp.hwnd, wszApplicationName);
|
||||||
}
|
}
|
||||||
|
|
||||||
HeapFree(GetProcessHeap(), 0, wszApplicationName);
|
|
||||||
if (wszParameters != parametersBuffer)
|
|
||||||
HeapFree(GetProcessHeap(), 0, wszParameters);
|
|
||||||
if (wszDir != dirBuffer)
|
|
||||||
HeapFree(GetProcessHeap(), 0, wszDir);
|
|
||||||
if (wcmd != wcmdBuffer)
|
|
||||||
HeapFree(GetProcessHeap(), 0, wcmd);
|
|
||||||
|
|
||||||
sei->hInstApp = (HINSTANCE)(retval > 32 ? 33 : retval);
|
sei->hInstApp = (HINSTANCE)(retval > 32 ? 33 : retval);
|
||||||
|
|
||||||
return retval > 32;
|
return retval > 32;
|
||||||
|
|
Loading…
Reference in a new issue