mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 16:36:33 +00:00
[SHELL32][SHELL32_APITEST] ShellExecute should accept invalid directory (#7150)
Implement parsing SHELLEXECUTEINFO.lpDirectory. Enhance ShellExecuteEx testcase for invalid directory.
This commit is contained in:
parent
466a19817f
commit
089788a52a
2 changed files with 62 additions and 18 deletions
|
@ -1983,21 +1983,48 @@ static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
|
||||||
else
|
else
|
||||||
*wszParameters = L'\0';
|
*wszParameters = L'\0';
|
||||||
|
|
||||||
|
// Get the working directory
|
||||||
WCHAR dirBuffer[MAX_PATH];
|
WCHAR dirBuffer[MAX_PATH];
|
||||||
LPWSTR wszDir = dirBuffer;
|
LPWSTR wszDir = dirBuffer;
|
||||||
|
wszDir[0] = UNICODE_NULL;
|
||||||
CHeapPtr<WCHAR, CLocalAllocator> wszDirAlloc;
|
CHeapPtr<WCHAR, CLocalAllocator> wszDirAlloc;
|
||||||
if (sei_tmp.lpDirectory)
|
if (sei_tmp.lpDirectory && *sei_tmp.lpDirectory)
|
||||||
{
|
{
|
||||||
len = lstrlenW(sei_tmp.lpDirectory) + 1;
|
if (sei_tmp.fMask & SEE_MASK_DOENVSUBST)
|
||||||
if (len > _countof(dirBuffer))
|
|
||||||
{
|
{
|
||||||
wszDirAlloc.Allocate(len);
|
LPWSTR tmp = expand_environment(sei_tmp.lpDirectory);
|
||||||
wszDir = wszDirAlloc;
|
if (tmp)
|
||||||
|
{
|
||||||
|
wszDirAlloc.Attach(tmp);
|
||||||
|
wszDir = wszDirAlloc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
__SHCloneStrW(&wszDirAlloc, sei_tmp.lpDirectory);
|
||||||
|
if (wszDirAlloc)
|
||||||
|
wszDir = wszDirAlloc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!wszDir[0])
|
||||||
|
{
|
||||||
|
::GetCurrentDirectoryW(_countof(dirBuffer), dirBuffer);
|
||||||
|
wszDir = dirBuffer;
|
||||||
|
}
|
||||||
|
// NOTE: ShellExecute should accept the invalid working directory for historical reason.
|
||||||
|
if (!PathIsDirectoryW(wszDir))
|
||||||
|
{
|
||||||
|
INT iDrive = PathGetDriveNumberW(wszDir);
|
||||||
|
if (iDrive >= 0)
|
||||||
|
{
|
||||||
|
PathStripToRootW(wszDir);
|
||||||
|
if (!PathIsDirectoryW(wszDir))
|
||||||
|
{
|
||||||
|
::GetWindowsDirectoryW(dirBuffer, _countof(dirBuffer));
|
||||||
|
wszDir = dirBuffer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
strcpyW(wszDir, sei_tmp.lpDirectory);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
*wszDir = L'\0';
|
|
||||||
|
|
||||||
/* adjust string pointers to point to the new buffers */
|
/* adjust string pointers to point to the new buffers */
|
||||||
sei_tmp.lpFile = wszApplicationName;
|
sei_tmp.lpFile = wszApplicationName;
|
||||||
|
@ -2128,16 +2155,6 @@ static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*sei_tmp.lpDirectory)
|
|
||||||
{
|
|
||||||
LPWSTR tmp = expand_environment(sei_tmp.lpDirectory);
|
|
||||||
if (tmp)
|
|
||||||
{
|
|
||||||
wszDirAlloc.Attach(tmp);
|
|
||||||
sei_tmp.lpDirectory = wszDir = wszDirAlloc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Else, try to execute the filename */
|
/* Else, try to execute the filename */
|
||||||
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));
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <strsafe.h>
|
#include <strsafe.h>
|
||||||
#include <versionhelpers.h>
|
#include <versionhelpers.h>
|
||||||
|
#include "shell32_apitest_sub.h"
|
||||||
|
|
||||||
static WCHAR s_win_dir[MAX_PATH];
|
static WCHAR s_win_dir[MAX_PATH];
|
||||||
static WCHAR s_sys_dir[MAX_PATH];
|
static WCHAR s_sys_dir[MAX_PATH];
|
||||||
|
@ -440,6 +441,31 @@ static void TEST_AppPath(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_DoInvalidDir(void)
|
||||||
|
{
|
||||||
|
WCHAR szSubProgram[MAX_PATH];
|
||||||
|
if (!FindSubProgram(szSubProgram, _countof(szSubProgram)))
|
||||||
|
{
|
||||||
|
skip("shell32_apitest_sub.exe not found\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD dwExitCode;
|
||||||
|
SHELLEXECUTEINFOW sei = { sizeof(sei), SEE_MASK_FLAG_NO_UI | SEE_MASK_NOCLOSEPROCESS };
|
||||||
|
sei.lpFile = szSubProgram;
|
||||||
|
sei.lpParameters = L"TEST";
|
||||||
|
sei.nShow = SW_SHOWNORMAL;
|
||||||
|
|
||||||
|
// Test invalid path on sei.lpDirectory
|
||||||
|
WCHAR szInvalidPath[MAX_PATH] = L"M:\\This is an invalid path\n";
|
||||||
|
sei.lpDirectory = szInvalidPath;
|
||||||
|
ok_int(ShellExecuteExW(&sei), TRUE);
|
||||||
|
WaitForSingleObject(sei.hProcess, 20 * 1000);
|
||||||
|
GetExitCodeProcess(sei.hProcess, &dwExitCode);
|
||||||
|
ok_long(dwExitCode, 0);
|
||||||
|
CloseHandle(sei.hProcess);
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(ShellExecuteEx)
|
START_TEST(ShellExecuteEx)
|
||||||
{
|
{
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
|
@ -454,6 +480,7 @@ START_TEST(ShellExecuteEx)
|
||||||
TEST_DoTestEntries();
|
TEST_DoTestEntries();
|
||||||
test_properties();
|
test_properties();
|
||||||
test_sei_lpIDList();
|
test_sei_lpIDList();
|
||||||
|
test_DoInvalidDir();
|
||||||
|
|
||||||
TEST_End();
|
TEST_End();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue