[APITESTS] Add ShellStateTest
[reactos.git] / modules / rostests / apitests / shell32 / ShellState.cpp
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 }