4 * Copyright 2008 Robert Shearman for CodeWeavers
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 #define TEST_URL "http://urlcachetest.winehq.org/index.html"
33 #define TEST_URL1 "Visited: user@http://urlcachetest.winehq.org/index.html"
35 static BOOL (WINAPI
*pDeleteUrlCacheEntryA
)(LPCSTR
);
36 static BOOL (WINAPI
*pUnlockUrlCacheEntryFileA
)(LPCSTR
,DWORD
);
38 static char filenameA
[MAX_PATH
+ 1];
39 static char filenameA1
[MAX_PATH
+ 1];
41 static void check_cache_entry_infoA(const char *returnedfrom
, LPINTERNET_CACHE_ENTRY_INFO lpCacheEntryInfo
)
43 ok(lpCacheEntryInfo
->dwStructSize
== sizeof(*lpCacheEntryInfo
), "%s: dwStructSize was %d\n", returnedfrom
, lpCacheEntryInfo
->dwStructSize
);
44 ok(!strcmp(lpCacheEntryInfo
->lpszSourceUrlName
, TEST_URL
), "%s: lpszSourceUrlName should be %s instead of %s\n", returnedfrom
, TEST_URL
, lpCacheEntryInfo
->lpszSourceUrlName
);
45 ok(!strcmp(lpCacheEntryInfo
->lpszLocalFileName
, filenameA
), "%s: lpszLocalFileName should be %s instead of %s\n", returnedfrom
, filenameA
, lpCacheEntryInfo
->lpszLocalFileName
);
46 ok(!strcmp(lpCacheEntryInfo
->lpszFileExtension
, "html"), "%s: lpszFileExtension should be html instead of %s\n", returnedfrom
, lpCacheEntryInfo
->lpszFileExtension
);
49 static void test_find_url_cache_entriesA(void)
54 DWORD cbCacheEntryInfo
;
55 DWORD cbCacheEntryInfoSaved
;
56 LPINTERNET_CACHE_ENTRY_INFO lpCacheEntryInfo
;
59 SetLastError(0xdeadbeef);
60 hEnumHandle
= FindFirstUrlCacheEntry(NULL
, NULL
, &cbCacheEntryInfo
);
61 ok(!hEnumHandle
, "FindFirstUrlCacheEntry should have failed\n");
62 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "FindFirstUrlCacheEntry should have set last error to ERROR_INSUFFICIENT_BUFFER instead of %d\n", GetLastError());
63 lpCacheEntryInfo
= HeapAlloc(GetProcessHeap(), 0, cbCacheEntryInfo
* sizeof(char));
64 cbCacheEntryInfoSaved
= cbCacheEntryInfo
;
65 hEnumHandle
= FindFirstUrlCacheEntry(NULL
, lpCacheEntryInfo
, &cbCacheEntryInfo
);
66 ok(hEnumHandle
!= NULL
, "FindFirstUrlCacheEntry failed with error %d\n", GetLastError());
69 if (!strcmp(lpCacheEntryInfo
->lpszSourceUrlName
, TEST_URL
))
74 SetLastError(0xdeadbeef);
75 cbCacheEntryInfo
= cbCacheEntryInfoSaved
;
76 ret
= FindNextUrlCacheEntry(hEnumHandle
, lpCacheEntryInfo
, &cbCacheEntryInfo
);
79 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
81 lpCacheEntryInfo
= HeapReAlloc(GetProcessHeap(), 0, lpCacheEntryInfo
, cbCacheEntryInfo
);
82 cbCacheEntryInfoSaved
= cbCacheEntryInfo
;
83 ret
= FindNextUrlCacheEntry(hEnumHandle
, lpCacheEntryInfo
, &cbCacheEntryInfo
);
86 ok(ret
, "FindNextUrlCacheEntry failed with error %d\n", GetLastError());
90 ok(found
, "committed url cache entry not found during enumeration\n");
92 ret
= FindCloseUrlCache(hEnumHandle
);
93 ok(ret
, "FindCloseUrlCache failed with error %d\n", GetLastError());
96 static void test_GetUrlCacheEntryInfoExA(void)
99 DWORD cbCacheEntryInfo
, cbRedirectUrl
;
100 LPINTERNET_CACHE_ENTRY_INFO lpCacheEntryInfo
;
102 SetLastError(0xdeadbeef);
103 ret
= GetUrlCacheEntryInfoEx(NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
104 ok(!ret
, "GetUrlCacheEntryInfoEx with NULL URL and NULL args should have failed\n");
105 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
106 "GetUrlCacheEntryInfoEx with NULL URL and NULL args should have set last error to ERROR_INVALID_PARAMETER instead of %d\n", GetLastError());
108 cbCacheEntryInfo
= sizeof(INTERNET_CACHE_ENTRY_INFO
);
109 SetLastError(0xdeadbeef);
110 ret
= GetUrlCacheEntryInfoEx("", NULL
, &cbCacheEntryInfo
, NULL
, NULL
, NULL
, 0);
111 ok(!ret
, "GetUrlCacheEntryInfoEx with zero-length buffer should fail\n");
112 ok(GetLastError() == ERROR_FILE_NOT_FOUND
,
113 "GetUrlCacheEntryInfoEx should have set last error to ERROR_FILE_NOT_FOUND instead of %d\n", GetLastError());
115 ret
= GetUrlCacheEntryInfoEx(TEST_URL
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
116 ok(ret
, "GetUrlCacheEntryInfoEx with NULL args failed with error %d\n", GetLastError());
118 cbCacheEntryInfo
= 0;
119 SetLastError(0xdeadbeef);
120 ret
= GetUrlCacheEntryInfoEx(TEST_URL
, NULL
, &cbCacheEntryInfo
, NULL
, NULL
, NULL
, 0);
121 ok(!ret
, "GetUrlCacheEntryInfoEx with zero-length buffer should fail\n");
122 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
123 "GetUrlCacheEntryInfoEx should have set last error to ERROR_INSUFFICIENT_BUFFER instead of %d\n", GetLastError());
125 lpCacheEntryInfo
= HeapAlloc(GetProcessHeap(), 0, cbCacheEntryInfo
);
127 SetLastError(0xdeadbeef);
128 ret
= GetUrlCacheEntryInfoEx(TEST_URL
, lpCacheEntryInfo
, &cbCacheEntryInfo
, NULL
, NULL
, NULL
, 0x200);
129 ok(!ret
, "GetUrlCacheEntryInfoEx succeeded\n");
130 ok(GetLastError() == ERROR_FILE_NOT_FOUND
,
131 "GetUrlCacheEntryInfoEx should have set last error to ERROR_FILE_NOT_FOUND instead of %d\n", GetLastError());
133 ret
= GetUrlCacheEntryInfoEx(TEST_URL
, lpCacheEntryInfo
, &cbCacheEntryInfo
, NULL
, NULL
, NULL
, 0);
134 ok(ret
, "GetUrlCacheEntryInfoEx failed with error %d\n", GetLastError());
136 check_cache_entry_infoA("GetUrlCacheEntryInfoEx", lpCacheEntryInfo
);
138 cbCacheEntryInfo
= 100000;
139 SetLastError(0xdeadbeef);
140 ret
= GetUrlCacheEntryInfoEx(TEST_URL
, NULL
, &cbCacheEntryInfo
, NULL
, NULL
, NULL
, 0);
141 ok(!ret
, "GetUrlCacheEntryInfoEx with zero-length buffer should fail\n");
142 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "GetUrlCacheEntryInfoEx should have set last error to ERROR_INSUFFICIENT_BUFFER instead of %d\n", GetLastError());
144 HeapFree(GetProcessHeap(), 0, lpCacheEntryInfo
);
146 /* Querying the redirect URL fails with ERROR_INVALID_PARAMETER */
147 SetLastError(0xdeadbeef);
148 ret
= GetUrlCacheEntryInfoEx(TEST_URL
, NULL
, NULL
, NULL
, &cbRedirectUrl
, NULL
, 0);
149 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
150 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
151 SetLastError(0xdeadbeef);
152 ret
= GetUrlCacheEntryInfoEx(TEST_URL
, NULL
, &cbCacheEntryInfo
, NULL
, &cbRedirectUrl
, NULL
, 0);
153 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
154 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
157 static void test_RetrieveUrlCacheEntryA(void)
160 DWORD cbCacheEntryInfo
;
162 cbCacheEntryInfo
= 0;
163 SetLastError(0xdeadbeef);
164 ret
= RetrieveUrlCacheEntryFile(NULL
, NULL
, &cbCacheEntryInfo
, 0);
165 ok(!ret
, "RetrieveUrlCacheEntryFile should have failed\n");
166 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "RetrieveUrlCacheEntryFile should have set last error to ERROR_INVALID_PARAMETER instead of %d\n", GetLastError());
170 /* Crashes on Win9x, NT4 and W2K */
171 SetLastError(0xdeadbeef);
172 ret
= RetrieveUrlCacheEntryFile(TEST_URL
, NULL
, NULL
, 0);
173 ok(!ret
, "RetrieveUrlCacheEntryFile should have failed\n");
174 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "RetrieveUrlCacheEntryFile should have set last error to ERROR_INVALID_PARAMETER instead of %d\n", GetLastError());
177 SetLastError(0xdeadbeef);
178 cbCacheEntryInfo
= 100000;
179 ret
= RetrieveUrlCacheEntryFile(NULL
, NULL
, &cbCacheEntryInfo
, 0);
180 ok(!ret
, "RetrieveUrlCacheEntryFile should have failed\n");
181 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "RetrieveUrlCacheEntryFile should have set last error to ERROR_INVALID_PARAMETER instead of %d\n", GetLastError());
184 static void test_IsUrlCacheEntryExpiredA(void)
186 static const char uncached_url
[] =
187 "What's the airspeed velocity of an unladen swallow?";
191 LPINTERNET_CACHE_ENTRY_INFO info
;
192 ULARGE_INTEGER exp_time
;
194 /* The function returns TRUE when the output time is NULL or the tested URL
197 ret
= IsUrlCacheEntryExpiredA(NULL
, 0, NULL
);
198 ok(ret
, "expected TRUE\n");
199 ft
.dwLowDateTime
= 0xdeadbeef;
200 ft
.dwHighDateTime
= 0xbaadf00d;
201 ret
= IsUrlCacheEntryExpiredA(NULL
, 0, &ft
);
202 ok(ret
, "expected TRUE\n");
203 ok(ft
.dwLowDateTime
== 0xdeadbeef && ft
.dwHighDateTime
== 0xbaadf00d,
204 "expected time to be unchanged, got (%u,%u)\n",
205 ft
.dwLowDateTime
, ft
.dwHighDateTime
);
206 ret
= IsUrlCacheEntryExpiredA(TEST_URL
, 0, NULL
);
207 ok(ret
, "expected TRUE\n");
209 /* The return value should indicate whether the URL is expired,
210 * and the filetime indicates the last modified time, but a cache entry
211 * with a zero expire time is "not expired".
213 ft
.dwLowDateTime
= 0xdeadbeef;
214 ft
.dwHighDateTime
= 0xbaadf00d;
215 ret
= IsUrlCacheEntryExpiredA(TEST_URL
, 0, &ft
);
216 ok(!ret
, "expected FALSE\n");
217 ok(!ft
.dwLowDateTime
&& !ft
.dwHighDateTime
,
218 "expected time (0,0), got (%u,%u)\n",
219 ft
.dwLowDateTime
, ft
.dwHighDateTime
);
221 /* Same behavior with bogus flags. */
222 ft
.dwLowDateTime
= 0xdeadbeef;
223 ft
.dwHighDateTime
= 0xbaadf00d;
224 ret
= IsUrlCacheEntryExpiredA(TEST_URL
, 0xffffffff, &ft
);
225 ok(!ret
, "expected FALSE\n");
226 ok(!ft
.dwLowDateTime
&& !ft
.dwHighDateTime
,
227 "expected time (0,0), got (%u,%u)\n",
228 ft
.dwLowDateTime
, ft
.dwHighDateTime
);
230 /* Set the expire time to a point in the past.. */
231 ret
= GetUrlCacheEntryInfo(TEST_URL
, NULL
, &size
);
232 ok(!ret
, "GetUrlCacheEntryInfo should have failed\n");
233 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
234 "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
235 info
= HeapAlloc(GetProcessHeap(), 0, size
);
236 ret
= GetUrlCacheEntryInfo(TEST_URL
, info
, &size
);
237 GetSystemTimeAsFileTime(&info
->ExpireTime
);
238 exp_time
.u
.LowPart
= info
->ExpireTime
.dwLowDateTime
;
239 exp_time
.u
.HighPart
= info
->ExpireTime
.dwHighDateTime
;
240 exp_time
.QuadPart
-= 10 * 60 * (ULONGLONG
)10000000;
241 info
->ExpireTime
.dwLowDateTime
= exp_time
.u
.LowPart
;
242 info
->ExpireTime
.dwHighDateTime
= exp_time
.u
.HighPart
;
243 ret
= SetUrlCacheEntryInfo(TEST_URL
, info
, CACHE_ENTRY_EXPTIME_FC
);
244 ok(ret
, "SetUrlCacheEntryInfo failed: %d\n", GetLastError());
245 ft
.dwLowDateTime
= 0xdeadbeef;
246 ft
.dwHighDateTime
= 0xbaadf00d;
247 /* and the entry should be expired. */
248 ret
= IsUrlCacheEntryExpiredA(TEST_URL
, 0, &ft
);
249 ok(ret
, "expected TRUE\n");
250 /* The modified time returned is 0. */
251 ok(!ft
.dwLowDateTime
&& !ft
.dwHighDateTime
,
252 "expected time (0,0), got (%u,%u)\n",
253 ft
.dwLowDateTime
, ft
.dwHighDateTime
);
254 /* Set the expire time to a point in the future.. */
255 exp_time
.QuadPart
+= 20 * 60 * (ULONGLONG
)10000000;
256 info
->ExpireTime
.dwLowDateTime
= exp_time
.u
.LowPart
;
257 info
->ExpireTime
.dwHighDateTime
= exp_time
.u
.HighPart
;
258 ret
= SetUrlCacheEntryInfo(TEST_URL
, info
, CACHE_ENTRY_EXPTIME_FC
);
259 ok(ret
, "SetUrlCacheEntryInfo failed: %d\n", GetLastError());
260 ft
.dwLowDateTime
= 0xdeadbeef;
261 ft
.dwHighDateTime
= 0xbaadf00d;
262 /* and the entry should no longer be expired. */
263 ret
= IsUrlCacheEntryExpiredA(TEST_URL
, 0, &ft
);
264 ok(!ret
, "expected FALSE\n");
265 /* The modified time returned is still 0. */
266 ok(!ft
.dwLowDateTime
&& !ft
.dwHighDateTime
,
267 "expected time (0,0), got (%u,%u)\n",
268 ft
.dwLowDateTime
, ft
.dwHighDateTime
);
269 /* Set the modified time... */
270 GetSystemTimeAsFileTime(&info
->LastModifiedTime
);
271 ret
= SetUrlCacheEntryInfo(TEST_URL
, info
, CACHE_ENTRY_MODTIME_FC
);
272 ok(ret
, "SetUrlCacheEntryInfo failed: %d\n", GetLastError());
273 /* and the entry should still be unexpired.. */
274 ret
= IsUrlCacheEntryExpiredA(TEST_URL
, 0, &ft
);
275 ok(!ret
, "expected FALSE\n");
276 /* but the modified time returned is the last modified time just set. */
277 ok(ft
.dwLowDateTime
== info
->LastModifiedTime
.dwLowDateTime
&&
278 ft
.dwHighDateTime
== info
->LastModifiedTime
.dwHighDateTime
,
279 "expected time (%u,%u), got (%u,%u)\n",
280 info
->LastModifiedTime
.dwLowDateTime
,
281 info
->LastModifiedTime
.dwHighDateTime
,
282 ft
.dwLowDateTime
, ft
.dwHighDateTime
);
283 HeapFree(GetProcessHeap(), 0, info
);
285 /* An uncached URL is implicitly expired, but with unknown time. */
286 ft
.dwLowDateTime
= 0xdeadbeef;
287 ft
.dwHighDateTime
= 0xbaadf00d;
288 ret
= IsUrlCacheEntryExpiredA(uncached_url
, 0, &ft
);
289 ok(ret
, "expected TRUE\n");
290 ok(!ft
.dwLowDateTime
&& !ft
.dwHighDateTime
,
291 "expected time (0,0), got (%u,%u)\n",
292 ft
.dwLowDateTime
, ft
.dwHighDateTime
);
295 static void _check_file_exists(LONG l
, LPCSTR filename
)
299 file
= CreateFileA(filename
, GENERIC_READ
, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
300 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
301 ok_(__FILE__
,l
)(file
!= INVALID_HANDLE_VALUE
,
302 "expected file to exist, CreateFile failed with error %d\n",
307 #define check_file_exists(f) _check_file_exists(__LINE__, f)
309 static void _check_file_not_exists(LONG l
, LPCSTR filename
)
313 file
= CreateFileA(filename
, GENERIC_READ
, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
314 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
315 ok_(__FILE__
,l
)(file
== INVALID_HANDLE_VALUE
,
316 "expected file not to exist\n");
317 if (file
!= INVALID_HANDLE_VALUE
)
321 #define check_file_not_exists(f) _check_file_not_exists(__LINE__, f)
323 static void create_and_write_file(LPCSTR filename
, void *data
, DWORD len
)
329 file
= CreateFileA(filename
, GENERIC_WRITE
,
330 FILE_SHARE_READ
|FILE_SHARE_WRITE
, NULL
, CREATE_ALWAYS
,
331 FILE_ATTRIBUTE_NORMAL
, NULL
);
332 ok(file
!= INVALID_HANDLE_VALUE
, "CreateFileA failed with error %d\n", GetLastError());
334 ret
= WriteFile(file
, data
, len
, &written
, NULL
);
335 ok(ret
, "WriteFile failed with error %d\n", GetLastError());
340 static void test_urlcacheA(void)
342 static char ok_header
[] = "HTTP/1.0 200 OK\r\n\r\n";
346 LPINTERNET_CACHE_ENTRY_INFO lpCacheEntryInfo
;
347 DWORD cbCacheEntryInfo
;
348 static const FILETIME filetime_zero
;
351 ret
= CreateUrlCacheEntry(TEST_URL
, 0, "html", filenameA
, 0);
352 ok(ret
, "CreateUrlCacheEntry failed with error %d\n", GetLastError());
354 ret
= CreateUrlCacheEntry(TEST_URL
, 0, "html", filenameA1
, 0);
355 ok(ret
, "CreateUrlCacheEntry failed with error %d\n", GetLastError());
357 ok(lstrcmpiA(filenameA
, filenameA1
), "expected a different file name\n");
359 create_and_write_file(filenameA
, &zero_byte
, sizeof(zero_byte
));
361 ret
= CommitUrlCacheEntry(TEST_URL1
, NULL
, filetime_zero
, filetime_zero
, NORMAL_CACHE_ENTRY
|URLHISTORY_CACHE_ENTRY
, NULL
, 0, NULL
, NULL
);
362 ok(ret
, "CommitUrlCacheEntry failed with error %d\n", GetLastError());
363 cbCacheEntryInfo
= 0;
364 ret
= GetUrlCacheEntryInfo(TEST_URL1
, NULL
, &cbCacheEntryInfo
);
365 ok(!ret
, "GetUrlCacheEntryInfo should have failed\n");
366 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
367 "GetUrlCacheEntryInfo should have set last error to ERROR_INSUFFICIENT_BUFFER instead of %d\n", GetLastError());
368 lpCacheEntryInfo
= HeapAlloc(GetProcessHeap(), 0, cbCacheEntryInfo
);
369 ret
= GetUrlCacheEntryInfo(TEST_URL1
, lpCacheEntryInfo
, &cbCacheEntryInfo
);
370 ok(ret
, "GetUrlCacheEntryInfo failed with error %d\n", GetLastError());
371 ok(!memcmp(&lpCacheEntryInfo
->ExpireTime
, &filetime_zero
, sizeof(FILETIME
)),
372 "expected zero ExpireTime\n");
373 ok(!memcmp(&lpCacheEntryInfo
->LastModifiedTime
, &filetime_zero
, sizeof(FILETIME
)),
374 "expected zero LastModifiedTime\n");
375 ok(lpCacheEntryInfo
->CacheEntryType
== (NORMAL_CACHE_ENTRY
|URLHISTORY_CACHE_ENTRY
) ||
376 broken(lpCacheEntryInfo
->CacheEntryType
== NORMAL_CACHE_ENTRY
/* NT4/W2k */),
377 "expected type NORMAL_CACHE_ENTRY|URLHISTORY_CACHE_ENTRY, got %08x\n",
378 lpCacheEntryInfo
->CacheEntryType
);
379 ok(!U(*lpCacheEntryInfo
).dwExemptDelta
, "expected dwExemptDelta 0, got %d\n",
380 U(*lpCacheEntryInfo
).dwExemptDelta
);
381 HeapFree(GetProcessHeap(), 0, lpCacheEntryInfo
);
383 /* A subsequent commit with a different time/type doesn't change the type */
384 GetSystemTimeAsFileTime(&now
);
385 ret
= CommitUrlCacheEntry(TEST_URL1
, NULL
, now
, now
, NORMAL_CACHE_ENTRY
,
386 (LPBYTE
)ok_header
, strlen(ok_header
), NULL
, NULL
);
387 ok(ret
, "CommitUrlCacheEntry failed with error %d\n", GetLastError());
388 cbCacheEntryInfo
= 0;
389 ret
= GetUrlCacheEntryInfo(TEST_URL1
, NULL
, &cbCacheEntryInfo
);
390 ok(!ret
, "GetUrlCacheEntryInfo should have failed\n");
391 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
392 "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
393 lpCacheEntryInfo
= HeapAlloc(GetProcessHeap(), 0, cbCacheEntryInfo
);
394 ret
= GetUrlCacheEntryInfo(TEST_URL1
, lpCacheEntryInfo
, &cbCacheEntryInfo
);
395 ok(ret
, "GetUrlCacheEntryInfo failed with error %d\n", GetLastError());
396 /* but it does change the time.. */
398 ok(memcmp(&lpCacheEntryInfo
->ExpireTime
, &filetime_zero
, sizeof(FILETIME
)),
399 "expected positive ExpireTime\n");
401 ok(memcmp(&lpCacheEntryInfo
->LastModifiedTime
, &filetime_zero
, sizeof(FILETIME
)),
402 "expected positive LastModifiedTime\n");
403 ok(lpCacheEntryInfo
->CacheEntryType
== (NORMAL_CACHE_ENTRY
|URLHISTORY_CACHE_ENTRY
) ||
404 broken(lpCacheEntryInfo
->CacheEntryType
== NORMAL_CACHE_ENTRY
/* NT4/W2k */),
405 "expected type NORMAL_CACHE_ENTRY|URLHISTORY_CACHE_ENTRY, got %08x\n",
406 lpCacheEntryInfo
->CacheEntryType
);
407 /* and set the headers. */
409 ok(lpCacheEntryInfo
->dwHeaderInfoSize
== 19,
410 "expected headers size 19, got %d\n",
411 lpCacheEntryInfo
->dwHeaderInfoSize
);
412 HeapFree(GetProcessHeap(), 0, lpCacheEntryInfo
);
414 ret
= CommitUrlCacheEntry(TEST_URL
, filenameA
, filetime_zero
, filetime_zero
, NORMAL_CACHE_ENTRY
, NULL
, 0, "html", NULL
);
415 ok(ret
, "CommitUrlCacheEntry failed with error %d\n", GetLastError());
417 cbCacheEntryInfo
= 0;
418 SetLastError(0xdeadbeef);
419 ret
= RetrieveUrlCacheEntryFile(TEST_URL
, NULL
, &cbCacheEntryInfo
, 0);
420 ok(!ret
, "RetrieveUrlCacheEntryFile should have failed\n");
421 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
422 "RetrieveUrlCacheEntryFile should have set last error to ERROR_INSUFFICIENT_BUFFER instead of %d\n", GetLastError());
424 lpCacheEntryInfo
= HeapAlloc(GetProcessHeap(), 0, cbCacheEntryInfo
);
425 ret
= RetrieveUrlCacheEntryFile(TEST_URL
, lpCacheEntryInfo
, &cbCacheEntryInfo
, 0);
426 ok(ret
, "RetrieveUrlCacheEntryFile failed with error %d\n", GetLastError());
428 check_cache_entry_infoA("RetrieveUrlCacheEntryFile", lpCacheEntryInfo
);
430 HeapFree(GetProcessHeap(), 0, lpCacheEntryInfo
);
432 cbCacheEntryInfo
= 0;
433 SetLastError(0xdeadbeef);
434 ret
= RetrieveUrlCacheEntryFile(TEST_URL1
, NULL
, &cbCacheEntryInfo
, 0);
435 ok(!ret
, "RetrieveUrlCacheEntryFile should have failed\n");
436 ok(GetLastError() == ERROR_INVALID_DATA
,
437 "RetrieveUrlCacheEntryFile should have set last error to ERROR_INVALID_DATA instead of %d\n", GetLastError());
439 if (pUnlockUrlCacheEntryFileA
)
441 ret
= pUnlockUrlCacheEntryFileA(TEST_URL
, 0);
442 ok(ret
, "UnlockUrlCacheEntryFileA failed with error %d\n", GetLastError());
445 /* test Find*UrlCacheEntry functions */
446 test_find_url_cache_entriesA();
448 test_GetUrlCacheEntryInfoExA();
449 test_RetrieveUrlCacheEntryA();
450 test_IsUrlCacheEntryExpiredA();
452 if (pDeleteUrlCacheEntryA
)
454 ret
= pDeleteUrlCacheEntryA(TEST_URL
);
455 ok(ret
, "DeleteUrlCacheEntryA failed with error %d\n", GetLastError());
456 ret
= pDeleteUrlCacheEntryA(TEST_URL1
);
457 ok(ret
, "DeleteUrlCacheEntryA failed with error %d\n", GetLastError());
460 SetLastError(0xdeadbeef);
461 ret
= DeleteFile(filenameA
);
463 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
, "local file should no longer exist\n");
465 /* Creating two entries with the same URL */
466 ret
= CreateUrlCacheEntry(TEST_URL
, 0, "html", filenameA
, 0);
467 ok(ret
, "CreateUrlCacheEntry failed with error %d\n", GetLastError());
469 ret
= CreateUrlCacheEntry(TEST_URL
, 0, "html", filenameA1
, 0);
470 ok(ret
, "CreateUrlCacheEntry failed with error %d\n", GetLastError());
472 ok(lstrcmpiA(filenameA
, filenameA1
), "expected a different file name\n");
474 create_and_write_file(filenameA
, &zero_byte
, sizeof(zero_byte
));
475 create_and_write_file(filenameA1
, &zero_byte
, sizeof(zero_byte
));
476 check_file_exists(filenameA
);
477 check_file_exists(filenameA1
);
479 ret
= CommitUrlCacheEntry(TEST_URL
, filenameA
, filetime_zero
,
480 filetime_zero
, NORMAL_CACHE_ENTRY
, (LPBYTE
)ok_header
,
481 strlen(ok_header
), "html", NULL
);
482 ok(ret
, "CommitUrlCacheEntry failed with error %d\n", GetLastError());
483 check_file_exists(filenameA
);
484 check_file_exists(filenameA1
);
485 ret
= CommitUrlCacheEntry(TEST_URL
, filenameA1
, filetime_zero
,
486 filetime_zero
, COOKIE_CACHE_ENTRY
, NULL
, 0, "html", NULL
);
487 ok(ret
, "CommitUrlCacheEntry failed with error %d\n", GetLastError());
488 /* By committing the same URL a second time, the prior entry is
491 cbCacheEntryInfo
= 0;
492 SetLastError(0xdeadbeef);
493 ret
= GetUrlCacheEntryInfo(TEST_URL
, NULL
, &cbCacheEntryInfo
);
494 ok(!ret
, "RetrieveUrlCacheEntryFile should have failed\n");
495 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
496 "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
497 lpCacheEntryInfo
= HeapAlloc(GetProcessHeap(), 0, cbCacheEntryInfo
);
498 ret
= GetUrlCacheEntryInfo(TEST_URL
, lpCacheEntryInfo
, &cbCacheEntryInfo
);
499 ok(ret
, "GetUrlCacheEntryInfo failed with error %d\n", GetLastError());
500 /* with the previous entry type retained.. */
501 ok(lpCacheEntryInfo
->CacheEntryType
& NORMAL_CACHE_ENTRY
,
502 "expected cache entry type NORMAL_CACHE_ENTRY, got %d (0x%08x)\n",
503 lpCacheEntryInfo
->CacheEntryType
, lpCacheEntryInfo
->CacheEntryType
);
504 /* and the headers overwritten.. */
506 ok(!lpCacheEntryInfo
->dwHeaderInfoSize
, "expected headers size 0, got %d\n",
507 lpCacheEntryInfo
->dwHeaderInfoSize
);
508 HeapFree(GetProcessHeap(), 0, lpCacheEntryInfo
);
509 /* and the previous filename shouldn't exist. */
511 check_file_not_exists(filenameA
);
512 check_file_exists(filenameA1
);
514 if (pDeleteUrlCacheEntryA
)
516 ret
= pDeleteUrlCacheEntryA(TEST_URL
);
517 ok(ret
, "DeleteUrlCacheEntryA failed with error %d\n", GetLastError());
519 check_file_not_exists(filenameA
);
521 check_file_not_exists(filenameA1
);
522 /* Just in case, clean up files */
523 DeleteFileA(filenameA1
);
524 DeleteFileA(filenameA
);
527 /* Check whether a retrieved cache entry can be deleted before it's
530 ret
= CreateUrlCacheEntry(TEST_URL
, 0, "html", filenameA
, 0);
531 ok(ret
, "CreateUrlCacheEntry failed with error %d\n", GetLastError());
532 ret
= CommitUrlCacheEntry(TEST_URL
, filenameA
, filetime_zero
, filetime_zero
,
533 NORMAL_CACHE_ENTRY
, NULL
, 0, "html", NULL
);
534 ok(ret
, "CommitUrlCacheEntry failed with error %d\n", GetLastError());
536 cbCacheEntryInfo
= 0;
537 SetLastError(0xdeadbeef);
538 ret
= RetrieveUrlCacheEntryFile(TEST_URL
, NULL
, &cbCacheEntryInfo
, 0);
539 ok(!ret
, "RetrieveUrlCacheEntryFile should have failed\n");
540 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
541 "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
543 lpCacheEntryInfo
= HeapAlloc(GetProcessHeap(), 0, cbCacheEntryInfo
);
544 ret
= RetrieveUrlCacheEntryFile(TEST_URL
, lpCacheEntryInfo
,
545 &cbCacheEntryInfo
, 0);
546 ok(ret
, "RetrieveUrlCacheEntryFile failed with error %d\n", GetLastError());
548 HeapFree(GetProcessHeap(), 0, lpCacheEntryInfo
);
550 if (pDeleteUrlCacheEntryA
)
552 ret
= pDeleteUrlCacheEntryA(TEST_URL
);
554 ok(!ret
, "Expected failure\n");
556 ok(GetLastError() == ERROR_SHARING_VIOLATION
,
557 "Expected ERROR_SHARING_VIOLATION, got %d\n", GetLastError());
558 check_file_exists(filenameA
);
560 if (pUnlockUrlCacheEntryFileA
)
562 check_file_exists(filenameA
);
563 ret
= pUnlockUrlCacheEntryFileA(TEST_URL
, 0);
565 ok(ret
, "UnlockUrlCacheEntryFileA failed: %d\n", GetLastError());
566 /* By unlocking the already-deleted cache entry, the file associated
567 * with it is deleted..
570 check_file_not_exists(filenameA
);
571 /* (just in case, delete file) */
572 DeleteFileA(filenameA
);
574 if (pDeleteUrlCacheEntryA
)
576 /* and a subsequent deletion should fail. */
577 ret
= pDeleteUrlCacheEntryA(TEST_URL
);
578 ok(!ret
, "Expected failure\n");
579 ok(GetLastError() == ERROR_FILE_NOT_FOUND
,
580 "expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
583 /* Test whether preventing a file from being deleted causes
584 * DeleteUrlCacheEntryA to fail.
586 ret
= CreateUrlCacheEntry(TEST_URL
, 0, "html", filenameA
, 0);
587 ok(ret
, "CreateUrlCacheEntry failed with error %d\n", GetLastError());
589 create_and_write_file(filenameA
, &zero_byte
, sizeof(zero_byte
));
590 check_file_exists(filenameA
);
592 ret
= CommitUrlCacheEntry(TEST_URL
, filenameA
, filetime_zero
,
593 filetime_zero
, NORMAL_CACHE_ENTRY
, (LPBYTE
)ok_header
,
594 strlen(ok_header
), "html", NULL
);
595 ok(ret
, "CommitUrlCacheEntry failed with error %d\n", GetLastError());
596 check_file_exists(filenameA
);
597 hFile
= CreateFileA(filenameA
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
,
598 FILE_ATTRIBUTE_NORMAL
, NULL
);
599 ok(hFile
!= INVALID_HANDLE_VALUE
, "CreateFileA failed: %d\n",
601 if (pDeleteUrlCacheEntryA
)
603 /* DeleteUrlCacheEntryA should succeed.. */
604 ret
= pDeleteUrlCacheEntryA(TEST_URL
);
605 ok(ret
, "DeleteUrlCacheEntryA failed with error %d\n", GetLastError());
608 if (pDeleteUrlCacheEntryA
)
610 /* and a subsequent deletion should fail.. */
611 ret
= pDeleteUrlCacheEntryA(TEST_URL
);
612 ok(!ret
, "Expected failure\n");
613 ok(GetLastError() == ERROR_FILE_NOT_FOUND
,
614 "expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
616 /* and the file should be untouched. */
617 check_file_exists(filenameA
);
618 DeleteFileA(filenameA
);
620 /* Try creating a sticky entry. Unlike non-sticky entries, the filename
621 * must have been set already.
623 SetLastError(0xdeadbeef);
624 ret
= CommitUrlCacheEntry(TEST_URL
, NULL
, filetime_zero
, filetime_zero
,
625 STICKY_CACHE_ENTRY
, (LPBYTE
)ok_header
, strlen(ok_header
), "html",
627 ok(!ret
, "expected failure\n");
628 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
629 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
630 SetLastError(0xdeadbeef);
631 ret
= CommitUrlCacheEntry(TEST_URL
, NULL
, filetime_zero
, filetime_zero
,
632 NORMAL_CACHE_ENTRY
|STICKY_CACHE_ENTRY
,
633 (LPBYTE
)ok_header
, strlen(ok_header
), "html", NULL
);
634 ok(!ret
, "expected failure\n");
635 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
636 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
637 ret
= CreateUrlCacheEntry(TEST_URL
, 0, "html", filenameA
, 0);
638 ok(ret
, "CreateUrlCacheEntry failed with error %d\n", GetLastError());
639 create_and_write_file(filenameA
, &zero_byte
, sizeof(zero_byte
));
640 ret
= CommitUrlCacheEntry(TEST_URL
, filenameA
, filetime_zero
, filetime_zero
,
641 NORMAL_CACHE_ENTRY
|STICKY_CACHE_ENTRY
,
642 (LPBYTE
)ok_header
, strlen(ok_header
), "html", NULL
);
643 ok(ret
, "CommitUrlCacheEntry failed with error %d\n", GetLastError());
644 cbCacheEntryInfo
= 0;
645 SetLastError(0xdeadbeef);
646 ret
= GetUrlCacheEntryInfo(TEST_URL
, NULL
, &cbCacheEntryInfo
);
647 ok(!ret
, "RetrieveUrlCacheEntryFile should have failed\n");
648 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
649 "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
650 lpCacheEntryInfo
= HeapAlloc(GetProcessHeap(), 0, cbCacheEntryInfo
);
651 ret
= GetUrlCacheEntryInfo(TEST_URL
, lpCacheEntryInfo
, &cbCacheEntryInfo
);
652 ok(ret
, "GetUrlCacheEntryInfo failed with error %d\n", GetLastError());
653 ok(lpCacheEntryInfo
->CacheEntryType
& (NORMAL_CACHE_ENTRY
|STICKY_CACHE_ENTRY
),
654 "expected cache entry type NORMAL_CACHE_ENTRY | STICKY_CACHE_ENTRY, got %d (0x%08x)\n",
655 lpCacheEntryInfo
->CacheEntryType
, lpCacheEntryInfo
->CacheEntryType
);
656 ok(U(*lpCacheEntryInfo
).dwExemptDelta
== 86400,
657 "expected dwExemptDelta 864000, got %d\n",
658 U(*lpCacheEntryInfo
).dwExemptDelta
);
659 HeapFree(GetProcessHeap(), 0, lpCacheEntryInfo
);
660 if (pDeleteUrlCacheEntryA
)
662 ret
= pDeleteUrlCacheEntryA(TEST_URL
);
663 ok(ret
, "DeleteUrlCacheEntryA failed with error %d\n", GetLastError());
664 /* When explicitly deleting the cache entry, the file is also deleted */
666 check_file_not_exists(filenameA
);
668 /* Test once again, setting the exempt delta via SetUrlCacheEntryInfo */
669 ret
= CreateUrlCacheEntry(TEST_URL
, 0, "html", filenameA
, 0);
670 ok(ret
, "CreateUrlCacheEntry failed with error %d\n", GetLastError());
671 create_and_write_file(filenameA
, &zero_byte
, sizeof(zero_byte
));
672 ret
= CommitUrlCacheEntry(TEST_URL
, filenameA
, filetime_zero
, filetime_zero
,
673 NORMAL_CACHE_ENTRY
|STICKY_CACHE_ENTRY
,
674 (LPBYTE
)ok_header
, strlen(ok_header
), "html", NULL
);
675 ok(ret
, "CommitUrlCacheEntry failed with error %d\n", GetLastError());
676 cbCacheEntryInfo
= 0;
677 SetLastError(0xdeadbeef);
678 ret
= GetUrlCacheEntryInfo(TEST_URL
, NULL
, &cbCacheEntryInfo
);
679 ok(!ret
, "RetrieveUrlCacheEntryFile should have failed\n");
680 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
681 "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
682 lpCacheEntryInfo
= HeapAlloc(GetProcessHeap(), 0, cbCacheEntryInfo
);
683 ret
= GetUrlCacheEntryInfo(TEST_URL
, lpCacheEntryInfo
, &cbCacheEntryInfo
);
684 ok(ret
, "GetUrlCacheEntryInfo failed with error %d\n", GetLastError());
685 ok(lpCacheEntryInfo
->CacheEntryType
& (NORMAL_CACHE_ENTRY
|STICKY_CACHE_ENTRY
),
686 "expected cache entry type NORMAL_CACHE_ENTRY | STICKY_CACHE_ENTRY, got %d (0x%08x)\n",
687 lpCacheEntryInfo
->CacheEntryType
, lpCacheEntryInfo
->CacheEntryType
);
688 ok(U(*lpCacheEntryInfo
).dwExemptDelta
== 86400,
689 "expected dwExemptDelta 864000, got %d\n",
690 U(*lpCacheEntryInfo
).dwExemptDelta
);
691 U(*lpCacheEntryInfo
).dwExemptDelta
= 0;
692 ret
= SetUrlCacheEntryInfoA(TEST_URL
, lpCacheEntryInfo
,
693 CACHE_ENTRY_EXEMPT_DELTA_FC
);
694 ok(ret
, "SetUrlCacheEntryInfo failed: %d\n", GetLastError());
695 ret
= GetUrlCacheEntryInfo(TEST_URL
, lpCacheEntryInfo
, &cbCacheEntryInfo
);
696 ok(ret
, "GetUrlCacheEntryInfo failed with error %d\n", GetLastError());
697 ok(!U(*lpCacheEntryInfo
).dwExemptDelta
, "expected dwExemptDelta 0, got %d\n",
698 U(*lpCacheEntryInfo
).dwExemptDelta
);
699 /* See whether a sticky cache entry has the flag cleared once the exempt
700 * delta is meaningless.
702 ok(lpCacheEntryInfo
->CacheEntryType
& (NORMAL_CACHE_ENTRY
|STICKY_CACHE_ENTRY
),
703 "expected cache entry type NORMAL_CACHE_ENTRY | STICKY_CACHE_ENTRY, got %d (0x%08x)\n",
704 lpCacheEntryInfo
->CacheEntryType
, lpCacheEntryInfo
->CacheEntryType
);
705 HeapFree(GetProcessHeap(), 0, lpCacheEntryInfo
);
706 if (pDeleteUrlCacheEntryA
)
708 ret
= pDeleteUrlCacheEntryA(TEST_URL
);
709 ok(ret
, "DeleteUrlCacheEntryA failed with error %d\n", GetLastError());
711 check_file_not_exists(filenameA
);
715 static void test_FindCloseUrlCache(void)
720 SetLastError(0xdeadbeef);
721 r
= FindCloseUrlCache(NULL
);
722 err
= GetLastError();
723 ok(0 == r
, "expected 0, got %d\n", r
);
724 ok(ERROR_INVALID_HANDLE
== err
, "expected %d, got %d\n", ERROR_INVALID_HANDLE
, err
);
727 static void test_GetDiskInfoA(void)
730 DWORD error
, cluster_size
;
731 DWORDLONG free
, total
;
732 char path
[MAX_PATH
], *p
;
734 GetSystemDirectoryA(path
, MAX_PATH
);
735 if ((p
= strchr(path
, '\\'))) *++p
= 0;
737 ret
= GetDiskInfoA(path
, &cluster_size
, &free
, &total
);
738 ok(ret
, "GetDiskInfoA failed %u\n", GetLastError());
740 ret
= GetDiskInfoA(path
, &cluster_size
, &free
, NULL
);
741 ok(ret
, "GetDiskInfoA failed %u\n", GetLastError());
743 ret
= GetDiskInfoA(path
, &cluster_size
, NULL
, NULL
);
744 ok(ret
, "GetDiskInfoA failed %u\n", GetLastError());
746 ret
= GetDiskInfoA(path
, NULL
, NULL
, NULL
);
747 ok(ret
, "GetDiskInfoA failed %u\n", GetLastError());
749 SetLastError(0xdeadbeef);
750 strcpy(p
, "\\non\\existing\\path");
751 ret
= GetDiskInfoA(path
, NULL
, NULL
, NULL
);
752 error
= GetLastError();
754 broken(ret
), /* < IE7 */
755 "GetDiskInfoA succeeded\n");
756 ok(error
== ERROR_PATH_NOT_FOUND
||
757 broken(error
== 0xdeadbeef), /* < IE7 */
758 "got %u expected ERROR_PATH_NOT_FOUND\n", error
);
760 SetLastError(0xdeadbeef);
761 ret
= GetDiskInfoA(NULL
, NULL
, NULL
, NULL
);
762 error
= GetLastError();
763 ok(!ret
, "GetDiskInfoA succeeded\n");
764 ok(error
== ERROR_INVALID_PARAMETER
, "got %u expected ERROR_INVALID_PARAMETER\n", error
);
770 hdll
= GetModuleHandleA("wininet.dll");
772 if(!GetProcAddress(hdll
, "InternetGetCookieExW")) {
773 win_skip("Too old IE (older than 6.0)\n");
777 pDeleteUrlCacheEntryA
= (void*)GetProcAddress(hdll
, "DeleteUrlCacheEntryA");
778 pUnlockUrlCacheEntryFileA
= (void*)GetProcAddress(hdll
, "UnlockUrlCacheEntryFileA");
780 test_FindCloseUrlCache();