ReactOS  0.4.15-dev-499-g1f31905
shdocvw.c
Go to the documentation of this file.
1 /*
2  * Unit tests for misc shdocvw functions
3  *
4  * Copyright 2008 Detlef Riekenberg
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 
21 
22 #include <stdarg.h>
23 
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winreg.h"
27 #include "wininet.h"
28 #include "winnls.h"
29 
30 #include "wine/test.h"
31 
32 /* ################ */
33 
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);
38 
39 static const char appdata[] = "AppData";
40 static const char common_appdata[] = "Common AppData";
41 static const char default_page_url[] = "Default_Page_URL";
42 static const char does_not_exist[] = "does_not_exist";
43 static const char regpath_iemain[] = "Software\\Microsoft\\Internet Explorer\\Main";
44 static const char regpath_shellfolders[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
45 static const char start_page[] = "Start Page";
46 
47 /* ################ */
48 
49 static const struct {
50  const char *url;
51  const char *newurl;
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}
68 
69 };
70 
71 /* ################ */
72 
73 static void init_functions(void)
74 {
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);
79 }
80 
81 /* ################ */
82 
83 static void test_URLSubRegQueryA(void)
84 {
86  HRESULT hr;
87  DWORD used;
88  DWORD len;
89 
90  if (!pURLSubRegQueryA) {
91  skip("URLSubRegQueryA not found\n");
92  return;
93  }
94 
95  memset(buffer, '#', sizeof(buffer)-1);
96  buffer[sizeof(buffer)-1] = '\0';
97  /* called by inetcpl.cpl */
99  ok(hr == E_FAIL || hr == S_OK, "got 0x%x (expected E_FAIL or S_OK)\n", hr);
100 
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);
108 
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);
117 
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);
125 
126  /* no space for the complete result: truncate another char */
127  if (len > 1) {
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);
134  }
135 
136  /* only space for the terminating 0: function still succeeded */
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);
143 
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);
150  ok( (hr == S_OK) &&
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",
153  hr, used);
154 
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);
158 
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);
162 
163  /* this value does not exist */
164  memset(buffer, '#', sizeof(buffer)-1);
165  buffer[sizeof(buffer)-1] = '\0';
167  /* random bytes are copied to the buffer */
168  ok((hr == E_FAIL), "got 0x%x (expected E_FAIL)\n", hr);
169 
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';
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);
177 
178  /* the function works for HKCU and HKLM */
179  memset(buffer, '#', sizeof(buffer)-1);
180  buffer[sizeof(buffer)-1] = '\0';
182  used = lstrlenA(buffer);
183  ok(hr == S_OK, "got 0x%x and %d (expected S_OK)\n", hr, used);
184 
185  memset(buffer, '#', sizeof(buffer)-1);
186  buffer[sizeof(buffer)-1] = '\0';
188  used = lstrlenA(buffer);
189  ok(hr == S_OK, "got 0x%x and %d (expected S_OK)\n", hr, used);
190 
191  /* todo: what does the last parameter mean? */
192 }
193 
194 /* ################ */
195 
197 {
199  DWORD dummy;
200  DWORD maxlen;
201  DWORD len;
202  DWORD res;
203  int i;
204 
205  if (!pParseURLFromOutsideSourceA) {
206  skip("ParseURLFromOutsideSourceA not found\n");
207  return;
208  }
209 
210  for(i = 0; i < ARRAY_SIZE(ParseURL_table); i++) {
211  memset(buffer, '#', sizeof(buffer)-1);
212  buffer[sizeof(buffer)-1] = '\0';
213  len = sizeof(buffer);
214  dummy = 0;
215  /* on success, string size including terminating 0 is returned for ansi version */
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 == (ParseURL_table[i].len+1) && len == ParseURL_table[i].len &&
220  "#%d: got %d and %d with '%s' (expected %d and %d with '%s')\n",
222 
223 
224  /* use the size test only for the first examples */
225  if (i > 4) continue;
226 
227  maxlen = len;
228 
229  memset(buffer, '#', sizeof(buffer)-1);
230  buffer[sizeof(buffer)-1] = '\0';
231  len = maxlen + 1;
232  dummy = 0;
233  res = pParseURLFromOutsideSourceA(ParseURL_table[i].url, buffer, &len, &dummy);
234  ok( res != 0 && len == ParseURL_table[i].len &&
236  "#%d (+1): got %d and %d with '%s' (expected '!=0' and %d with '%s')\n",
238 
239  memset(buffer, '#', sizeof(buffer)-1);
240  buffer[sizeof(buffer)-1] = '\0';
241  len = maxlen;
242  dummy = 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);
248 
249  memset(buffer, '#', sizeof(buffer)-1);
250  buffer[sizeof(buffer)-1] = '\0';
251  len = maxlen-1;
252  dummy = 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",
258 
259  memset(buffer, '#', sizeof(buffer)-1);
260  buffer[sizeof(buffer)-1] = '\0';
261  len = maxlen+1;
262  dummy = 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);
268 
269  if (0) {
270  /* that test crash on native shdocvw */
271  pParseURLFromOutsideSourceA(ParseURL_table[i].url, buffer, NULL, &dummy);
272  }
273 
274  memset(buffer, '#', sizeof(buffer)-1);
275  buffer[sizeof(buffer)-1] = '\0';
276  len = maxlen+1;
277  dummy = 0;
278  res = pParseURLFromOutsideSourceA(ParseURL_table[i].url, buffer, &len, NULL);
279  ok( res != 0 && len == ParseURL_table[i].len &&
281  "#%d (unknown): got %d and %d with '%s' (expected '!=0' and %d with '%s')\n",
283  }
284 }
285 
286 /* ################ */
287 
289 {
292  CHAR bufferA[INTERNET_MAX_URL_LENGTH];
293  DWORD maxlen;
294  DWORD dummy;
295  DWORD len;
296  DWORD res;
297 
298  if (!pParseURLFromOutsideSourceW) {
299  skip("ParseURLFromOutsideSourceW not found\n");
300  return;
301  }
303 
304  memset(bufferA, '#', sizeof(bufferA)-1);
305  bufferA[sizeof(bufferA) - 1] = '\0';
306  MultiByteToWideChar(CP_ACP, 0, bufferA, -1, bufferW, INTERNET_MAX_URL_LENGTH);
307 
308  /* len is in characters */
309  len = ARRAY_SIZE(bufferW);
310  dummy = 0;
311  /* on success, 1 is returned for unicode version */
312  res = pParseURLFromOutsideSourceW(urlW, bufferW, &len, &dummy);
313  WideCharToMultiByte(CP_ACP, 0, bufferW, -1, bufferA, sizeof(bufferA), NULL, NULL);
314  ok( res == 1 && len == ParseURL_table[0].len &&
315  !lstrcmpA(bufferA, ParseURL_table[0].newurl),
316  "got %d and %d with '%s' (expected 1 and %d with '%s')\n",
317  res, len, bufferA, ParseURL_table[0].len, ParseURL_table[0].newurl);
318 
319 
320  maxlen = len;
321 
322  memset(bufferA, '#', sizeof(bufferA)-1);
323  bufferA[sizeof(bufferA) - 1] = '\0';
324  MultiByteToWideChar(CP_ACP, 0, bufferA, -1, bufferW, INTERNET_MAX_URL_LENGTH);
325  len = maxlen+1;
326  dummy = 0;
327  res = pParseURLFromOutsideSourceW(urlW, bufferW, &len, &dummy);
328  WideCharToMultiByte(CP_ACP, 0, bufferW, -1, bufferA, sizeof(bufferA), NULL, NULL);
329  /* len does not include the terminating 0, when buffer is large enough */
330  ok( res != 0 && len == ParseURL_table[0].len &&
331  !lstrcmpA(bufferA, ParseURL_table[0].newurl),
332  "+1: got %d and %d with '%s' (expected '!=0' and %d with '%s')\n",
333  res, len, bufferA, ParseURL_table[0].len, ParseURL_table[0].newurl);
334 
335  len = maxlen;
336  dummy = 0;
337  res = pParseURLFromOutsideSourceW(urlW, bufferW, &len, &dummy);
338  /* len includes the terminating 0, when the buffer is too small */
339  ok( res == 0 && len == ParseURL_table[0].len + 1,
340  "==: got %d and %d (expected '0' and %d)\n",
341  res, len, ParseURL_table[0].len + 1);
342 
343  len = maxlen - 1;
344  dummy = 0;
345  res = pParseURLFromOutsideSourceW(urlW, bufferW, &len, &dummy);
346  /* len includes the terminating 0 on XP SP1 and before, when the buffer is too small */
347  ok( res == 0 && (len == ParseURL_table[0].len || len == ParseURL_table[0].len + 1),
348  "-1: got %d and %d (expected '0' and %d or %d)\n",
349  res, len, ParseURL_table[0].len, ParseURL_table[0].len + 1);
350 
351 }
352 
353 /* ################ */
354 
355 START_TEST(shdocvw)
356 {
357  init_functions();
362 }
static const struct @1670 ParseURL_table[]
static void test_URLSubRegQueryA(void)
Definition: shdocvw.c:83
static const char start_page[]
Definition: shdocvw.c:45
#define WideCharToMultiByte
Definition: compat.h:101
HRESULT hr
Definition: shlfolder.c:183
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
static LPWSTR
Definition: shdocvw.c:37
static DWORD
Definition: shdocvw.c:35
static const char common_appdata[]
Definition: shdocvw.c:40
#define CP_ACP
Definition: compat.h:99
static void init_functions(void)
Definition: shdocvw.c:73
char CHAR
Definition: xmlstorage.h:175
const char * newurl
Definition: shdocvw.c:51
int WINAPI lstrcmpA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:18
GLuint buffer
Definition: glext.h:5915
char * LPSTR
Definition: xmlstorage.h:182
#define E_FAIL
Definition: ddrawi.h:102
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
DWORD len
Definition: shdocvw.c:52
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
smooth NULL
Definition: ftsmooth.c:416
#define INTERNET_MAX_URL_LENGTH
Definition: session.c:1418
static void test_ParseURLFromOutsideSourceW(void)
Definition: shdocvw.c:288
static const char appdata[]
Definition: shdocvw.c:39
static const char does_not_exist[]
Definition: shdocvw.c:42
static const char regpath_iemain[]
Definition: shdocvw.c:43
c used
Definition: write.c:2857
#define FreeLibrary(x)
Definition: compat.h:414
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:78
static LPDWORD
Definition: shdocvw.c:36
static LPCSTR
Definition: shdocvw.c:35
#define WINAPI
Definition: msvc.h:6
unsigned long DWORD
Definition: ntddk_ex.h:95
START_TEST(shdocvw)
Definition: shdocvw.c:243
static const char default_page_url[]
Definition: shdocvw.c:41
const char * url
Definition: shdocvw.c:50
GLenum GLsizei len
Definition: glext.h:6722
#define broken(x)
Definition: _sntprintf.h:21
#define S_OK
Definition: intsafe.h:59
static HMODULE hshdocvw
Definition: shdocvw.c:34
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
static const char regpath_shellfolders[]
Definition: shdocvw.c:44
static LPVOID
Definition: shdocvw.c:35
#define ARRAY_SIZE(a)
Definition: main.h:24
unsigned char dummy
Definition: maze.c:118
#define ok(value,...)
Definition: atltest.h:57
static void test_ParseURLFromOutsideSourceA(void)
Definition: shdocvw.c:196
static LPSTR
Definition: shdocvw.c:36
#define MultiByteToWideChar
Definition: compat.h:100
#define skip(...)
Definition: atltest.h:64
GLuint res
Definition: glext.h:9613
#define GetProcAddress(x, y)
Definition: compat.h:419
#define memset(x, y, z)
Definition: compat.h:39
#define REG_DWORD
Definition: sdbapi.c:596
#define REG_SZ
Definition: layer.c:22
static HRESULT(WINAPI *pURLSubRegQueryA)(LPCSTR