ReactOS 0.4.15-dev-8109-gd7be748
mru.c
Go to the documentation of this file.
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/heap.h"
32#include "wine/test.h"
33
34/* Keys for testing MRU functions */
35#define REG_TEST_BASEKEYA "Software\\Wine"
36#define REG_TEST_BASESUBKEYA "Test"
37#define REG_TEST_KEYA REG_TEST_BASEKEYA "\\" REG_TEST_BASESUBKEYA
38#define REG_TEST_SUBKEYA "MRUTest"
39#define REG_TEST_FULLKEY REG_TEST_KEYA "\\" REG_TEST_SUBKEYA
40
41/* Undocumented MRU functions */
42typedef struct tagMRUINFOA
43{
45 UINT uMax;
47 HKEY hKey;
49 int (CALLBACK *lpfnCompare)(LPCSTR, LPCSTR);
51
52typedef struct tagMRUINFOW
53{
55 UINT uMax;
57 HKEY hKey;
59 int (CALLBACK *lpfnCompare)(LPCWSTR, LPCWSTR);
61
62#define MRU_STRING 0 /* this one's invented */
63#define MRU_BINARY 1
64#define MRU_CACHEWRITE 2
65
66#define LIST_SIZE 3 /* Max entries for each mru */
67
69static HANDLE (WINAPI *pCreateMRUListA)(MRUINFOA*);
70static void (WINAPI *pFreeMRUList)(HANDLE);
71static INT (WINAPI *pAddMRUStringA)(HANDLE,LPCSTR);
72static INT (WINAPI *pEnumMRUListA)(HANDLE,INT,LPVOID,DWORD);
73static INT (WINAPI *pEnumMRUListW)(HANDLE,INT,LPVOID,DWORD);
74static HANDLE (WINAPI *pCreateMRUListLazyA)(MRUINFOA*, DWORD, DWORD, DWORD);
75static HANDLE (WINAPI *pCreateMRUListLazyW)(MRUINFOW*, DWORD, DWORD, DWORD);
76static INT (WINAPI *pFindMRUData)(HANDLE, LPCVOID, DWORD, LPINT);
77static INT (WINAPI *pAddMRUData)(HANDLE, LPCVOID, DWORD);
78static HANDLE (WINAPI *pCreateMRUListW)(MRUINFOW*);
79
80static void init_functions(void)
81{
82 hComctl32 = LoadLibraryA("comctl32.dll");
83
84#define X2(f, ord) p##f = (void*)GetProcAddress(hComctl32, (const char *)ord);
85 X2(CreateMRUListA, 151);
86 X2(FreeMRUList, 152);
87 X2(AddMRUStringA, 153);
88 X2(EnumMRUListA, 154);
90 X2(AddMRUData, 167);
91 X2(FindMRUData, 169);
92 X2(CreateMRUListW, 400);
93 X2(EnumMRUListW, 403);
95#undef X2
96}
97
98/* Based on RegDeleteTreeW from dlls/advapi32/registry.c */
100{
101 LONG ret;
102 DWORD dwMaxSubkeyLen, dwMaxValueLen;
103 DWORD dwMaxLen, dwSize;
104 CHAR szNameBuf[MAX_PATH], *lpszName = szNameBuf;
105 HKEY hSubKey = hKey;
106
107 if(lpszSubKey)
108 {
109 ret = RegOpenKeyExA(hKey, lpszSubKey, 0, KEY_READ, &hSubKey);
110 if (ret) return ret;
111 }
112
113 /* Get highest length for keys, values */
114 ret = RegQueryInfoKeyA(hSubKey, NULL, NULL, NULL, NULL,
115 &dwMaxSubkeyLen, NULL, NULL, &dwMaxValueLen, NULL, NULL, NULL);
116 if (ret) goto cleanup;
117
118 dwMaxSubkeyLen++;
119 dwMaxValueLen++;
120 dwMaxLen = max(dwMaxSubkeyLen, dwMaxValueLen);
121 if (dwMaxLen > ARRAY_SIZE(szNameBuf))
122 {
123 /* Name too big: alloc a buffer for it */
124 if (!(lpszName = heap_alloc(dwMaxLen * sizeof(CHAR))))
125 {
127 goto cleanup;
128 }
129 }
130
131
132 /* Recursively delete all the subkeys */
133 while (TRUE)
134 {
135 dwSize = dwMaxLen;
136 if (RegEnumKeyExA(hSubKey, 0, lpszName, &dwSize, NULL,
137 NULL, NULL, NULL)) break;
138
139 ret = mru_RegDeleteTreeA(hSubKey, lpszName);
140 if (ret) goto cleanup;
141 }
142
143 if (lpszSubKey)
144 ret = RegDeleteKeyA(hKey, lpszSubKey);
145 else
146 while (TRUE)
147 {
148 dwSize = dwMaxLen;
149 if (RegEnumValueA(hKey, 0, lpszName, &dwSize,
150 NULL, NULL, NULL, NULL)) break;
151
152 ret = RegDeleteValueA(hKey, lpszName);
153 if (ret) goto cleanup;
154 }
155
156cleanup:
157 /* Free buffer if allocated */
158 if (lpszName != szNameBuf)
159 heap_free(lpszName);
160 if(lpszSubKey)
161 RegCloseKey(hSubKey);
162 return ret;
163}
164
166{
167 HKEY hKey = NULL;
168
170 "Couldn't create test key \"%s\"\n", REG_TEST_KEYA);
171 if (!hKey) return FALSE;
173 return TRUE;
174}
175
176static void delete_reg_entries(void)
177{
178 HKEY hKey;
179
181 &hKey))
182 return;
185}
186
187static void check_reg_entries(const char *mrulist, const char**items)
188{
189 char buff[128];
190 HKEY hKey = NULL;
191 DWORD type, size, ret;
192 unsigned int i;
193
195 "Couldn't open test key \"%s\"\n", REG_TEST_FULLKEY);
196 if (!hKey) return;
197
198 type = REG_SZ;
199 size = sizeof(buff);
200 buff[0] = '\0';
201 ret = RegQueryValueExA(hKey, "MRUList", NULL, &type, (LPBYTE)buff, &size);
202
203 ok(!ret && buff[0], "Checking MRU: got %d from RegQueryValueExW\n", ret);
204 if(ret || !buff[0]) return;
205
206 ok(strcmp(buff, mrulist) == 0, "Checking MRU: Expected list %s, got %s\n",
207 mrulist, buff);
208 if(strcmp(buff, mrulist)) return;
209
210 for (i = 0; i < strlen(mrulist); i++)
211 {
212 char name[2];
213 name[0] = mrulist[i];
214 name[1] = '\0';
215 type = REG_SZ;
216 size = sizeof(buff);
217 buff[0] = '\0';
219 ok(!ret && buff[0],
220 "Checking MRU item %d ('%c'): got %d from RegQueryValueExW\n",
221 i, mrulist[i], ret);
222 if(ret || !buff[0]) return;
223 ok(!strcmp(buff, items[mrulist[i]-'a']),
224 "Checking MRU item %d ('%c'): expected \"%s\", got \"%s\"\n",
225 i, mrulist[i], buff, items[mrulist[i] - 'a']);
226 }
227}
228
230{
231 return lstrcmpiA(data1, data2);
232}
233
234static void test_MRUListA(void)
235{
236 const char *checks[LIST_SIZE+1];
238 HANDLE hMRU;
239 HKEY hKey;
240 INT iRet;
241
242 if (!pCreateMRUListA || !pFreeMRUList || !pAddMRUStringA || !pEnumMRUListA)
243 {
244 win_skip("MRU entry points not found\n");
245 return;
246 }
247
248 if (0)
249 {
250 /* Create (NULL) - crashes native */
251 hMRU = pCreateMRUListA(NULL);
252 }
253
254 /* size too small */
255 infoA.cbSize = sizeof(infoA) - 2;
256 infoA.uMax = LIST_SIZE;
257 infoA.fFlags = MRU_STRING;
258 infoA.hKey = NULL;
259 infoA.lpszSubKey = REG_TEST_SUBKEYA;
260 infoA.lpfnCompare = cmp_mru_strA;
261
262 SetLastError(0);
263 hMRU = pCreateMRUListA(&infoA);
264 ok (!hMRU && !GetLastError(),
265 "CreateMRUListA(too small) expected NULL,0 got %p,%d\n",
266 hMRU, GetLastError());
267
268 /* size too big */
269 infoA.cbSize = sizeof(infoA) + 2;
270 infoA.uMax = LIST_SIZE;
271 infoA.fFlags = MRU_STRING;
272 infoA.hKey = NULL;
273 infoA.lpszSubKey = REG_TEST_SUBKEYA;
274 infoA.lpfnCompare = cmp_mru_strA;
275
276 SetLastError(0);
277 hMRU = pCreateMRUListA(&infoA);
278 ok (!hMRU && !GetLastError(),
279 "CreateMRUListA(too big) expected NULL,0 got %p,%d\n",
280 hMRU, GetLastError());
281
282 /* NULL hKey */
283 infoA.cbSize = sizeof(infoA);
284 infoA.uMax = LIST_SIZE;
285 infoA.fFlags = MRU_STRING;
286 infoA.hKey = NULL;
287 infoA.lpszSubKey = REG_TEST_SUBKEYA;
288 infoA.lpfnCompare = cmp_mru_strA;
289
290 SetLastError(0);
291 hMRU = pCreateMRUListA(&infoA);
292 ok (!hMRU && !GetLastError(),
293 "CreateMRUListA(NULL key) expected NULL,0 got %p,%d\n",
294 hMRU, GetLastError());
295
296 /* NULL subkey name */
297 infoA.cbSize = sizeof(infoA);
298 infoA.uMax = LIST_SIZE;
299 infoA.fFlags = MRU_STRING;
300 infoA.hKey = NULL;
301 infoA.lpszSubKey = NULL;
302 infoA.lpfnCompare = cmp_mru_strA;
303
304 SetLastError(0);
305 hMRU = pCreateMRUListA(&infoA);
306 ok (!hMRU && !GetLastError(),
307 "CreateMRUListA(NULL name) expected NULL,0 got %p,%d\n",
308 hMRU, GetLastError());
309
310 /* Create a string MRU */
312 "Couldn't create test key \"%s\"\n", REG_TEST_KEYA);
313 if (!hKey) return;
314
315 infoA.cbSize = sizeof(infoA);
316 infoA.uMax = LIST_SIZE;
317 infoA.fFlags = MRU_STRING;
318 infoA.hKey = hKey;
319 infoA.lpszSubKey = REG_TEST_SUBKEYA;
320 infoA.lpfnCompare = cmp_mru_strA;
321
322 hMRU = pCreateMRUListA(&infoA);
323 ok(hMRU && !GetLastError(),
324 "CreateMRUListA(string) expected non-NULL,0 got %p,%d\n",
325 hMRU, GetLastError());
326
327 if (hMRU)
328 {
329 char buffer[255];
330 checks[0] = "Test 1";
331 checks[1] = "Test 2";
332 checks[2] = "Test 3";
333 checks[3] = "Test 4";
334
335 /* Add (NULL list) */
336 SetLastError(0);
337 iRet = pAddMRUStringA(NULL, checks[0]);
338 ok(iRet == -1 && !GetLastError(),
339 "AddMRUStringA(NULL list) expected -1,0 got %d,%d\n",
340 iRet, GetLastError());
341
342 /* Add (NULL string) */
343 if (0)
344 {
345 /* Some native versions crash when passed NULL or fail to SetLastError() */
346 SetLastError(0);
347 iRet = pAddMRUStringA(hMRU, NULL);
348 ok(iRet == 0 && GetLastError() == ERROR_INVALID_PARAMETER,
349 "AddMRUStringA(NULL str) expected 0,ERROR_INVALID_PARAMETER got %d,%d\n",
350 iRet, GetLastError());
351 }
352
353 /* Add 3 strings. Check the registry is correct after each add */
354 SetLastError(0);
355 iRet = pAddMRUStringA(hMRU, checks[0]);
356 ok(iRet == 0 && !GetLastError(),
357 "AddMRUStringA(1) expected 0,0 got %d,%d\n",
358 iRet, GetLastError());
359 check_reg_entries("a", checks);
360
361 SetLastError(0);
362 iRet = pAddMRUStringA(hMRU, checks[1]);
363 ok(iRet == 1 && !GetLastError(),
364 "AddMRUStringA(2) expected 1,0 got %d,%d\n",
365 iRet, GetLastError());
366 check_reg_entries("ba", checks);
367
368 SetLastError(0);
369 iRet = pAddMRUStringA(hMRU, checks[2]);
370 ok(iRet == 2 && !GetLastError(),
371 "AddMRUStringA(2) expected 2,0 got %d,%d\n",
372 iRet, GetLastError());
373 check_reg_entries("cba", checks);
374
375 /* Add a duplicate of the 2nd string - it should move to the front,
376 * but keep the same index in the registry.
377 */
378 SetLastError(0);
379 iRet = pAddMRUStringA(hMRU, checks[1]);
380 ok(iRet == 1 && !GetLastError(),
381 "AddMRUStringA(re-add 1) expected 1,0 got %d,%d\n",
382 iRet, GetLastError());
383 check_reg_entries("bca", checks);
384
385 /* Add a new string - replaces the oldest string + moves to the front */
386 SetLastError(0);
387 iRet = pAddMRUStringA(hMRU, checks[3]);
388 ok(iRet == 0 && !GetLastError(),
389 "AddMRUStringA(add new) expected 0,0 got %d,%d\n",
390 iRet, GetLastError());
391 checks[0] = checks[3];
392 check_reg_entries("abc", checks);
393
394 /* NULL buffer = get list size */
395 iRet = pEnumMRUListA(hMRU, 0, NULL, 0);
396 ok(iRet == 3 || iRet == -1 /* Vista */, "EnumMRUList expected %d or -1, got %d\n", LIST_SIZE, iRet);
397
398 /* negative item pos = get list size */
399 iRet = pEnumMRUListA(hMRU, -1, NULL, 0);
400 ok(iRet == 3 || iRet == -1 /* Vista */, "EnumMRUList expected %d or -1, got %d\n", LIST_SIZE, iRet);
401
402 /* negative item pos = get list size */
403 iRet = pEnumMRUListA(hMRU, -5, NULL, 0);
404 ok(iRet == 3 || iRet == -1 /* Vista */, "EnumMRUList expected %d or -1, got %d\n", LIST_SIZE, iRet);
405
406 /* negative item pos = get list size */
407 iRet = pEnumMRUListA(hMRU, -1, buffer, 255);
408 ok(iRet == 3, "EnumMRUList expected %d, got %d\n", LIST_SIZE, iRet);
409
410 /* negative item pos = get list size */
411 iRet = pEnumMRUListA(hMRU, -5, buffer, 255);
412 ok(iRet == 3, "EnumMRUList expected %d, got %d\n", LIST_SIZE, iRet);
413
414 /* check entry 0 */
415 buffer[0] = 0;
416 iRet = pEnumMRUListA(hMRU, 0, buffer, 255);
417 ok(iRet == lstrlenA(checks[3]), "EnumMRUList expected %d, got %d\n", lstrlenA(checks[3]), iRet);
418 ok(strcmp(buffer, checks[3]) == 0, "EnumMRUList expected %s, got %s\n", checks[3], buffer);
419
420 /* check entry 0 with a too small buffer */
421 buffer[0] = 0; /* overwritten with 'T' */
422 buffer[1] = 'A'; /* overwritten with 0 */
423 buffer[2] = 'A'; /* unchanged */
424 buffer[3] = 0; /* unchanged */
425 iRet = pEnumMRUListA(hMRU, 0, buffer, 2);
426 ok(iRet == lstrlenA(checks[3]), "EnumMRUList expected %d, got %d\n", lstrlenA(checks[3]), iRet);
427 ok(strcmp(buffer, "T") == 0, "EnumMRUList expected %s, got %s\n", "T", buffer);
428 /* make sure space after buffer has old values */
429 ok(buffer[2] == 'A', "EnumMRUList expected %02x, got %02x\n", 'A', buffer[2]);
430
431 /* check entry 1 */
432 buffer[0] = 0;
433 iRet = pEnumMRUListA(hMRU, 1, buffer, 255);
434 ok(iRet == lstrlenA(checks[1]), "EnumMRUList expected %d, got %d\n", lstrlenA(checks[1]), iRet);
435 ok(strcmp(buffer, checks[1]) == 0, "EnumMRUList expected %s, got %s\n", checks[1], buffer);
436
437 /* check entry 2 */
438 buffer[0] = 0;
439 iRet = pEnumMRUListA(hMRU, 2, buffer, 255);
440 ok(iRet == lstrlenA(checks[2]), "EnumMRUList expected %d, got %d\n", lstrlenA(checks[2]), iRet);
441 ok(strcmp(buffer, checks[2]) == 0, "EnumMRUList expected %s, got %s\n", checks[2], buffer);
442
443 /* check out of bounds entry 3 */
444 strcpy(buffer, "dummy");
445 iRet = pEnumMRUListA(hMRU, 3, buffer, 255);
446 ok(iRet == -1, "EnumMRUList expected %d, got %d\n", -1, iRet);
447 ok(strcmp(buffer, "dummy") == 0, "EnumMRUList expected unchanged buffer %s, got %s\n", "dummy", buffer);
448
449 /* Finished with this MRU */
450 pFreeMRUList(hMRU);
451 }
452
453 /* FreeMRUList(NULL) crashes on Win98 OSR0 */
454}
455
456typedef struct {
460
461static const create_lazya_t create_lazyA[] = {
462 {{ sizeof(MRUINFOA) + 1, 0, 0, HKEY_CURRENT_USER, NULL, NULL }, FALSE },
463 {{ sizeof(MRUINFOA) - 1, 0, 0, HKEY_CURRENT_USER, NULL, NULL }, FALSE },
464 {{ sizeof(MRUINFOA) + 1, 0, 0, HKEY_CURRENT_USER, "WineTest", NULL }, TRUE },
465 {{ sizeof(MRUINFOA) - 1, 0, 0, HKEY_CURRENT_USER, "WineTest", NULL }, TRUE },
466 {{ sizeof(MRUINFOA), 0, 0, HKEY_CURRENT_USER, "WineTest", NULL }, TRUE },
467 {{ sizeof(MRUINFOA), 0, 0, HKEY_CURRENT_USER, NULL, NULL }, FALSE },
468 {{ sizeof(MRUINFOA), 0, 0, NULL, "WineTest", NULL }, FALSE },
469 {{ 0, 0, 0, NULL, "WineTest", NULL }, FALSE },
470 {{ 0, 0, 0, HKEY_CURRENT_USER, "WineTest", NULL }, TRUE }
471};
472
473static void test_CreateMRUListLazyA(void)
474{
475 int i;
476
477 if (!pCreateMRUListLazyA || !pFreeMRUList)
478 {
479 win_skip("CreateMRUListLazyA or FreeMRUList entry points not found\n");
480 return;
481 }
482
483 for (i = 0; i < ARRAY_SIZE(create_lazyA); i++)
484 {
485 const create_lazya_t *ptr = &create_lazyA[i];
486 HANDLE hMRU;
487
488 hMRU = pCreateMRUListLazyA((MRUINFOA*)&ptr->mruA, 0, 0, 0);
489 if (ptr->ret)
490 {
491 ok(hMRU != NULL, "%d: got %p\n", i, hMRU);
492 pFreeMRUList(hMRU);
493 }
494 else
495 ok(hMRU == NULL, "%d: got %p\n", i, hMRU);
496 }
497}
498
499static void test_EnumMRUList(void)
500{
501 if (!pEnumMRUListA || !pEnumMRUListW)
502 {
503 win_skip("EnumMRUListA/EnumMRUListW entry point not found\n");
504 return;
505 }
506
507 /* NULL handle */
508 if (0)
509 {
510 /* crashes on NT4, passed on Win2k, XP, 2k3, Vista, 2k8 */
511 pEnumMRUListA(NULL, 0, NULL, 0);
512 pEnumMRUListW(NULL, 0, NULL, 0);
513 }
514}
515
516static void test_FindMRUData(void)
517{
518 INT iRet;
519
520 if (!pFindMRUData)
521 {
522 win_skip("FindMRUData entry point not found\n");
523 return;
524 }
525
526 /* NULL handle */
527 iRet = pFindMRUData(NULL, NULL, 0, NULL);
528 ok(iRet == -1, "FindMRUData expected -1, got %d\n", iRet);
529}
530
531static void test_AddMRUData(void)
532{
533 INT iRet;
534
535 if (!pAddMRUData)
536 {
537 win_skip("AddMRUData entry point not found\n");
538 return;
539 }
540
541 /* NULL handle */
542 iRet = pFindMRUData(NULL, NULL, 0, NULL);
543 ok(iRet == -1, "AddMRUData expected -1, got %d\n", iRet);
544}
545
546static void test_CreateMRUListW(void)
547{
548 static const WCHAR mrutestW[] = {'M','R','U','T','e','s','t',0};
550 void *named;
551 HKEY hKey;
552 HANDLE hMru;
553
554 if (!pCreateMRUListW)
555 {
556 win_skip("CreateMRUListW entry point not found\n");
557 return;
558 }
559
560 /* exported by name too on recent versions */
561 named = GetProcAddress(hComctl32, "CreateMRUListW");
562 if (named)
563 ok(named == pCreateMRUListW, "got %p, expected %p\n", named, pCreateMRUListW);
564
566 "Couldn't create test key \"%s\"\n", REG_TEST_KEYA);
567
568 infoW.cbSize = sizeof(infoW);
569 infoW.uMax = 1;
570 infoW.fFlags = 0;
571 infoW.lpszSubKey = mrutestW;
572 infoW.hKey = hKey;
573 infoW.lpfnCompare = NULL;
574
575 hMru = pCreateMRUListW(&infoW);
576 ok(hMru != NULL, "got %p\n", hMru);
577 pFreeMRUList(hMru);
578
579 /* smaller size */
580 infoW.cbSize = sizeof(infoW) - 1;
581 infoW.uMax = 1;
582 infoW.fFlags = 0;
583 infoW.lpszSubKey = mrutestW;
584 infoW.hKey = hKey;
585 infoW.lpfnCompare = NULL;
586
587 hMru = pCreateMRUListW(&infoW);
588 ok(hMru != NULL, "got %p\n", hMru);
589 pFreeMRUList(hMru);
590
591 /* increased size */
592 infoW.cbSize = sizeof(infoW) + 1;
593 infoW.uMax = 1;
594 infoW.fFlags = 0;
595 infoW.lpszSubKey = mrutestW;
596 infoW.hKey = hKey;
597 infoW.lpfnCompare = NULL;
598
599 hMru = pCreateMRUListW(&infoW);
600 ok(hMru != NULL, "got %p\n", hMru);
601 pFreeMRUList(hMru);
602
603 /* zero size */
604 infoW.cbSize = 0;
605 infoW.uMax = 1;
606 infoW.fFlags = 0;
607 infoW.lpszSubKey = mrutestW;
608 infoW.hKey = hKey;
609 infoW.lpfnCompare = NULL;
610
611 hMru = pCreateMRUListW(&infoW);
612 ok(hMru != NULL, "got %p\n", hMru);
613 pFreeMRUList(hMru);
614
615 /* NULL hKey */
616 infoW.cbSize = sizeof(infoW);
617 infoW.uMax = 1;
618 infoW.fFlags = 0;
619 infoW.lpszSubKey = mrutestW;
620 infoW.hKey = NULL;
621 infoW.lpfnCompare = NULL;
622
623 hMru = pCreateMRUListW(&infoW);
624 ok(hMru == NULL, "got %p\n", hMru);
625
627}
628
629static void test_CreateMRUListLazyW(void)
630{
631 static const WCHAR mrutestW[] = {'M','R','U','T','e','s','t',0};
633 void *named;
634 HKEY hKey;
635 HANDLE hMru;
636
637 if (!pCreateMRUListLazyW)
638 {
639 win_skip("CreateMRUListLazyW entry point not found\n");
640 return;
641 }
642
643 /* check that it's not exported by name */
644 named = GetProcAddress(hComctl32, "CreateMRUListLazyW");
645 ok(named == NULL, "got %p\n", named);
646
648 "Couldn't create test key \"%s\"\n", REG_TEST_KEYA);
649
650 infoW.cbSize = sizeof(infoW);
651 infoW.uMax = 1;
652 infoW.fFlags = 0;
653 infoW.lpszSubKey = mrutestW;
654 infoW.hKey = hKey;
655 infoW.lpfnCompare = NULL;
656
657 hMru = pCreateMRUListLazyW(&infoW, 0, 0, 0);
658 ok(hMru != NULL, "got %p\n", hMru);
659 pFreeMRUList(hMru);
660
661 /* smaller size */
662 infoW.cbSize = sizeof(infoW) - 1;
663 infoW.uMax = 1;
664 infoW.fFlags = 0;
665 infoW.lpszSubKey = mrutestW;
666 infoW.hKey = hKey;
667 infoW.lpfnCompare = NULL;
668
669 hMru = pCreateMRUListLazyW(&infoW, 0, 0, 0);
670 ok(hMru != NULL, "got %p\n", hMru);
671 pFreeMRUList(hMru);
672
673 /* increased size */
674 infoW.cbSize = sizeof(infoW) + 1;
675 infoW.uMax = 1;
676 infoW.fFlags = 0;
677 infoW.lpszSubKey = mrutestW;
678 infoW.hKey = hKey;
679 infoW.lpfnCompare = NULL;
680
681 hMru = pCreateMRUListLazyW(&infoW, 0, 0, 0);
682 ok(hMru != NULL, "got %p\n", hMru);
683 pFreeMRUList(hMru);
684
685 /* zero size */
686 infoW.cbSize = 0;
687 infoW.uMax = 1;
688 infoW.fFlags = 0;
689 infoW.lpszSubKey = mrutestW;
690 infoW.hKey = hKey;
691 infoW.lpfnCompare = NULL;
692
693 hMru = pCreateMRUListLazyW(&infoW, 0, 0, 0);
694 ok(hMru != NULL, "got %p\n", hMru);
695 pFreeMRUList(hMru);
696
697 /* NULL hKey */
698 infoW.cbSize = sizeof(infoW);
699 infoW.uMax = 1;
700 infoW.fFlags = 0;
701 infoW.lpszSubKey = mrutestW;
702 infoW.hKey = NULL;
703 infoW.lpfnCompare = NULL;
704
705 hMru = pCreateMRUListLazyW(&infoW, 0, 0, 0);
706 ok(hMru == NULL, "got %p\n", hMru);
707
709}
710
712{
714 if (!create_reg_entries())
715 return;
716
718
726
728}
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
#define ok(value,...)
Definition: atltest.h:57
#define START_TEST(x)
Definition: atltest.h:75
#define ARRAY_SIZE(A)
Definition: main.h:33
#define RegCloseKey(hKey)
Definition: registry.h:49
INT WINAPI FindMRUData(HANDLE hList, LPCVOID lpData, DWORD cbData, LPINT lpRegNum)
INT WINAPI AddMRUStringA(HANDLE hList, LPCSTR lpszString)
INT WINAPI EnumMRUListW(HANDLE hList, INT nItemPos, LPVOID lpBuffer, DWORD nBufferSize)
HANDLE WINAPI CreateMRUListW(const MRUINFOW *infoW)
HANDLE WINAPI CreateMRUListA(const MRUINFOA *lpcml)
INT WINAPI EnumMRUListA(HANDLE hList, INT nItemPos, LPVOID lpBuffer, DWORD nBufferSize)
void WINAPI FreeMRUList(HANDLE hMRUList)
HANDLE WINAPI CreateMRUListLazyA(const MRUINFOA *lpcml, DWORD dwParam2, DWORD dwParam3, DWORD dwParam4)
INT WINAPI AddMRUData(HANDLE hList, LPCVOID lpData, DWORD cbData)
HANDLE WINAPI CreateMRUListLazyW(const MRUINFOW *infoW, DWORD dwParam2, DWORD dwParam3, DWORD dwParam4)
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
static LSTATUS(WINAPI *pRegDeleteTreeW)(HKEY
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
LONG WINAPI RegCreateKeyA(HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1179
LONG WINAPI RegOpenKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD ulOptions, _In_ REGSAM samDesired, _Out_ PHKEY phkResult)
Definition: reg.c:3298
LONG WINAPI RegQueryInfoKeyA(HKEY hKey, LPSTR lpClass, LPDWORD lpcClass, LPDWORD lpReserved, LPDWORD lpcSubKeys, LPDWORD lpcMaxSubKeyLen, LPDWORD lpcMaxClassLen, LPDWORD lpcValues, LPDWORD lpcMaxValueNameLen, LPDWORD lpcMaxValueLen, LPDWORD lpcbSecurityDescriptor, PFILETIME lpftLastWriteTime)
Definition: reg.c:3583
LONG WINAPI RegOpenKeyA(HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3234
LONG WINAPI RegEnumValueA(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpdwReserved, _Out_opt_ LPDWORD lpdwType, _Out_opt_ LPBYTE lpData, _Inout_opt_ LPDWORD lpcbData)
Definition: reg.c:2668
LONG WINAPI RegDeleteValueA(HKEY hKey, LPCSTR lpValueName)
Definition: reg.c:2287
LONG WINAPI RegQueryValueExA(_In_ HKEY hkeyorg, _In_ LPCSTR name, _In_ LPDWORD reserved, _Out_opt_ LPDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ LPDWORD count)
Definition: reg.c:4009
LONG WINAPI RegEnumKeyExA(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2419
LONG WINAPI RegDeleteKeyA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey)
Definition: reg.c:1224
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define SetLastError(x)
Definition: compat.h:752
#define GetProcAddress(x, y)
Definition: compat.h:753
#define MAX_PATH
Definition: compat.h:34
#define CALLBACK
Definition: compat.h:35
static void cleanup(void)
Definition: main.c:1335
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
int WINAPI lstrcmpiA(LPCSTR str1, LPCSTR str2)
Definition: locale.c:4223
static unsigned char buff[32768]
Definition: fatten.c:17
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
FxAutoRegKey hKey
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLuint buffer
Definition: glext.h:5915
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static const SecPkgInfoW infoW
Definition: kerberos.c:293
static const SecPkgInfoA infoA
Definition: kerberos.c:302
#define REG_SZ
Definition: layer.c:22
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
static PVOID ptr
Definition: dispmode.c:27
static LPINT
Definition: mru.c:76
static void test_CreateMRUListLazyA(void)
Definition: mru.c:473
struct tagMRUINFOW MRUINFOW
#define X2(f, ord)
#define REG_TEST_BASEKEYA
Definition: mru.c:35
static void test_CreateMRUListW(void)
Definition: mru.c:546
#define LIST_SIZE
Definition: mru.c:66
static INT
Definition: mru.c:72
#define REG_TEST_KEYA
Definition: mru.c:37
struct tagMRUINFOA MRUINFOA
static void test_FindMRUData(void)
Definition: mru.c:516
static LSTATUS mru_RegDeleteTreeA(HKEY hKey, LPCSTR lpszSubKey)
Definition: mru.c:99
static void test_AddMRUData(void)
Definition: mru.c:531
static DWORD
Definition: mru.c:72
#define REG_TEST_FULLKEY
Definition: mru.c:39
static const create_lazya_t create_lazyA[]
Definition: mru.c:461
static void test_MRUListA(void)
Definition: mru.c:234
static LPCVOID
Definition: mru.c:76
static void test_CreateMRUListLazyW(void)
Definition: mru.c:629
static void check_reg_entries(const char *mrulist, const char **items)
Definition: mru.c:187
static LPVOID
Definition: mru.c:72
#define REG_TEST_SUBKEYA
Definition: mru.c:38
static void delete_reg_entries(void)
Definition: mru.c:176
static BOOL create_reg_entries(void)
Definition: mru.c:165
#define MRU_STRING
Definition: mru.c:62
static void init_functions(void)
Definition: mru.c:80
static LPCSTR
Definition: mru.c:71
static int CALLBACK cmp_mru_strA(LPCSTR data1, LPCSTR data2)
Definition: mru.c:229
static void test_EnumMRUList(void)
Definition: mru.c:499
static HMODULE hComctl32
Definition: mru.c:68
#define REG_TEST_BASESUBKEYA
Definition: mru.c:36
unsigned int UINT
Definition: ndis.h:50
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define KEY_READ
Definition: nt_native.h:1023
static TCHAR * items[]
Definition: page1.c:45
long LONG
Definition: pedump.c:60
#define win_skip
Definition: test.h:163
BOOL ret
Definition: mru.c:458
MRUINFOA mruA
Definition: mru.c:457
Definition: tftpd.h:126
Definition: tftpd.h:138
Definition: name.c:39
LPCSTR lpszSubKey
Definition: mru.c:48
LPCSTR
Definition: mru.c:49
int(CALLBACK *lpfnCompare)(LPCSTR
LPCWSTR
Definition: mru.c:59
LPCWSTR lpszSubKey
Definition: mru.c:58
int(CALLBACK *lpfnCompare)(LPCWSTR
#define max(a, b)
Definition: svc.c:63
unsigned char * LPBYTE
Definition: typedefs.h:53
PVOID HANDLE
Definition: typedefs.h:73
int32_t INT
Definition: typedefs.h:58
int ret
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define WINAPI
Definition: msvc.h:6
#define HKEY_CURRENT_USER
Definition: winreg.h:11
const char * LPCSTR
Definition: xmlstorage.h:183
__wchar_t WCHAR
Definition: xmlstorage.h:180
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
char CHAR
Definition: xmlstorage.h:175