1 /* 2 * PROJECT: ReactOS API tests 3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory 4 * PURPOSE: Test for SHELLSTATE 5 * PROGRAMMERS: Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com> 6 */ 7 #include "shelltest.h" 8 9 #define NDEBUG 10 #include <debug.h> 11 #include <stdio.h> 12 #include <shellutils.h> 13 #include <strsafe.h> 14 #include <shlwapi.h> 15 16 /* [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer] */ 17 /* The contents of RegValue ShellState. */ 18 typedef struct REGSHELLSTATE 19 { 20 DWORD dwSize; 21 SHELLSTATE ss; 22 } REGSHELLSTATE, *PREGSHELLSTATE; 23 24 static void dump(const char *name, const void *ptr, size_t siz) 25 { 26 char buf[256], sz[16]; 27 28 StringCbCopyA(buf, sizeof(buf), name); 29 StringCbCatA(buf, sizeof(buf), ": "); 30 31 const BYTE *pb = reinterpret_cast<const BYTE *>(ptr); 32 while (siz--) 33 { 34 StringCbPrintfA(sz, sizeof(sz), "%02X ", *pb++); 35 StringCbCatA(buf, sizeof(buf), sz); 36 } 37 38 trace("%s\n", buf); 39 } 40 41 static int read_key(REGSHELLSTATE *prss) 42 { 43 HKEY hKey; 44 LONG result; 45 DWORD cb; 46 static const LPCWSTR s_pszExplorer = 47 L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"; 48 49 memset(prss, 0, sizeof(*prss)); 50 51 result = RegOpenKeyExW(HKEY_CURRENT_USER, s_pszExplorer, 0, KEY_READ, &hKey); 52 ok(result == ERROR_SUCCESS, "result was %ld\n", result); 53 ok(hKey != NULL, "hKey was NULL\n"); 54 55 if (result != ERROR_SUCCESS || !hKey) 56 { 57 skip("RegOpenKeyEx failed: %ld\n", result); 58 return 1; 59 } 60 61 cb = sizeof(*prss); 62 result = RegQueryValueExW(hKey, L"ShellState", NULL, NULL, reinterpret_cast<LPBYTE>(prss), &cb); 63 RegCloseKey(hKey); 64 65 ok(result == ERROR_SUCCESS, "result was %ld\n", result); 66 if (result != ERROR_SUCCESS) 67 { 68 skip("RegQueryValueEx failed: %ld\n", result); 69 return 2; 70 } 71 72 return 0; 73 } 74 75 extern "C" HKEY WINAPI SHGetShellKey(DWORD flags, LPCWSTR sub_key, BOOL create); 76 77 static int read_advanced_key(SHELLSTATE* pss) 78 { 79 HKEY hKey; 80 DWORD dwValue, dwSize; 81 82 hKey = SHGetShellKey(1, L"Advanced", FALSE); 83 if (hKey == NULL) 84 { 85 return 0; 86 } 87 88 dwSize = sizeof(dwValue); 89 if (SHQueryValueExW(hKey, L"Hidden", NULL, NULL, &dwValue, &dwSize) == ERROR_SUCCESS) 90 { 91 pss->fShowAllObjects = (dwValue == 1); 92 pss->fShowSysFiles = (dwValue == 2); 93 } 94 95 dwSize = sizeof(dwValue); 96 if (SHQueryValueExW(hKey, L"HideFileExt", NULL, NULL, &dwValue, &dwSize) == ERROR_SUCCESS) 97 { 98 pss->fShowExtensions = (dwValue == 0); 99 } 100 101 dwSize = sizeof(dwValue); 102 if (SHQueryValueExW(hKey, L"DontPrettyPath", NULL, NULL, &dwValue, &dwSize) == ERROR_SUCCESS) 103 { 104 pss->fDontPrettyPath = (dwValue != 0); 105 } 106 107 dwSize = sizeof(dwValue); 108 if (SHQueryValueExW(hKey, L"MapNetDrvBtn", NULL, NULL, &dwValue, &dwSize) == ERROR_SUCCESS) 109 { 110 pss->fMapNetDrvBtn = (dwValue != 0); 111 } 112 113 dwSize = sizeof(dwValue); 114 if (SHQueryValueExW(hKey, L"ShowInfoTip", NULL, NULL, &dwValue, &dwSize) == ERROR_SUCCESS) 115 { 116 pss->fShowInfoTip = (dwValue != 0); 117 } 118 119 dwSize = sizeof(dwValue); 120 if (SHQueryValueExW(hKey, L"HideIcons", NULL, NULL, &dwValue, &dwSize) == ERROR_SUCCESS) 121 { 122 pss->fHideIcons = (dwValue != 0); 123 } 124 125 dwSize = sizeof(dwValue); 126 if (SHQueryValueExW(hKey, L"WebView", NULL, NULL, &dwValue, &dwSize) == ERROR_SUCCESS) 127 { 128 pss->fWebView = (dwValue != 0); 129 } 130 131 dwSize = sizeof(dwValue); 132 if (SHQueryValueExW(hKey, L"Filter", NULL, NULL, &dwValue, &dwSize) == ERROR_SUCCESS) 133 { 134 pss->fFilter = (dwValue != 0); 135 } 136 137 dwSize = sizeof(dwValue); 138 if (SHQueryValueExW(hKey, L"ShowSuperHidden", NULL, NULL, &dwValue, &dwSize) == ERROR_SUCCESS) 139 { 140 pss->fShowSuperHidden = (dwValue != 0); 141 } 142 143 dwSize = sizeof(dwValue); 144 if (SHQueryValueExW(hKey, L"NoNetCrawling", NULL, NULL, &dwValue, &dwSize) == ERROR_SUCCESS) 145 { 146 pss->fNoNetCrawling = (dwValue != 0); 147 } 148 149 RegCloseKey(hKey); 150 return 0; 151 } 152 153 static int dump_pss(SHELLSTATE *pss) 154 { 155 dump("SHELLSTATE", pss, sizeof(*pss)); 156 return 0; 157 } 158 159 START_TEST(ShellState) 160 { 161 OSVERSIONINFO osinfo; 162 REGSHELLSTATE rss; 163 SHELLSTATE ss, *pss; 164 SHELLFLAGSTATE FlagState; 165 LPBYTE pb; 166 int ret; 167 168 trace("GetVersion(): 0x%08lX", GetVersion()); 169 170 osinfo.dwOSVersionInfoSize = sizeof(osinfo); 171 GetVersionEx(&osinfo); 172 trace("osinfo.dwMajorVersion: 0x%08lX\n", osinfo.dwMajorVersion); 173 trace("osinfo.dwMinorVersion: 0x%08lX\n", osinfo.dwMinorVersion); 174 trace("osinfo.dwBuildNumber: 0x%08lX\n", osinfo.dwBuildNumber); 175 trace("osinfo.dwPlatformId: 0x%08lX\n", osinfo.dwPlatformId); 176 177 trace("WINVER: 0x%04X\n", WINVER); 178 trace("_WIN32_WINNT: 0x%04X\n", _WIN32_WINNT); 179 trace("_WIN32_IE: 0x%04X\n", _WIN32_IE); 180 trace("NTDDI_VERSION: 0x%08X\n", NTDDI_VERSION); 181 182 #ifdef _MSC_VER 183 trace("_MSC_VER: 0x%08X\n", int(_MSC_VER)); 184 #elif defined(__MINGW32__) 185 trace("__MINGW32__: 0x%08X\n", int(__MINGW32__)); 186 #elif defined(__clang__) 187 trace("__clang__: 0x%08X\n", int(__clang__)); 188 #else 189 #error Unknown compiler. 190 #endif 191 192 ok(sizeof(REGSHELLSTATE) >= 0x24, "sizeof(REGSHELLSTATE) was %d\n", (int)sizeof(REGSHELLSTATE)); 193 trace("sizeof(SHELLSTATE): %d\n", (int)sizeof(SHELLSTATE)); 194 trace("__alignof(SHELLSTATE): %d\n", (int)__alignof(SHELLSTATE)); 195 trace("sizeof(SHELLFLAGSTATE): %d\n", (int)sizeof(SHELLFLAGSTATE)); 196 trace("sizeof(CABINETSTATE): %d\n", (int)sizeof(CABINETSTATE)); 197 198 pss = &rss.ss; 199 pb = reinterpret_cast<LPBYTE>(pss); 200 201 ret = read_key(&rss); 202 if (ret) 203 { 204 return; 205 } 206 207 dump_pss(pss); 208 ok(rss.dwSize >= 0x24, "rss.dwSize was %ld (0x%lX).\n", rss.dwSize, rss.dwSize); 209 210 read_advanced_key(&rss.ss); 211 212 #define DUMP_LONG(x) trace(#x ": 0x%08X\n", int(x)); 213 #define DUMP_BOOL(x) trace(#x ": %d\n", !!int(x)); 214 DUMP_BOOL(pss->fShowAllObjects); 215 DUMP_BOOL(pss->fShowExtensions); 216 DUMP_BOOL(pss->fNoConfirmRecycle); 217 DUMP_BOOL(pss->fShowSysFiles); 218 DUMP_BOOL(pss->fShowCompColor); 219 DUMP_BOOL(pss->fDoubleClickInWebView); 220 DUMP_BOOL(pss->fDesktopHTML); 221 DUMP_BOOL(pss->fWin95Classic); 222 DUMP_BOOL(pss->fDontPrettyPath); 223 DUMP_BOOL(pss->fShowAttribCol); 224 DUMP_BOOL(pss->fMapNetDrvBtn); 225 DUMP_BOOL(pss->fShowInfoTip); 226 DUMP_BOOL(pss->fHideIcons); 227 DUMP_BOOL(pss->fWebView); 228 DUMP_BOOL(pss->fFilter); 229 DUMP_BOOL(pss->fShowSuperHidden); 230 DUMP_BOOL(pss->fNoNetCrawling); 231 DUMP_LONG(pss->lParamSort); 232 DUMP_LONG(pss->iSortDirection); 233 DUMP_LONG(pss->version); 234 DUMP_LONG(pss->lParamSort); 235 DUMP_LONG(pss->iSortDirection); 236 DUMP_LONG(pss->version); 237 DUMP_BOOL(pss->fSepProcess); 238 DUMP_BOOL(pss->fStartPanelOn); 239 DUMP_BOOL(pss->fShowStartPage); 240 #if NTDDI_VERSION >= 0x06000000 // for future use 241 DUMP_BOOL(pss->fIconsOnly); 242 DUMP_BOOL(pss->fShowTypeOverlay); 243 DUMP_BOOL(pss->fShowStatusBar); 244 #endif 245 246 #define SSF_MASK \ 247 (SSF_SHOWALLOBJECTS | SSF_SHOWEXTENSIONS | SSF_NOCONFIRMRECYCLE | \ 248 SSF_SHOWCOMPCOLOR | SSF_DOUBLECLICKINWEBVIEW | SSF_DESKTOPHTML | \ 249 SSF_WIN95CLASSIC | SSF_DONTPRETTYPATH | SSF_SHOWATTRIBCOL | \ 250 SSF_MAPNETDRVBUTTON | SSF_SHOWINFOTIP | SSF_HIDEICONS) 251 // For future: 252 // SSF_AUTOCHECKSELECT, SSF_ICONSONLY, SSF_SHOWTYPEOVERLAY, SSF_SHOWSTATUSBAR 253 254 /* Get the settings */ 255 memset(&ss, 0, sizeof(ss)); 256 SHGetSetSettings(&ss, SSF_MASK, FALSE); 257 #define CHECK_REG_FLAG(x) ok(pss->x == ss.x, "ss.%s expected %d, was %d\n", #x, (int)pss->x, (int)ss.x) 258 CHECK_REG_FLAG(fShowAllObjects); 259 CHECK_REG_FLAG(fShowExtensions); 260 CHECK_REG_FLAG(fNoConfirmRecycle); 261 CHECK_REG_FLAG(fShowSysFiles); // No use 262 CHECK_REG_FLAG(fShowCompColor); 263 CHECK_REG_FLAG(fDoubleClickInWebView); 264 CHECK_REG_FLAG(fDesktopHTML); 265 CHECK_REG_FLAG(fWin95Classic); 266 CHECK_REG_FLAG(fDontPrettyPath); 267 CHECK_REG_FLAG(fShowAttribCol); 268 CHECK_REG_FLAG(fMapNetDrvBtn); 269 CHECK_REG_FLAG(fShowInfoTip); 270 CHECK_REG_FLAG(fHideIcons); 271 #if NTDDI_VERSION >= 0x06000000 // for future use 272 CHECK_REG_FLAG(fAutoCheckSelect); 273 CHECK_REG_FLAG(fIconsOnly); 274 #endif 275 276 /* Get the flag settings */ 277 memset(&FlagState, 0, sizeof(FlagState)); 278 SHGetSettings(&FlagState, SSF_MASK); 279 #define CHECK_FLAG(x) ok(ss.x == FlagState.x, "FlagState.%s expected %d, was %d\n", #x, (int)ss.x, (int)FlagState.x) 280 CHECK_FLAG(fShowAllObjects); 281 CHECK_FLAG(fShowExtensions); 282 CHECK_FLAG(fNoConfirmRecycle); 283 CHECK_FLAG(fShowSysFiles); // No use 284 CHECK_FLAG(fShowCompColor); 285 CHECK_FLAG(fDoubleClickInWebView); 286 CHECK_FLAG(fDesktopHTML); 287 CHECK_FLAG(fWin95Classic); 288 CHECK_FLAG(fDontPrettyPath); 289 CHECK_FLAG(fShowAttribCol); 290 CHECK_FLAG(fMapNetDrvBtn); 291 CHECK_FLAG(fShowInfoTip); 292 CHECK_FLAG(fHideIcons); 293 #if NTDDI_VERSION >= 0x06000000 // for future use 294 CHECK_FLAG(fAutoCheckSelect); 295 CHECK_FLAG(fIconsOnly); 296 #endif 297 298 #if 1 299 #define DO_IT(x) x 300 #else 301 #define DO_IT(x) do { trace(#x ";\n"); x; } while (0) 302 #endif 303 304 DO_IT(memset(pss, 0, sizeof(*pss))); 305 DO_IT(pss->dwWin95Unused = 1); 306 ok(pb[4] == 0x01 || dump_pss(pss), "Unexpected pss ^\n"); 307 308 DO_IT(memset(pss, 0, sizeof(*pss))); 309 DO_IT(pss->lParamSort = 1); 310 ok(pb[12] == 0x01 || dump_pss(pss), "Unexpected pss ^\n"); 311 312 DO_IT(memset(pss, 0, sizeof(*pss))); 313 DO_IT(pss->iSortDirection = 0xDEADBEEF); 314 ok(*(UNALIGNED DWORD *)(pb + 16) == 0xDEADBEEF || dump_pss(pss), "Unexpected pss ^\n"); 315 316 DO_IT(memset(pss, 0, sizeof(*pss))); 317 DO_IT(pss->version = 0xDEADBEEF); 318 ok(*(UNALIGNED DWORD *)(pb + 20) == 0xDEADBEEF || dump_pss(pss), "Unexpected pss ^\n"); 319 320 DO_IT(memset(pss, 0, sizeof(*pss))); 321 DO_IT(pss->fSepProcess = TRUE); 322 ok(pb[28] == 0x01 || dump_pss(pss), "Unexpected pss ^\n"); 323 } 324