2 * comctl32 MRU unit tests
4 * Copyright (C) 2004 Jon Griffiths <jon_p_griffiths@yahoo.com>
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.
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.
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
31 #include "wine/test.h"
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
40 /* Undocumented MRU structures & functions */
41 typedef struct tagCREATEMRULISTA
49 } CREATEMRULISTA
, *LPCREATEMRULISTA
;
51 #define MRUF_STRING_LIST 0
52 #define MRUF_BINARY_LIST 1
53 #define MRUF_DELAYED_SAVE 2
55 #define LIST_SIZE 3 /* Max entries for each mru */
57 static CREATEMRULISTA mruA
=
59 sizeof(CREATEMRULISTA
),
67 static HMODULE hComctl32
;
68 static HANDLE (WINAPI
*pCreateMRUListA
)(LPCREATEMRULISTA
);
69 static void (WINAPI
*pFreeMRUList
)(HANDLE
);
70 static INT (WINAPI
*pAddMRUStringA
)(HANDLE
,LPCSTR
);
72 static INT (WINAPI *pFindMRUStringA)(HANDLE,LPCSTR,LPINT);
73 static INT (WINAPI *pEnumMRUList)(HANDLE,INT,LPVOID,DWORD);
76 static BOOL
create_reg_entries(void)
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
;
87 static void delete_reg_entries(void)
91 if (RegOpenKeyExA(HKEY_CURRENT_USER
, REG_TEST_BASEKEYA
, 0, KEY_ALL_ACCESS
,
94 SHDeleteKeyA(hKey
, REG_TEST_BASESUBKEYA
);
98 static void check_reg_entries(const char *mrulist
, const char**items
)
102 DWORD type
, size
, ret
;
105 ok(!RegOpenKeyA(HKEY_CURRENT_USER
, REG_TEST_FULLKEY
, &hKey
),
106 "Couldn't open test key \"%s\"\n", REG_TEST_FULLKEY
);
112 ret
= RegQueryValueExA(hKey
, "MRUList", NULL
, &type
, (LPBYTE
)buff
, &size
);
114 ok(!ret
&& buff
[0], "Checking MRU: got %d from RegQueryValueExW\n", ret
);
115 if(ret
|| !buff
[0]) return;
117 ok(strcmp(buff
, mrulist
) == 0, "Checking MRU: Expected list %s, got %s\n",
119 if(strcmp(buff
, mrulist
)) return;
121 for (i
= 0; i
< strlen(mrulist
); i
++)
124 name
[0] = mrulist
[i
];
129 ret
= RegQueryValueExA(hKey
, name
, NULL
, &type
, (LPBYTE
)buff
, &size
);
131 "Checking MRU item %d ('%c'): got %d from RegQueryValueExW\n",
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']);
140 static INT CALLBACK
cmp_mru_strA(LPCVOID data1
, LPCVOID data2
)
142 return lstrcmpiA(data1
, data2
);
145 static HANDLE
create_mruA(HKEY hKey
, DWORD flags
, PROC cmp
)
147 mruA
.dwFlags
= flags
;
148 mruA
.lpfnCompare
= cmp
;
152 return pCreateMRUListA(&mruA
);
155 static void test_MRUListA(void)
157 const char *checks
[LIST_SIZE
+1];
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
)
170 /* Create (NULL) - crashes native */
171 hMRU
= pCreateMRUListA(NULL
);
174 /* Create (size too small) */
175 mruA
.cbSize
= sizeof(mruA
) - 2;
176 hMRU
= create_mruA(NULL
, MRUF_STRING_LIST
, (PROC
)cmp_mru_strA
);
177 ok (!hMRU
&& !GetLastError(),
178 "CreateMRUListA(too small) expected NULL,0 got %p,%d\n",
179 hMRU
, GetLastError());
180 mruA
.cbSize
= sizeof(mruA
);
182 /* Create (size too big) */
183 mruA
.cbSize
= sizeof(mruA
) + 2;
184 hMRU
= create_mruA(NULL
, MRUF_STRING_LIST
, (PROC
)cmp_mru_strA
);
185 ok (!hMRU
&& !GetLastError(),
186 "CreateMRUListA(too big) expected NULL,0 got %p,%d\n",
187 hMRU
, GetLastError());
188 mruA
.cbSize
= sizeof(mruA
);
190 /* Create (NULL hKey) */
191 hMRU
= create_mruA(NULL
, MRUF_STRING_LIST
, (PROC
)cmp_mru_strA
);
192 ok (!hMRU
&& !GetLastError(),
193 "CreateMRUListA(NULL key) expected NULL,0 got %p,%d\n",
194 hMRU
, GetLastError());
196 /* Create (NULL name) */
197 mruA
.lpszSubKey
= NULL
;
198 hMRU
= create_mruA(NULL
, MRUF_STRING_LIST
, (PROC
)cmp_mru_strA
);
199 ok (!hMRU
&& !GetLastError(),
200 "CreateMRUListA(NULL name) expected NULL,0 got %p,%d\n",
201 hMRU
, GetLastError());
202 mruA
.lpszSubKey
= REG_TEST_SUBKEYA
;
204 /* Create a string MRU */
205 ok(!RegCreateKeyA(HKEY_CURRENT_USER
, REG_TEST_KEYA
, &hKey
),
206 "Couldn't create test key \"%s\"\n", REG_TEST_KEYA
);
209 hMRU
= create_mruA(hKey
, MRUF_STRING_LIST
, (PROC
)cmp_mru_strA
);
210 ok(hMRU
&& !GetLastError(),
211 "CreateMRUListA(string) expected non-NULL,0 got %p,%d\n",
212 hMRU
, GetLastError());
216 checks
[0] = "Test 1";
217 checks
[1] = "Test 2";
218 checks
[2] = "Test 3";
219 checks
[3] = "Test 4";
221 /* Add (NULL list) */
223 iRet
= pAddMRUStringA(NULL
, checks
[0]);
224 ok(iRet
== -1 && !GetLastError(),
225 "AddMRUStringA(NULL list) expected -1,0 got %d,%d\n",
226 iRet
, GetLastError());
228 /* Add (NULL string) */
231 /* Some native versions crash when passed NULL or fail to SetLastError() */
233 iRet
= pAddMRUStringA(hMRU
, NULL
);
234 ok(iRet
== 0 && GetLastError() == ERROR_INVALID_PARAMETER
,
235 "AddMRUStringA(NULL str) expected 0,ERROR_INVALID_PARAMETER got %d,%d\n",
236 iRet
, GetLastError());
239 /* Add 3 strings. Check the registry is correct after each add */
241 iRet
= pAddMRUStringA(hMRU
, checks
[0]);
242 ok(iRet
== 0 && !GetLastError(),
243 "AddMRUStringA(1) expected 0,0 got %d,%d\n",
244 iRet
, GetLastError());
245 check_reg_entries("a", checks
);
248 iRet
= pAddMRUStringA(hMRU
, checks
[1]);
249 ok(iRet
== 1 && !GetLastError(),
250 "AddMRUStringA(2) expected 1,0 got %d,%d\n",
251 iRet
, GetLastError());
252 check_reg_entries("ba", checks
);
255 iRet
= pAddMRUStringA(hMRU
, checks
[2]);
256 ok(iRet
== 2 && !GetLastError(),
257 "AddMRUStringA(2) expected 2,0 got %d,%d\n",
258 iRet
, GetLastError());
259 check_reg_entries("cba", checks
);
261 /* Add a duplicate of the 2nd string - it should move to the front,
262 * but keep the same index in the registry.
265 iRet
= pAddMRUStringA(hMRU
, checks
[1]);
266 ok(iRet
== 1 && !GetLastError(),
267 "AddMRUStringA(re-add 1) expected 1,0 got %d,%d\n",
268 iRet
, GetLastError());
269 check_reg_entries("bca", checks
);
271 /* Add a new string - replaces the oldest string + moves to the front */
273 iRet
= pAddMRUStringA(hMRU
, checks
[3]);
274 ok(iRet
== 0 && !GetLastError(),
275 "AddMRUStringA(add new) expected 0,0 got %d,%d\n",
276 iRet
, GetLastError());
277 checks
[0] = checks
[3];
278 check_reg_entries("abc", checks
);
280 /* Finished with this MRU */
284 /* Free (NULL list) - Doesn't crash */
290 hComctl32
= GetModuleHandleA("comctl32.dll");
292 delete_reg_entries();
293 if (!create_reg_entries())
298 delete_reg_entries();