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