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 <shellutils.h> 12 #include <strsafe.h> 13 14 /* [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer] */ 15 /* The contents of RegValue ShellState. */ 16 typedef struct REGSHELLSTATE 17 { 18 DWORD dwSize; 19 SHELLSTATE ss; 20 } REGSHELLSTATE, *PREGSHELLSTATE; 21 22 static void dump(const char *name, const void *ptr, size_t siz) 23 { 24 char buf[256], sz[16]; 25 26 StringCbCopyA(buf, sizeof(buf), name); 27 StringCbCatA(buf, sizeof(buf), ": "); 28 29 const BYTE *pb = reinterpret_cast<const BYTE *>(ptr); 30 while (siz--) 31 { 32 StringCbPrintfA(sz, sizeof(sz), "%02X ", *pb++); 33 StringCbCatA(buf, sizeof(buf), sz); 34 } 35 36 trace("%s\n", buf); 37 } 38 39 static int read_key(REGSHELLSTATE *prss) 40 { 41 HKEY hKey; 42 LONG result; 43 DWORD cb; 44 static const LPCWSTR s_pszExplorer = 45 L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"; 46 47 memset(prss, 0, sizeof(*prss)); 48 49 result = RegOpenKeyExW(HKEY_CURRENT_USER, s_pszExplorer, 0, KEY_READ, &hKey); 50 ok(result == ERROR_SUCCESS, "result was %ld\n", result); 51 ok(hKey != NULL, "hKey was NULL\n"); 52 53 if (result != ERROR_SUCCESS || !hKey) 54 { 55 skip("RegOpenKeyEx failed: %ld\n", result); 56 return 1; 57 } 58 59 cb = sizeof(*prss); 60 result = RegQueryValueExW(hKey, L"ShellState", NULL, NULL, reinterpret_cast<LPBYTE>(prss), &cb); 61 RegCloseKey(hKey); 62 63 ok(result == ERROR_SUCCESS, "result was %ld\n", result); 64 if (result != ERROR_SUCCESS) 65 { 66 skip("RegQueryValueEx failed: %ld\n", result); 67 return 2; 68 } 69 70 return 0; 71 } 72 73 static int dump_pss(SHELLSTATE *pss) 74 { 75 dump("SHELLSTATE", pss, sizeof(*pss)); 76 return 0; 77 } 78 79 START_TEST(ShellState) 80 { 81 OSVERSIONINFO osinfo; 82 REGSHELLSTATE rss; 83 SHELLSTATE *pss; 84 SHELLFLAGSTATE FlagState; 85 LPBYTE pb; 86 int ret; 87 88 trace("GetVersion(): 0x%08lX", GetVersion()); 89 90 osinfo.dwOSVersionInfoSize = sizeof(osinfo); 91 GetVersionEx(&osinfo); 92 trace("osinfo.dwMajorVersion: 0x%08lX\n", osinfo.dwMajorVersion); 93 trace("osinfo.dwMinorVersion: 0x%08lX\n", osinfo.dwMinorVersion); 94 trace("osinfo.dwBuildNumber: 0x%08lX\n", osinfo.dwBuildNumber); 95 trace("osinfo.dwPlatformId: 0x%08lX\n", osinfo.dwPlatformId); 96 97 trace("WINVER: 0x%04X\n", WINVER); 98 trace("_WIN32_WINNT: 0x%04X\n", _WIN32_WINNT); 99 trace("_WIN32_IE: 0x%04X\n", _WIN32_IE); 100 trace("NTDDI_VERSION: 0x%08X\n", NTDDI_VERSION); 101 102 #ifdef _MSC_VER 103 trace("_MSC_VER: 0x%08X\n", int(_MSC_VER)); 104 #elif defined(__MINGW32__) 105 trace("__MINGW32__: 0x%08X\n", int(__MINGW32__)); 106 #elif defined(__clang__) 107 trace("__clang__: 0x%08X\n", int(__clang__)); 108 #else 109 #error Unknown compiler. 110 #endif 111 112 ok(sizeof(REGSHELLSTATE) >= 0x24, "sizeof(REGSHELLSTATE) was %d\n", (int)sizeof(REGSHELLSTATE)); 113 trace("sizeof(SHELLSTATE): %d\n", (int)sizeof(SHELLSTATE)); 114 trace("__alignof(SHELLSTATE): %d\n", (int)__alignof(SHELLSTATE)); 115 trace("sizeof(SHELLFLAGSTATE): %d\n", (int)sizeof(SHELLFLAGSTATE)); 116 trace("sizeof(CABINETSTATE): %d\n", (int)sizeof(CABINETSTATE)); 117 118 pss = &rss.ss; 119 pb = reinterpret_cast<LPBYTE>(pss); 120 121 ret = read_key(&rss); 122 if (ret) 123 { 124 return; 125 } 126 127 dump_pss(pss); 128 ok(rss.dwSize >= 0x24, "rss.dwSize was %ld (0x%lX).\n", rss.dwSize, rss.dwSize); 129 130 #define DUMP_LONG(x) trace(#x ": 0x%08X\n", int(x)); 131 #define DUMP_BOOL(x) trace(#x ": %d\n", !!int(x)); 132 DUMP_BOOL(pss->fShowAllObjects); 133 DUMP_BOOL(pss->fShowExtensions); 134 DUMP_BOOL(pss->fNoConfirmRecycle); 135 DUMP_BOOL(pss->fShowSysFiles); 136 DUMP_BOOL(pss->fShowCompColor); 137 DUMP_BOOL(pss->fDoubleClickInWebView); 138 DUMP_BOOL(pss->fDesktopHTML); 139 DUMP_BOOL(pss->fWin95Classic); 140 DUMP_BOOL(pss->fDontPrettyPath); 141 DUMP_BOOL(pss->fShowAttribCol); 142 DUMP_BOOL(pss->fMapNetDrvBtn); 143 DUMP_BOOL(pss->fShowInfoTip); 144 DUMP_BOOL(pss->fHideIcons); 145 DUMP_BOOL(pss->fWebView); 146 DUMP_BOOL(pss->fFilter); 147 DUMP_BOOL(pss->fShowSuperHidden); 148 DUMP_BOOL(pss->fNoNetCrawling); 149 DUMP_LONG(pss->lParamSort); 150 DUMP_LONG(pss->iSortDirection); 151 DUMP_LONG(pss->version); 152 DUMP_LONG(pss->lParamSort); 153 DUMP_LONG(pss->iSortDirection); 154 DUMP_LONG(pss->version); 155 DUMP_BOOL(pss->fSepProcess); 156 DUMP_BOOL(pss->fStartPanelOn); 157 DUMP_BOOL(pss->fShowStartPage); 158 #if NTDDI_VERSION >= 0x06000000 // for future use 159 DUMP_BOOL(pss->fIconsOnly); 160 DUMP_BOOL(pss->fShowTypeOverlay); 161 DUMP_BOOL(pss->fShowStatusBar); 162 #endif 163 164 #define SSF_MASK \ 165 (SSF_SHOWALLOBJECTS | SSF_SHOWEXTENSIONS | SSF_NOCONFIRMRECYCLE | \ 166 SSF_SHOWCOMPCOLOR | SSF_DOUBLECLICKINWEBVIEW | SSF_DESKTOPHTML | \ 167 SSF_WIN95CLASSIC | SSF_DONTPRETTYPATH | SSF_SHOWATTRIBCOL | \ 168 SSF_MAPNETDRVBUTTON | SSF_SHOWINFOTIP | SSF_HIDEICONS) 169 // For future: 170 // SSF_AUTOCHECKSELECT, SSF_ICONSONLY, SSF_SHOWTYPEOVERLAY, SSF_SHOWSTATUSBAR 171 172 memset(&FlagState, 0, sizeof(FlagState)); 173 SHGetSettings(&FlagState, SSF_MASK); 174 175 #define CHECK_FLAG(x) ok(pss->x == FlagState.x, "FlagState.%s expected %d, was %d\n", #x, (int)pss->x, (int)FlagState.x) 176 CHECK_FLAG(fShowAllObjects); 177 CHECK_FLAG(fShowExtensions); 178 CHECK_FLAG(fNoConfirmRecycle); 179 //CHECK_FLAG(fShowSysFiles); // No use 180 CHECK_FLAG(fShowCompColor); 181 CHECK_FLAG(fDoubleClickInWebView); 182 CHECK_FLAG(fDesktopHTML); 183 CHECK_FLAG(fWin95Classic); 184 CHECK_FLAG(fDontPrettyPath); 185 CHECK_FLAG(fShowAttribCol); 186 CHECK_FLAG(fMapNetDrvBtn); 187 CHECK_FLAG(fShowInfoTip); 188 CHECK_FLAG(fHideIcons); 189 #if NTDDI_VERSION >= 0x06000000 // for future use 190 CHECK_FLAG(fAutoCheckSelect); 191 CHECK_FLAG(fIconsOnly); 192 #endif 193 194 #if 1 195 #define DO_IT(x) x 196 #else 197 #define DO_IT(x) do { trace(#x ";\n"); x; } while (0) 198 #endif 199 200 DO_IT(memset(pss, 0, sizeof(*pss))); 201 DO_IT(pss->dwWin95Unused = 1); 202 ok(pb[4] == 0x01 || dump_pss(pss), "Unexpected pss ^\n"); 203 204 DO_IT(memset(pss, 0, sizeof(*pss))); 205 DO_IT(pss->lParamSort = 1); 206 ok(pb[12] == 0x01 || dump_pss(pss), "Unexpected pss ^\n"); 207 208 DO_IT(memset(pss, 0, sizeof(*pss))); 209 DO_IT(pss->iSortDirection = 0xDEADBEEF); 210 ok(*(UNALIGNED DWORD *)(pb + 16) == 0xDEADBEEF || dump_pss(pss), "Unexpected pss ^\n"); 211 212 DO_IT(memset(pss, 0, sizeof(*pss))); 213 DO_IT(pss->version = 0xDEADBEEF); 214 ok(*(UNALIGNED DWORD *)(pb + 20) == 0xDEADBEEF || dump_pss(pss), "Unexpected pss ^\n"); 215 216 DO_IT(memset(pss, 0, sizeof(*pss))); 217 DO_IT(pss->fSepProcess = TRUE); 218 ok(pb[28] == 0x01 || dump_pss(pss), "Unexpected pss ^\n"); 219 } 220