2 * Unit tests for misc shdocvw functions
4 * Copyright 2008 Detlef Riekenberg
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
30 #include "wine/test.h"
32 /* ################ */
34 static HMODULE hshdocvw
;
35 static HRESULT (WINAPI
*pURLSubRegQueryA
)(LPCSTR
, LPCSTR
, DWORD
, LPVOID
, DWORD
, DWORD
);
36 static DWORD (WINAPI
*pParseURLFromOutsideSourceA
)(LPCSTR
, LPSTR
, LPDWORD
, LPDWORD
);
37 static DWORD (WINAPI
*pParseURLFromOutsideSourceW
)(LPCWSTR
, LPWSTR
, LPDWORD
, LPDWORD
);
39 static CHAR appdata
[] = "AppData";
40 static CHAR common_appdata
[] = "Common AppData";
41 static CHAR default_page_url
[] = "Default_Page_URL";
42 static CHAR does_not_exist
[] = "does_not_exist";
43 static CHAR regpath_iemain
[] = "Software\\Microsoft\\Internet Explorer\\Main";
44 static CHAR regpath_shellfolders
[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
45 static CHAR start_page
[] = "Start Page";
47 /* ################ */
53 } ParseURL_table
[] = {
54 {"http://www.winehq.org", "http://www.winehq.org/", 22},
55 {"www.winehq.org", "http://www.winehq.org/", 22},
56 {"winehq.org", "http://winehq.org/", 18},
57 {"ftp.winehq.org", "ftp://ftp.winehq.org/", 21},
58 {"http://winehq.org", "http://winehq.org/", 18},
59 {"https://winehq.org", "https://winehq.org/", 19},
60 {"https://www.winehq.org", "https://www.winehq.org/", 23},
61 {"ftp://winehq.org", "ftp://winehq.org/", 17},
62 {"ftp://ftp.winehq.org", "ftp://ftp.winehq.org/", 21},
63 {"about:blank", "about:blank", 11},
64 {"about:home", "about:home", 10},
65 {"about:mozilla", "about:mozilla", 13},
66 /* a space at the start is not allowed */
67 {" http://www.winehq.org", "http://%20http://www.winehq.org", 31}
71 /* ################ */
73 static void init_functions(void)
75 hshdocvw
= LoadLibraryA("shdocvw.dll");
76 pURLSubRegQueryA
= (void *) GetProcAddress(hshdocvw
, (LPSTR
) 151);
77 pParseURLFromOutsideSourceA
= (void *) GetProcAddress(hshdocvw
, (LPSTR
) 169);
78 pParseURLFromOutsideSourceW
= (void *) GetProcAddress(hshdocvw
, (LPSTR
) 170);
81 /* ################ */
83 static void test_URLSubRegQueryA(void)
85 CHAR buffer
[INTERNET_MAX_URL_LENGTH
];
90 if (!pURLSubRegQueryA
) {
91 skip("URLSubRegQueryA not found\n");
95 memset(buffer
, '#', sizeof(buffer
)-1);
96 buffer
[sizeof(buffer
)-1] = '\0';
97 /* called by inetcpl.cpl */
98 hr
= pURLSubRegQueryA(regpath_iemain
, default_page_url
, REG_SZ
, buffer
, INTERNET_MAX_URL_LENGTH
, -1);
99 ok(hr
== E_FAIL
|| hr
== S_OK
, "got 0x%x (expected E_FAIL or S_OK)\n", hr
);
101 memset(buffer
, '#', sizeof(buffer
)-1);
102 buffer
[sizeof(buffer
)-1] = '\0';
103 /* called by inetcpl.cpl */
104 hr
= pURLSubRegQueryA(regpath_iemain
, start_page
, REG_SZ
, buffer
, INTERNET_MAX_URL_LENGTH
, -1);
105 len
= lstrlenA(buffer
);
106 /* respect privacy: do not dump the url */
107 ok(hr
== S_OK
, "got 0x%x and %d (expected S_OK)\n", hr
, len
);
109 /* test buffer length: just large enough */
110 memset(buffer
, '#', sizeof(buffer
)-1);
111 buffer
[sizeof(buffer
)-1] = '\0';
112 hr
= pURLSubRegQueryA(regpath_iemain
, start_page
, REG_SZ
, buffer
, len
+1, -1);
113 used
= lstrlenA(buffer
);
114 /* respect privacy: do not dump the url */
115 ok((hr
== S_OK
) && (used
== len
),
116 "got 0x%x and %d (expected S_OK and %d)\n", hr
, used
, len
);
118 /* no space for terminating 0: result is truncated */
119 memset(buffer
, '#', sizeof(buffer
)-1);
120 buffer
[sizeof(buffer
)-1] = '\0';
121 hr
= pURLSubRegQueryA(regpath_iemain
, start_page
, REG_SZ
, buffer
, len
, -1);
122 used
= lstrlenA(buffer
);
123 ok((hr
== S_OK
) && (used
== len
- 1),
124 "got 0x%x and %d (expected S_OK and %d)\n", hr
, used
, len
- 1);
126 /* no space for the complete result: truncate another char */
128 memset(buffer
, '#', sizeof(buffer
)-1);
129 buffer
[sizeof(buffer
)-1] = '\0';
130 hr
= pURLSubRegQueryA(regpath_iemain
, start_page
, REG_SZ
, buffer
, len
-1, -1);
131 used
= lstrlenA(buffer
);
132 ok((hr
== S_OK
) && (used
== (len
- 2)),
133 "got 0x%x and %d (expected S_OK and %d)\n", hr
, used
, len
- 2);
136 /* only space for the terminating 0: function still succeded */
137 memset(buffer
, '#', sizeof(buffer
)-1);
138 buffer
[sizeof(buffer
)-1] = '\0';
139 hr
= pURLSubRegQueryA(regpath_iemain
, start_page
, REG_SZ
, buffer
, 1, -1);
140 used
= lstrlenA(buffer
);
141 ok((hr
== S_OK
) && !used
,
142 "got 0x%x and %d (expected S_OK and 0)\n", hr
, used
);
144 /* size of buffer is 0, but the function still succeed.
145 buffer[0] is cleared in IE 5.01 and IE 5.5 (Buffer Overflow) */
146 memset(buffer
, '#', sizeof(buffer
)-1);
147 buffer
[sizeof(buffer
)-1] = '\0';
148 hr
= pURLSubRegQueryA(regpath_iemain
, start_page
, REG_SZ
, buffer
, 0, -1);
149 used
= lstrlenA(buffer
);
151 ((used
== INTERNET_MAX_URL_LENGTH
- 1) || broken(used
== 0)) ,
152 "got 0x%x and %d (expected S_OK and INTERNET_MAX_URL_LENGTH - 1)\n",
155 /* still succeed without a buffer for the result */
156 hr
= pURLSubRegQueryA(regpath_iemain
, start_page
, REG_SZ
, NULL
, 0, -1);
157 ok(hr
== S_OK
, "got 0x%x (expected S_OK)\n", hr
);
159 /* still succeed, when a length is given without a buffer */
160 hr
= pURLSubRegQueryA(regpath_iemain
, start_page
, REG_SZ
, NULL
, INTERNET_MAX_URL_LENGTH
, -1);
161 ok(hr
== S_OK
, "got 0x%x (expected S_OK)\n", hr
);
163 /* this value does not exist */
164 memset(buffer
, '#', sizeof(buffer
)-1);
165 buffer
[sizeof(buffer
)-1] = '\0';
166 hr
= pURLSubRegQueryA(regpath_iemain
, does_not_exist
, REG_SZ
, buffer
, INTERNET_MAX_URL_LENGTH
, -1);
167 /* random bytes are copied to the buffer */
168 ok((hr
== E_FAIL
), "got 0x%x (expected E_FAIL)\n", hr
);
170 /* the third parameter is ignored. Is it really a type? (data is REG_SZ) */
171 memset(buffer
, '#', sizeof(buffer
)-1);
172 buffer
[sizeof(buffer
)-1] = '\0';
173 hr
= pURLSubRegQueryA(regpath_iemain
, start_page
, REG_DWORD
, buffer
, INTERNET_MAX_URL_LENGTH
, -1);
174 used
= lstrlenA(buffer
);
175 ok((hr
== S_OK
) && (used
== len
),
176 "got 0x%x and %d (expected S_OK and %d)\n", hr
, used
, len
);
178 /* the function works for HKCU and HKLM */
179 memset(buffer
, '#', sizeof(buffer
)-1);
180 buffer
[sizeof(buffer
)-1] = '\0';
181 hr
= pURLSubRegQueryA(regpath_shellfolders
, appdata
, REG_SZ
, buffer
, INTERNET_MAX_URL_LENGTH
, -1);
182 used
= lstrlenA(buffer
);
183 ok(hr
== S_OK
, "got 0x%x and %d (expected S_OK)\n", hr
, used
);
185 memset(buffer
, '#', sizeof(buffer
)-1);
186 buffer
[sizeof(buffer
)-1] = '\0';
187 hr
= pURLSubRegQueryA(regpath_shellfolders
, common_appdata
, REG_SZ
, buffer
, INTERNET_MAX_URL_LENGTH
, -1);
188 used
= lstrlenA(buffer
);
189 ok(hr
== S_OK
, "got 0x%x and %d (expected S_OK)\n", hr
, used
);
191 /* todo: what does the last parameter mean? */
194 /* ################ */
196 static void test_ParseURLFromOutsideSourceA(void)
198 CHAR buffer
[INTERNET_MAX_URL_LENGTH
];
205 if (!pParseURLFromOutsideSourceA
) {
206 skip("ParseURLFromOutsideSourceA not found\n");
210 for(i
= 0; i
< sizeof(ParseURL_table
)/sizeof(ParseURL_table
[0]); i
++) {
211 memset(buffer
, '#', sizeof(buffer
)-1);
212 buffer
[sizeof(buffer
)-1] = '\0';
213 len
= sizeof(buffer
);
215 /* on success, len+1 is returned. No idea, if someone depend on this */
216 res
= pParseURLFromOutsideSourceA(ParseURL_table
[i
].url
, buffer
, &len
, &dummy
);
217 /* len does not include the terminating 0, when buffer is large enough */
218 ok( res
!= 0 && len
== ParseURL_table
[i
].len
&&
219 !lstrcmpA(buffer
, ParseURL_table
[i
].newurl
),
220 "#%d: got %d and %d with '%s' (expected '!=0' and %d with '%s')\n",
221 i
, res
, len
, buffer
, ParseURL_table
[i
].len
, ParseURL_table
[i
].newurl
);
224 /* use the size test only for the first examples */
229 memset(buffer
, '#', sizeof(buffer
)-1);
230 buffer
[sizeof(buffer
)-1] = '\0';
233 res
= pParseURLFromOutsideSourceA(ParseURL_table
[i
].url
, buffer
, &len
, &dummy
);
234 ok( res
!= 0 && len
== ParseURL_table
[i
].len
&&
235 !lstrcmpA(buffer
, ParseURL_table
[i
].newurl
),
236 "#%d (+1): got %d and %d with '%s' (expected '!=0' and %d with '%s')\n",
237 i
, res
, len
, buffer
, ParseURL_table
[i
].len
, ParseURL_table
[i
].newurl
);
239 memset(buffer
, '#', sizeof(buffer
)-1);
240 buffer
[sizeof(buffer
)-1] = '\0';
243 res
= pParseURLFromOutsideSourceA(ParseURL_table
[i
].url
, buffer
, &len
, &dummy
);
244 /* len includes the terminating 0, when the buffer is too small */
245 ok( res
== 0 && len
== ParseURL_table
[i
].len
+ 1,
246 "#%d (==): got %d and %d (expected '0' and %d)\n",
247 i
, res
, len
, ParseURL_table
[i
].len
+ 1);
249 memset(buffer
, '#', sizeof(buffer
)-1);
250 buffer
[sizeof(buffer
)-1] = '\0';
253 res
= pParseURLFromOutsideSourceA(ParseURL_table
[i
].url
, buffer
, &len
, &dummy
);
254 /* len includes the terminating 0 on XP SP1 and before, when the buffer is too small */
255 ok( res
== 0 && (len
== ParseURL_table
[i
].len
|| len
== ParseURL_table
[i
].len
+ 1),
256 "#%d (-1): got %d and %d (expected '0' and %d or %d)\n",
257 i
, res
, len
, ParseURL_table
[i
].len
, ParseURL_table
[i
].len
+ 1);
259 memset(buffer
, '#', sizeof(buffer
)-1);
260 buffer
[sizeof(buffer
)-1] = '\0';
263 res
= pParseURLFromOutsideSourceA(ParseURL_table
[i
].url
, NULL
, &len
, &dummy
);
264 /* len does not include the terminating 0, when buffer is NULL */
265 ok( res
== 0 && len
== ParseURL_table
[i
].len
,
266 "#%d (buffer): got %d and %d (expected '0' and %d)\n",
267 i
, res
, len
, ParseURL_table
[i
].len
);
270 /* that test crash on native shdocvw */
271 res
= pParseURLFromOutsideSourceA(ParseURL_table
[i
].url
, buffer
, NULL
, &dummy
);
274 memset(buffer
, '#', sizeof(buffer
)-1);
275 buffer
[sizeof(buffer
)-1] = '\0';
278 res
= pParseURLFromOutsideSourceA(ParseURL_table
[i
].url
, buffer
, &len
, NULL
);
279 ok( res
!= 0 && len
== ParseURL_table
[i
].len
&&
280 !lstrcmpA(buffer
, ParseURL_table
[i
].newurl
),
281 "#%d (unknown): got %d and %d with '%s' (expected '!=0' and %d with '%s')\n",
282 i
, res
, len
, buffer
, ParseURL_table
[i
].len
, ParseURL_table
[i
].newurl
);
286 /* ################ */
288 static void test_ParseURLFromOutsideSourceW(void)
290 WCHAR urlW
[INTERNET_MAX_URL_LENGTH
];
291 WCHAR bufferW
[INTERNET_MAX_URL_LENGTH
];
292 CHAR bufferA
[INTERNET_MAX_URL_LENGTH
];
298 if (!pParseURLFromOutsideSourceW
) {
299 skip("ParseURLFromOutsideSourceW not found\n");
302 MultiByteToWideChar(CP_ACP
, 0, ParseURL_table
[0].url
, -1, urlW
, INTERNET_MAX_URL_LENGTH
);
304 memset(bufferA
, '#', sizeof(bufferA
)-1);
305 bufferA
[sizeof(bufferA
) - 1] = '\0';
306 MultiByteToWideChar(CP_ACP
, 0, bufferA
, -1, bufferW
, INTERNET_MAX_URL_LENGTH
);
308 /* len is in characters */
309 len
= sizeof(bufferW
)/sizeof(bufferW
[0]);
311 res
= pParseURLFromOutsideSourceW(urlW
, bufferW
, &len
, &dummy
);
312 WideCharToMultiByte(CP_ACP
, 0, bufferW
, -1, bufferA
, sizeof(bufferA
), NULL
, NULL
);
313 ok( res
!= 0 && len
== ParseURL_table
[0].len
&&
314 !lstrcmpA(bufferA
, ParseURL_table
[0].newurl
),
315 "got %d and %d with '%s' (expected '!=0' and %d with '%s')\n",
316 res
, len
, bufferA
, ParseURL_table
[0].len
, ParseURL_table
[0].newurl
);
321 memset(bufferA
, '#', sizeof(bufferA
)-1);
322 bufferA
[sizeof(bufferA
) - 1] = '\0';
323 MultiByteToWideChar(CP_ACP
, 0, bufferA
, -1, bufferW
, INTERNET_MAX_URL_LENGTH
);
326 res
= pParseURLFromOutsideSourceW(urlW
, bufferW
, &len
, &dummy
);
327 WideCharToMultiByte(CP_ACP
, 0, bufferW
, -1, bufferA
, sizeof(bufferA
), NULL
, NULL
);
328 /* len does not include the terminating 0, when buffer is large enough */
329 ok( res
!= 0 && len
== ParseURL_table
[0].len
&&
330 !lstrcmpA(bufferA
, ParseURL_table
[0].newurl
),
331 "+1: got %d and %d with '%s' (expected '!=0' and %d with '%s')\n",
332 res
, len
, bufferA
, ParseURL_table
[0].len
, ParseURL_table
[0].newurl
);
336 res
= pParseURLFromOutsideSourceW(urlW
, bufferW
, &len
, &dummy
);
337 /* len includes the terminating 0, when the buffer is too small */
338 ok( res
== 0 && len
== ParseURL_table
[0].len
+ 1,
339 "==: got %d and %d (expected '0' and %d)\n",
340 res
, len
, ParseURL_table
[0].len
+ 1);
344 res
= pParseURLFromOutsideSourceW(urlW
, bufferW
, &len
, &dummy
);
345 /* len includes the terminating 0 on XP SP1 and before, when the buffer is too small */
346 ok( res
== 0 && (len
== ParseURL_table
[0].len
|| len
== ParseURL_table
[0].len
+ 1),
347 "-1: got %d and %d (expected '0' and %d or %d)\n",
348 res
, len
, ParseURL_table
[0].len
, ParseURL_table
[0].len
+ 1);
352 /* ################ */
357 test_URLSubRegQueryA();
358 test_ParseURLFromOutsideSourceA();
359 test_ParseURLFromOutsideSourceW();
360 FreeLibrary(hshdocvw
);