Move and reshuffle reactos/regtetsts into rostests. 1/2
[reactos.git] / rostests / winetests / comctl32 / mru.c
1 /*
2 * comctl32 MRU unit tests
3 *
4 * Copyright (C) 2004 Jon Griffiths <jon_p_griffiths@yahoo.com>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20 #include <stdarg.h>
21
22 #include "windef.h"
23 #include "winbase.h"
24 #include "wingdi.h"
25 #include "winuser.h"
26 #include "winnls.h"
27 #include "winreg.h"
28 #include "commctrl.h"
29 #include "shlwapi.h"
30
31 #include "wine/test.h"
32
33 /* Keys for testing MRU functions */
34 #define REG_TEST_BASEKEYA "Software\\Wine"
35 #define REG_TEST_BASESUBKEYA "Test"
36 #define REG_TEST_KEYA REG_TEST_BASEKEYA "\\" REG_TEST_BASESUBKEYA
37 #define REG_TEST_SUBKEYA "MRUTest"
38 #define REG_TEST_FULLKEY REG_TEST_KEYA "\\" REG_TEST_SUBKEYA
39
40 /* Undocumented MRU structures & functions */
41 typedef struct tagCREATEMRULISTA
42 {
43 DWORD cbSize;
44 DWORD nMaxItems;
45 DWORD dwFlags;
46 HKEY hKey;
47 LPCSTR lpszSubKey;
48 PROC lpfnCompare;
49 } CREATEMRULISTA, *LPCREATEMRULISTA;
50
51 #define MRUF_STRING_LIST 0
52 #define MRUF_BINARY_LIST 1
53 #define MRUF_DELAYED_SAVE 2
54
55 #define LIST_SIZE 3 /* Max entries for each mru */
56
57 static CREATEMRULISTA mruA =
58 {
59 sizeof(CREATEMRULISTA),
60 LIST_SIZE,
61 0,
62 NULL,
63 REG_TEST_SUBKEYA,
64 NULL
65 };
66
67 static HMODULE hComctl32;
68 static HANDLE (WINAPI *pCreateMRUListA)(LPCREATEMRULISTA);
69 static void (WINAPI *pFreeMRUList)(HANDLE);
70 static INT (WINAPI *pAddMRUStringA)(HANDLE,LPCSTR);
71 /*
72 static INT (WINAPI *pFindMRUStringA)(HANDLE,LPCSTR,LPINT);
73 static INT (WINAPI *pEnumMRUList)(HANDLE,INT,LPVOID,DWORD);
74 */
75
76 static BOOL create_reg_entries(void)
77 {
78 HKEY hKey = NULL;
79
80 ok(!RegCreateKeyA(HKEY_CURRENT_USER, REG_TEST_FULLKEY, &hKey),
81 "Couldn't create test key \"%s\"\n", REG_TEST_KEYA);
82 if (!hKey) return FALSE;
83 RegCloseKey(hKey);
84 return TRUE;
85 }
86
87 static void delete_reg_entries(void)
88 {
89 HKEY hKey;
90
91 if (RegOpenKeyExA(HKEY_CURRENT_USER, REG_TEST_BASEKEYA, 0, KEY_ALL_ACCESS,
92 &hKey))
93 return;
94 SHDeleteKeyA(hKey, REG_TEST_BASESUBKEYA);
95 RegCloseKey(hKey);
96 }
97
98 static void check_reg_entries(const char *mrulist, const char**items)
99 {
100 char buff[128];
101 HKEY hKey = NULL;
102 DWORD type, size, ret;
103 unsigned int i;
104
105 ok(!RegOpenKeyA(HKEY_CURRENT_USER, REG_TEST_FULLKEY, &hKey),
106 "Couldn't open test key \"%s\"\n", REG_TEST_FULLKEY);
107 if (!hKey) return;
108
109 type = REG_SZ;
110 size = sizeof(buff);
111 buff[0] = '\0';
112 ret = RegQueryValueExA(hKey, "MRUList", NULL, &type, (LPBYTE)buff, &size);
113
114 ok(!ret && buff[0], "Checking MRU: got %ld from RegQueryValueExW\n", ret);
115 if(ret || !buff[0]) return;
116
117 ok(strcmp(buff, mrulist) == 0, "Checking MRU: Expected list %s, got %s\n",
118 mrulist, buff);
119 if(strcmp(buff, mrulist)) return;
120
121 for (i = 0; i < strlen(mrulist); i++)
122 {
123 char name[2];
124 name[0] = mrulist[i];
125 name[1] = '\0';
126 type = REG_SZ;
127 size = sizeof(buff);
128 buff[0] = '\0';
129 ret = RegQueryValueExA(hKey, name, NULL, &type, (LPBYTE)buff, &size);
130 ok(!ret && buff[0],
131 "Checking MRU item %d ('%c'): got %ld from RegQueryValueExW\n",
132 i, mrulist[i], ret);
133 if(ret || !buff[0]) return;
134 ok(!strcmp(buff, items[mrulist[i]-'a']),
135 "Checking MRU item %d ('%c'): expected \"%s\", got \"%s\"\n",
136 i, mrulist[i], buff, items[mrulist[i] - 'a']);
137 }
138 }
139
140 static INT CALLBACK cmp_mru_strA(LPCVOID data1, LPCVOID data2)
141 {
142 return lstrcmpiA(data1, data2);
143 }
144
145 static HANDLE create_mruA(HKEY hKey, DWORD flags, PROC cmp)
146 {
147 mruA.dwFlags = flags;
148 mruA.lpfnCompare = cmp;
149 mruA.hKey = hKey;
150
151 SetLastError(0);
152 return pCreateMRUListA(&mruA);
153 }
154
155 static void test_MRUListA(void)
156 {
157 const char *checks[LIST_SIZE+1];
158 HANDLE hMRU;
159 HKEY hKey;
160 INT iRet;
161
162 pCreateMRUListA = (void*)GetProcAddress(hComctl32,(LPCSTR)151);
163 pFreeMRUList = (void*)GetProcAddress(hComctl32,(LPCSTR)152);
164 pAddMRUStringA = (void*)GetProcAddress(hComctl32,(LPCSTR)153);
165 if (!pCreateMRUListA || !pFreeMRUList || !pAddMRUStringA)
166 return;
167
168 #if 0 /* Create (NULL) - crashes native */
169 hMRU = pCreateMRUListA(NULL);
170 #endif
171
172 /* Create (size too small) */
173 mruA.cbSize = sizeof(mruA) - 2;
174 hMRU = create_mruA(NULL, MRUF_STRING_LIST, cmp_mru_strA);
175 ok (!hMRU && !GetLastError(),
176 "CreateMRUListA(too small) expected NULL,0 got %p,%ld\n",
177 hMRU, GetLastError());
178 mruA.cbSize = sizeof(mruA);
179
180 /* Create (size too big) */
181 mruA.cbSize = sizeof(mruA) + 2;
182 hMRU = create_mruA(NULL, MRUF_STRING_LIST, cmp_mru_strA);
183 ok (!hMRU && !GetLastError(),
184 "CreateMRUListA(too big) expected NULL,0 got %p,%ld\n",
185 hMRU, GetLastError());
186 mruA.cbSize = sizeof(mruA);
187
188 /* Create (NULL hKey) */
189 hMRU = create_mruA(NULL, MRUF_STRING_LIST, cmp_mru_strA);
190 ok (!hMRU && !GetLastError(),
191 "CreateMRUListA(NULL key) expected NULL,0 got %p,%ld\n",
192 hMRU, GetLastError());
193
194 /* Create (NULL name) */
195 mruA.lpszSubKey = NULL;
196 hMRU = create_mruA(NULL, MRUF_STRING_LIST, cmp_mru_strA);
197 ok (!hMRU && !GetLastError(),
198 "CreateMRUListA(NULL name) expected NULL,0 got %p,%ld\n",
199 hMRU, GetLastError());
200 mruA.lpszSubKey = REG_TEST_SUBKEYA;
201
202 /* Create a string MRU */
203 ok(!RegCreateKeyA(HKEY_CURRENT_USER, REG_TEST_KEYA, &hKey),
204 "Couldn't create test key \"%s\"\n", REG_TEST_KEYA);
205 if (!hKey)
206 return;
207 hMRU = create_mruA(hKey, MRUF_STRING_LIST, cmp_mru_strA);
208 ok(hMRU && !GetLastError(),
209 "CreateMRUListA(string) expected non-NULL,0 got %p,%ld\n",
210 hMRU, GetLastError());
211
212 if (hMRU)
213 {
214 checks[0] = "Test 1";
215 checks[1] = "Test 2";
216 checks[2] = "Test 3";
217 checks[3] = "Test 4";
218
219 /* Add (NULL list) */
220 SetLastError(0);
221 iRet = pAddMRUStringA(NULL, checks[0]);
222 ok(iRet == -1 && !GetLastError(),
223 "AddMRUStringA(NULL list) expected -1,0 got %d,%ld\n",
224 iRet, GetLastError());
225
226 /* Add (NULL string) */
227 #if 0
228 /* Some native versions crash when passed NULL or fail to SetLastError() */
229 SetLastError(0);
230 iRet = pAddMRUStringA(hMRU, NULL);
231 ok(iRet == 0 && GetLastError() == ERROR_INVALID_PARAMETER,
232 "AddMRUStringA(NULL str) expected 0,ERROR_INVALID_PARAMETER got %d,%ld\n",
233 iRet, GetLastError());
234 #endif
235
236 /* Add 3 strings. Check the registry is correct after each add */
237 SetLastError(0);
238 iRet = pAddMRUStringA(hMRU, checks[0]);
239 ok(iRet == 0 && !GetLastError(),
240 "AddMRUStringA(1) expected 0,0 got %d,%ld\n",
241 iRet, GetLastError());
242 check_reg_entries("a", checks);
243
244 SetLastError(0);
245 iRet = pAddMRUStringA(hMRU, checks[1]);
246 ok(iRet == 1 && !GetLastError(),
247 "AddMRUStringA(2) expected 1,0 got %d,%ld\n",
248 iRet, GetLastError());
249 check_reg_entries("ba", checks);
250
251 SetLastError(0);
252 iRet = pAddMRUStringA(hMRU, checks[2]);
253 ok(iRet == 2 && !GetLastError(),
254 "AddMRUStringA(2) expected 2,0 got %d,%ld\n",
255 iRet, GetLastError());
256 check_reg_entries("cba", checks);
257
258 /* Add a duplicate of the 2nd string - it should move to the front,
259 * but keep the same index in the registry.
260 */
261 SetLastError(0);
262 iRet = pAddMRUStringA(hMRU, checks[1]);
263 ok(iRet == 1 && !GetLastError(),
264 "AddMRUStringA(re-add 1) expected 1,0 got %d,%ld\n",
265 iRet, GetLastError());
266 check_reg_entries("bca", checks);
267
268 /* Add a new string - replaces the oldest string + moves to the front */
269 SetLastError(0);
270 iRet = pAddMRUStringA(hMRU, checks[3]);
271 ok(iRet == 0 && !GetLastError(),
272 "AddMRUStringA(add new) expected 0,0 got %d,%ld\n",
273 iRet, GetLastError());
274 checks[0] = checks[3];
275 check_reg_entries("abc", checks);
276
277 /* Finished with this MRU */
278 pFreeMRUList(hMRU);
279 }
280
281 /* Free (NULL list) - Doesn't crash */
282 pFreeMRUList(NULL);
283 }
284
285 START_TEST(mru)
286 {
287 hComctl32 = GetModuleHandleA("comctl32.dll");
288 if (!hComctl32)
289 return;
290
291 delete_reg_entries();
292 if (!create_reg_entries())
293 return;
294
295 test_MRUListA();
296
297 delete_reg_entries();
298 }