mirror of
https://github.com/reactos/reactos.git
synced 2025-08-07 09:42:57 +00:00

Fix the shell32 apitests so that they pass on Windows Server 2003 - Windows 10. Many of these fixes are for Vista+, but the most important fixes are for ShellExecCmdLine and FindExecutable which had issues closing windows after tests and deleting test files. Failing to delete these files breaks the other test (i.e. running ShellExecCmdLine would break FindExecutable and vis-versa.)
323 lines
9.7 KiB
C++
323 lines
9.7 KiB
C++
/*
|
|
* PROJECT: ReactOS API tests
|
|
* LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
|
|
* PURPOSE: Test for SHELLSTATE
|
|
* PROGRAMMERS: Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
|
|
*/
|
|
#include "shelltest.h"
|
|
|
|
#define NDEBUG
|
|
#include <debug.h>
|
|
#include <stdio.h>
|
|
#include <shellutils.h>
|
|
#include <strsafe.h>
|
|
#include <shlwapi.h>
|
|
#include <shlwapi_undoc.h>
|
|
|
|
/* [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer] */
|
|
/* The contents of RegValue ShellState. */
|
|
typedef struct REGSHELLSTATE
|
|
{
|
|
DWORD dwSize;
|
|
SHELLSTATE ss;
|
|
} REGSHELLSTATE, *PREGSHELLSTATE;
|
|
|
|
static void dump(const char *name, const void *ptr, size_t siz)
|
|
{
|
|
char buf[256], sz[16];
|
|
|
|
StringCbCopyA(buf, sizeof(buf), name);
|
|
StringCbCatA(buf, sizeof(buf), ": ");
|
|
|
|
const BYTE *pb = reinterpret_cast<const BYTE *>(ptr);
|
|
while (siz--)
|
|
{
|
|
StringCbPrintfA(sz, sizeof(sz), "%02X ", *pb++);
|
|
StringCbCatA(buf, sizeof(buf), sz);
|
|
}
|
|
|
|
trace("%s\n", buf);
|
|
}
|
|
|
|
static int read_key(REGSHELLSTATE *prss)
|
|
{
|
|
HKEY hKey;
|
|
LONG result;
|
|
DWORD cb;
|
|
static const LPCWSTR s_pszExplorer =
|
|
L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer";
|
|
|
|
memset(prss, 0, sizeof(*prss));
|
|
|
|
result = RegOpenKeyExW(HKEY_CURRENT_USER, s_pszExplorer, 0, KEY_READ, &hKey);
|
|
ok(result == ERROR_SUCCESS, "result was %ld\n", result);
|
|
ok(hKey != NULL, "hKey was NULL\n");
|
|
|
|
if (result != ERROR_SUCCESS || !hKey)
|
|
{
|
|
skip("RegOpenKeyEx failed: %ld\n", result);
|
|
return 1;
|
|
}
|
|
|
|
cb = sizeof(*prss);
|
|
result = RegQueryValueExW(hKey, L"ShellState", NULL, NULL, reinterpret_cast<LPBYTE>(prss), &cb);
|
|
RegCloseKey(hKey);
|
|
|
|
ok(result == ERROR_SUCCESS, "result was %ld\n", result);
|
|
if (result != ERROR_SUCCESS)
|
|
{
|
|
skip("RegQueryValueEx failed: %ld\n", result);
|
|
return 2;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int read_advanced_key(SHELLSTATE* pss)
|
|
{
|
|
HKEY hKey;
|
|
DWORD dwValue, dwSize;
|
|
|
|
hKey = SHGetShellKey(1, L"Advanced", FALSE);
|
|
if (hKey == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
dwSize = sizeof(dwValue);
|
|
if (SHQueryValueExW(hKey, L"Hidden", NULL, NULL, &dwValue, &dwSize) == ERROR_SUCCESS)
|
|
{
|
|
pss->fShowAllObjects = (dwValue == 1);
|
|
pss->fShowSysFiles = (dwValue == 2);
|
|
}
|
|
|
|
dwSize = sizeof(dwValue);
|
|
if (SHQueryValueExW(hKey, L"HideFileExt", NULL, NULL, &dwValue, &dwSize) == ERROR_SUCCESS)
|
|
{
|
|
pss->fShowExtensions = (dwValue == 0);
|
|
}
|
|
|
|
dwSize = sizeof(dwValue);
|
|
if (SHQueryValueExW(hKey, L"DontPrettyPath", NULL, NULL, &dwValue, &dwSize) == ERROR_SUCCESS)
|
|
{
|
|
pss->fDontPrettyPath = (dwValue != 0);
|
|
}
|
|
|
|
dwSize = sizeof(dwValue);
|
|
if (SHQueryValueExW(hKey, L"MapNetDrvBtn", NULL, NULL, &dwValue, &dwSize) == ERROR_SUCCESS)
|
|
{
|
|
pss->fMapNetDrvBtn = (dwValue != 0);
|
|
}
|
|
|
|
dwSize = sizeof(dwValue);
|
|
if (SHQueryValueExW(hKey, L"ShowInfoTip", NULL, NULL, &dwValue, &dwSize) == ERROR_SUCCESS)
|
|
{
|
|
pss->fShowInfoTip = (dwValue != 0);
|
|
}
|
|
|
|
dwSize = sizeof(dwValue);
|
|
if (SHQueryValueExW(hKey, L"HideIcons", NULL, NULL, &dwValue, &dwSize) == ERROR_SUCCESS)
|
|
{
|
|
pss->fHideIcons = (dwValue != 0);
|
|
}
|
|
|
|
dwSize = sizeof(dwValue);
|
|
if (SHQueryValueExW(hKey, L"WebView", NULL, NULL, &dwValue, &dwSize) == ERROR_SUCCESS)
|
|
{
|
|
pss->fWebView = (dwValue != 0);
|
|
}
|
|
|
|
dwSize = sizeof(dwValue);
|
|
if (SHQueryValueExW(hKey, L"Filter", NULL, NULL, &dwValue, &dwSize) == ERROR_SUCCESS)
|
|
{
|
|
pss->fFilter = (dwValue != 0);
|
|
}
|
|
|
|
dwSize = sizeof(dwValue);
|
|
if (SHQueryValueExW(hKey, L"ShowSuperHidden", NULL, NULL, &dwValue, &dwSize) == ERROR_SUCCESS)
|
|
{
|
|
pss->fShowSuperHidden = (dwValue != 0);
|
|
}
|
|
|
|
dwSize = sizeof(dwValue);
|
|
if (SHQueryValueExW(hKey, L"NoNetCrawling", NULL, NULL, &dwValue, &dwSize) == ERROR_SUCCESS)
|
|
{
|
|
pss->fNoNetCrawling = (dwValue != 0);
|
|
}
|
|
|
|
RegCloseKey(hKey);
|
|
return 0;
|
|
}
|
|
|
|
static int dump_pss(SHELLSTATE *pss)
|
|
{
|
|
dump("SHELLSTATE", pss, sizeof(*pss));
|
|
return 0;
|
|
}
|
|
|
|
START_TEST(ShellState)
|
|
{
|
|
OSVERSIONINFO osinfo;
|
|
REGSHELLSTATE rss;
|
|
SHELLSTATE ss, *pss;
|
|
SHELLFLAGSTATE FlagState;
|
|
LPBYTE pb;
|
|
int ret;
|
|
|
|
trace("GetVersion(): 0x%08lX\n", GetVersion());
|
|
|
|
osinfo.dwOSVersionInfoSize = sizeof(osinfo);
|
|
GetVersionEx(&osinfo);
|
|
trace("osinfo.dwMajorVersion: 0x%08lX\n", osinfo.dwMajorVersion);
|
|
trace("osinfo.dwMinorVersion: 0x%08lX\n", osinfo.dwMinorVersion);
|
|
trace("osinfo.dwBuildNumber: 0x%08lX\n", osinfo.dwBuildNumber);
|
|
trace("osinfo.dwPlatformId: 0x%08lX\n", osinfo.dwPlatformId);
|
|
|
|
trace("WINVER: 0x%04X\n", WINVER);
|
|
trace("_WIN32_WINNT: 0x%04X\n", _WIN32_WINNT);
|
|
trace("_WIN32_IE: 0x%04X\n", _WIN32_IE);
|
|
trace("NTDDI_VERSION: 0x%08X\n", NTDDI_VERSION);
|
|
|
|
#ifdef _MSC_VER
|
|
trace("_MSC_VER: 0x%08X\n", int(_MSC_VER));
|
|
#elif defined(__MINGW32__)
|
|
trace("__MINGW32__: 0x%08X\n", int(__MINGW32__));
|
|
#elif defined(__clang__)
|
|
trace("__clang__: 0x%08X\n", int(__clang__));
|
|
#else
|
|
#error Unknown compiler.
|
|
#endif
|
|
|
|
ok(sizeof(REGSHELLSTATE) >= 0x24, "sizeof(REGSHELLSTATE) was %d\n", (int)sizeof(REGSHELLSTATE));
|
|
trace("sizeof(SHELLSTATE): %d\n", (int)sizeof(SHELLSTATE));
|
|
trace("__alignof(SHELLSTATE): %d\n", (int)__alignof(SHELLSTATE));
|
|
trace("sizeof(SHELLFLAGSTATE): %d\n", (int)sizeof(SHELLFLAGSTATE));
|
|
trace("sizeof(CABINETSTATE): %d\n", (int)sizeof(CABINETSTATE));
|
|
|
|
pss = &rss.ss;
|
|
pb = reinterpret_cast<LPBYTE>(pss);
|
|
|
|
ret = read_key(&rss);
|
|
if (ret)
|
|
{
|
|
return;
|
|
}
|
|
|
|
dump_pss(pss);
|
|
ok(rss.dwSize >= 0x24, "rss.dwSize was %ld (0x%lX).\n", rss.dwSize, rss.dwSize);
|
|
|
|
read_advanced_key(&rss.ss);
|
|
|
|
#define DUMP_LONG(x) trace(#x ": 0x%08X\n", int(x));
|
|
#define DUMP_BOOL(x) trace(#x ": %d\n", !!int(x));
|
|
DUMP_BOOL(pss->fShowAllObjects);
|
|
DUMP_BOOL(pss->fShowExtensions);
|
|
DUMP_BOOL(pss->fNoConfirmRecycle);
|
|
DUMP_BOOL(pss->fShowSysFiles);
|
|
DUMP_BOOL(pss->fShowCompColor);
|
|
DUMP_BOOL(pss->fDoubleClickInWebView);
|
|
DUMP_BOOL(pss->fDesktopHTML);
|
|
DUMP_BOOL(pss->fWin95Classic);
|
|
DUMP_BOOL(pss->fDontPrettyPath);
|
|
DUMP_BOOL(pss->fShowAttribCol);
|
|
DUMP_BOOL(pss->fMapNetDrvBtn);
|
|
DUMP_BOOL(pss->fShowInfoTip);
|
|
DUMP_BOOL(pss->fHideIcons);
|
|
DUMP_BOOL(pss->fWebView);
|
|
DUMP_BOOL(pss->fFilter);
|
|
DUMP_BOOL(pss->fShowSuperHidden);
|
|
DUMP_BOOL(pss->fNoNetCrawling);
|
|
DUMP_LONG(pss->lParamSort);
|
|
DUMP_LONG(pss->iSortDirection);
|
|
DUMP_LONG(pss->version);
|
|
DUMP_LONG(pss->lParamSort);
|
|
DUMP_LONG(pss->iSortDirection);
|
|
DUMP_LONG(pss->version);
|
|
DUMP_BOOL(pss->fSepProcess);
|
|
DUMP_BOOL(pss->fStartPanelOn);
|
|
DUMP_BOOL(pss->fShowStartPage);
|
|
#if NTDDI_VERSION >= 0x06000000 // for future use
|
|
DUMP_BOOL(pss->fIconsOnly);
|
|
DUMP_BOOL(pss->fShowTypeOverlay);
|
|
DUMP_BOOL(pss->fShowStatusBar);
|
|
#endif
|
|
|
|
#define SSF_MASK \
|
|
(SSF_SHOWALLOBJECTS | SSF_SHOWEXTENSIONS | SSF_NOCONFIRMRECYCLE | \
|
|
SSF_SHOWCOMPCOLOR | SSF_DOUBLECLICKINWEBVIEW | SSF_DESKTOPHTML | \
|
|
SSF_WIN95CLASSIC | SSF_DONTPRETTYPATH | SSF_SHOWATTRIBCOL | \
|
|
SSF_MAPNETDRVBUTTON | SSF_SHOWINFOTIP | SSF_HIDEICONS)
|
|
// For future:
|
|
// SSF_AUTOCHECKSELECT, SSF_ICONSONLY, SSF_SHOWTYPEOVERLAY, SSF_SHOWSTATUSBAR
|
|
|
|
/* Get the settings */
|
|
memset(&ss, 0, sizeof(ss));
|
|
SHGetSetSettings(&ss, SSF_MASK, FALSE);
|
|
#define CHECK_REG_FLAG(x) ok(pss->x == ss.x, "ss.%s expected %d, was %d\n", #x, (int)pss->x, (int)ss.x)
|
|
CHECK_REG_FLAG(fShowAllObjects);
|
|
CHECK_REG_FLAG(fShowExtensions);
|
|
CHECK_REG_FLAG(fNoConfirmRecycle);
|
|
if (GetNTVersion() != _WIN32_WINNT_VISTA)
|
|
CHECK_REG_FLAG(fShowSysFiles); // No use, test is broken on Vista
|
|
CHECK_REG_FLAG(fShowCompColor);
|
|
CHECK_REG_FLAG(fDoubleClickInWebView);
|
|
CHECK_REG_FLAG(fDesktopHTML);
|
|
CHECK_REG_FLAG(fWin95Classic);
|
|
CHECK_REG_FLAG(fDontPrettyPath);
|
|
CHECK_REG_FLAG(fShowAttribCol);
|
|
CHECK_REG_FLAG(fMapNetDrvBtn);
|
|
CHECK_REG_FLAG(fShowInfoTip);
|
|
CHECK_REG_FLAG(fHideIcons);
|
|
#if NTDDI_VERSION >= 0x06000000 // for future use
|
|
CHECK_REG_FLAG(fAutoCheckSelect);
|
|
CHECK_REG_FLAG(fIconsOnly);
|
|
#endif
|
|
|
|
/* Get the flag settings */
|
|
memset(&FlagState, 0, sizeof(FlagState));
|
|
SHGetSettings(&FlagState, SSF_MASK);
|
|
#define CHECK_FLAG(x) ok(ss.x == FlagState.x, "FlagState.%s expected %d, was %d\n", #x, (int)ss.x, (int)FlagState.x)
|
|
CHECK_FLAG(fShowAllObjects);
|
|
CHECK_FLAG(fShowExtensions);
|
|
CHECK_FLAG(fNoConfirmRecycle);
|
|
CHECK_FLAG(fShowSysFiles); // No use
|
|
CHECK_FLAG(fShowCompColor);
|
|
CHECK_FLAG(fDoubleClickInWebView);
|
|
CHECK_FLAG(fDesktopHTML);
|
|
CHECK_FLAG(fWin95Classic);
|
|
CHECK_FLAG(fDontPrettyPath);
|
|
CHECK_FLAG(fShowAttribCol);
|
|
CHECK_FLAG(fMapNetDrvBtn);
|
|
CHECK_FLAG(fShowInfoTip);
|
|
CHECK_FLAG(fHideIcons);
|
|
#if NTDDI_VERSION >= 0x06000000 // for future use
|
|
CHECK_FLAG(fAutoCheckSelect);
|
|
CHECK_FLAG(fIconsOnly);
|
|
#endif
|
|
|
|
#if 1
|
|
#define DO_IT(x) x
|
|
#else
|
|
#define DO_IT(x) do { trace(#x ";\n"); x; } while (0)
|
|
#endif
|
|
|
|
DO_IT(memset(pss, 0, sizeof(*pss)));
|
|
DO_IT(pss->dwWin95Unused = 1);
|
|
ok(pb[4] == 0x01 || dump_pss(pss), "Unexpected pss ^\n");
|
|
|
|
DO_IT(memset(pss, 0, sizeof(*pss)));
|
|
DO_IT(pss->lParamSort = 1);
|
|
ok(pb[12] == 0x01 || dump_pss(pss), "Unexpected pss ^\n");
|
|
|
|
DO_IT(memset(pss, 0, sizeof(*pss)));
|
|
DO_IT(pss->iSortDirection = 0xDEADBEEF);
|
|
ok(*(UNALIGNED DWORD *)(pb + 16) == 0xDEADBEEF || dump_pss(pss), "Unexpected pss ^\n");
|
|
|
|
DO_IT(memset(pss, 0, sizeof(*pss)));
|
|
DO_IT(pss->version = 0xDEADBEEF);
|
|
ok(*(UNALIGNED DWORD *)(pb + 20) == 0xDEADBEEF || dump_pss(pss), "Unexpected pss ^\n");
|
|
|
|
DO_IT(memset(pss, 0, sizeof(*pss)));
|
|
DO_IT(pss->fSepProcess = TRUE);
|
|
ok(pb[28] == 0x01 || dump_pss(pss), "Unexpected pss ^\n");
|
|
}
|