2 * Unit tests for cabinet.dll extract functions
4 * Copyright (C) 2006 James Hawkins
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
25 #include "wine/test.h"
27 /* make the max size large so there is only one cab file */
28 #define MEDIA_SIZE 999999999
29 #define FOLDER_THRESHOLD 900000
31 /* The following definitions were copied from dlls/cabinet/cabinet.h
32 * because they are undocumented in windows.
35 /* SESSION Operation */
36 #define EXTRACT_FILLFILELIST 0x00000001
37 #define EXTRACT_EXTRACTFILES 0x00000002
41 struct FILELIST
*next
;
48 struct FILELIST
*FileList
;
51 CHAR Destination
[MAX_PATH
];
52 CHAR CurrentFile
[MAX_PATH
];
53 CHAR Reserved
[MAX_PATH
];
54 struct FILELIST
*FilterList
;
57 /* function pointers */
58 static HMODULE hCabinet
;
59 static HRESULT (WINAPI
*pExtract
)(SESSION
*, LPCSTR
);
61 static CHAR CURR_DIR
[MAX_PATH
];
63 static void init_function_pointers(void)
65 hCabinet
= GetModuleHandleA("cabinet.dll");
67 pExtract
= (void *)GetProcAddress(hCabinet
, "Extract");
70 /* creates a file with the specified name for tests */
71 static void createTestFile(const CHAR
*name
)
76 file
= CreateFileA(name
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
77 ok(file
!= INVALID_HANDLE_VALUE
, "Failure to open file %s\n", name
);
78 WriteFile(file
, name
, strlen(name
), &written
, NULL
);
79 WriteFile(file
, "\n", strlen("\n"), &written
, NULL
);
83 static int getFileSize(const CHAR
*name
)
87 file
= CreateFileA(name
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
88 if (file
== INVALID_HANDLE_VALUE
)
90 size
= GetFileSize(file
, NULL
);
95 static void create_test_files(void)
99 GetCurrentDirectoryA(MAX_PATH
, CURR_DIR
);
100 len
= lstrlenA(CURR_DIR
);
102 if(len
&& (CURR_DIR
[len
-1] == '\\'))
105 createTestFile("a.txt");
106 createTestFile("b.txt");
107 CreateDirectoryA("testdir", NULL
);
108 createTestFile("testdir\\c.txt");
109 createTestFile("testdir\\d.txt");
110 CreateDirectoryA("dest", NULL
);
113 static void delete_test_files(void)
115 DeleteFileA("a.txt");
116 DeleteFileA("b.txt");
117 DeleteFileA("testdir\\c.txt");
118 DeleteFileA("testdir\\d.txt");
119 RemoveDirectoryA("testdir");
121 DeleteFileA("extract.cab");
124 /* the FCI callbacks */
126 static void * CDECL
mem_alloc(ULONG cb
)
128 return HeapAlloc(GetProcessHeap(), 0, cb
);
131 static void CDECL
mem_free(void *memory
)
133 HeapFree(GetProcessHeap(), 0, memory
);
136 static BOOL CDECL
get_next_cabinet(PCCAB pccab
, ULONG cbPrevCab
, void *pv
)
141 static LONG CDECL
progress(UINT typeStatus
, ULONG cb1
, ULONG cb2
, void *pv
)
146 static int CDECL
file_placed(PCCAB pccab
, char *pszFile
, LONG cbFile
,
147 BOOL fContinuation
, void *pv
)
152 static INT_PTR CDECL
fci_open(char *pszFile
, int oflag
, int pmode
, int *err
, void *pv
)
156 DWORD dwShareMode
= 0;
157 DWORD dwCreateDisposition
= OPEN_EXISTING
;
159 dwAccess
= GENERIC_READ
| GENERIC_WRITE
;
160 /* FILE_SHARE_DELETE is not supported by Windows Me/98/95 */
161 dwShareMode
= FILE_SHARE_READ
| FILE_SHARE_WRITE
;
163 if (GetFileAttributesA(pszFile
) != INVALID_FILE_ATTRIBUTES
)
164 dwCreateDisposition
= OPEN_EXISTING
;
166 dwCreateDisposition
= CREATE_NEW
;
168 handle
= CreateFileA(pszFile
, dwAccess
, dwShareMode
, NULL
,
169 dwCreateDisposition
, 0, NULL
);
171 ok(handle
!= INVALID_HANDLE_VALUE
, "Failed to CreateFile %s\n", pszFile
);
173 return (INT_PTR
)handle
;
176 static UINT CDECL
fci_read(INT_PTR hf
, void *memory
, UINT cb
, int *err
, void *pv
)
178 HANDLE handle
= (HANDLE
)hf
;
182 res
= ReadFile(handle
, memory
, cb
, &dwRead
, NULL
);
183 ok(res
, "Failed to ReadFile\n");
188 static UINT CDECL
fci_write(INT_PTR hf
, void *memory
, UINT cb
, int *err
, void *pv
)
190 HANDLE handle
= (HANDLE
)hf
;
194 res
= WriteFile(handle
, memory
, cb
, &dwWritten
, NULL
);
195 ok(res
, "Failed to WriteFile\n");
200 static int CDECL
fci_close(INT_PTR hf
, int *err
, void *pv
)
202 HANDLE handle
= (HANDLE
)hf
;
203 ok(CloseHandle(handle
), "Failed to CloseHandle\n");
208 static LONG CDECL
fci_seek(INT_PTR hf
, LONG dist
, int seektype
, int *err
, void *pv
)
210 HANDLE handle
= (HANDLE
)hf
;
213 ret
= SetFilePointer(handle
, dist
, NULL
, seektype
);
214 ok(ret
!= INVALID_SET_FILE_POINTER
, "Failed to SetFilePointer\n");
219 static int CDECL
fci_delete(char *pszFile
, int *err
, void *pv
)
221 BOOL ret
= DeleteFileA(pszFile
);
222 ok(ret
, "Failed to DeleteFile %s\n", pszFile
);
227 static BOOL CDECL
get_temp_file(char *pszTempName
, int cbTempName
, void *pv
)
231 tempname
= HeapAlloc(GetProcessHeap(), 0, MAX_PATH
);
232 GetTempFileNameA(".", "xx", 0, tempname
);
234 if (tempname
&& (strlen(tempname
) < (unsigned)cbTempName
))
236 lstrcpyA(pszTempName
, tempname
);
237 HeapFree(GetProcessHeap(), 0, tempname
);
241 HeapFree(GetProcessHeap(), 0, tempname
);
246 static INT_PTR CDECL
get_open_info(char *pszName
, USHORT
*pdate
, USHORT
*ptime
,
247 USHORT
*pattribs
, int *err
, void *pv
)
249 BY_HANDLE_FILE_INFORMATION finfo
;
255 handle
= CreateFileA(pszName
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
256 OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
| FILE_FLAG_SEQUENTIAL_SCAN
, NULL
);
258 ok(handle
!= INVALID_HANDLE_VALUE
, "Failed to CreateFile %s\n", pszName
);
260 res
= GetFileInformationByHandle(handle
, &finfo
);
261 ok(res
, "Expected GetFileInformationByHandle to succeed\n");
263 FileTimeToLocalFileTime(&finfo
.ftLastWriteTime
, &filetime
);
264 FileTimeToDosDateTime(&filetime
, pdate
, ptime
);
266 attrs
= GetFileAttributesA(pszName
);
267 ok(attrs
!= INVALID_FILE_ATTRIBUTES
, "Failed to GetFileAttributes\n");
269 return (INT_PTR
)handle
;
272 static void add_file(HFCI hfci
, char *file
)
277 lstrcpyA(path
, CURR_DIR
);
278 lstrcatA(path
, "\\");
279 lstrcatA(path
, file
);
281 res
= FCIAddFile(hfci
, path
, file
, FALSE
, get_next_cabinet
, progress
,
282 get_open_info
, tcompTYPE_MSZIP
);
283 ok(res
, "Expected FCIAddFile to succeed\n");
286 static void set_cab_parameters(PCCAB pCabParams
)
288 ZeroMemory(pCabParams
, sizeof(CCAB
));
290 pCabParams
->cb
= MEDIA_SIZE
;
291 pCabParams
->cbFolderThresh
= FOLDER_THRESHOLD
;
292 pCabParams
->setID
= 0xbeef;
293 lstrcpyA(pCabParams
->szCabPath
, CURR_DIR
);
294 lstrcatA(pCabParams
->szCabPath
, "\\");
295 lstrcpyA(pCabParams
->szCab
, "extract.cab");
298 static void create_cab_file(void)
303 static CHAR a_txt
[] = "a.txt",
305 testdir_c_txt
[] = "testdir\\c.txt",
306 testdir_d_txt
[] = "testdir\\d.txt";
309 set_cab_parameters(&cabParams
);
311 hfci
= FCICreate(&erf
, file_placed
, mem_alloc
, mem_free
, fci_open
,
312 fci_read
, fci_write
, fci_close
, fci_seek
, fci_delete
,
313 get_temp_file
, &cabParams
, NULL
);
315 ok(hfci
!= NULL
, "Failed to create an FCI context\n");
317 add_file(hfci
, a_txt
);
318 add_file(hfci
, b_txt
);
319 add_file(hfci
, testdir_c_txt
);
320 add_file(hfci
, testdir_d_txt
);
322 res
= FCIFlushCabinet(hfci
, FALSE
, get_next_cabinet
, progress
);
323 ok(res
, "Failed to flush the cabinet\n");
325 res
= FCIDestroy(hfci
);
326 ok(res
, "Failed to destroy the cabinet\n");
329 static BOOL
check_list(struct FILELIST
**node
, const char *filename
, BOOL do_extract
)
334 if (lstrcmpA((*node
)->FileName
, filename
))
337 if ((*node
)->DoExtract
!= do_extract
)
340 *node
= (*node
)->next
;
344 static void free_file_node(struct FILELIST
*node
)
346 HeapFree(GetProcessHeap(), 0, node
->FileName
);
347 HeapFree(GetProcessHeap(), 0, node
);
350 static void free_file_list(SESSION
* session
)
352 struct FILELIST
*next
, *curr
= session
->FileList
;
357 free_file_node(curr
);
361 session
->FileList
= NULL
;
364 static void test_Extract(void)
368 struct FILELIST
*node
;
370 /* native windows crashes if
371 * - invalid parameters are sent in
372 * - you call EXTRACT_EXTRACTFILES without calling
373 * EXTRACT_FILLFILELIST first or at the same time
376 /* try to extract all files */
377 ZeroMemory(&session
, sizeof(SESSION
));
378 lstrcpyA(session
.Destination
, "dest");
379 session
.Operation
= EXTRACT_FILLFILELIST
| EXTRACT_EXTRACTFILES
;
380 res
= pExtract(&session
, "extract.cab");
381 node
= session
.FileList
;
382 ok(res
== S_OK
, "Expected S_OK, got %d\n", res
);
383 ok(session
.FileSize
== 40, "Expected 40, got %d\n", session
.FileSize
);
384 ok(session
.Error
.erfOper
== FDIERROR_NONE
,
385 "Expected FDIERROR_NONE, got %d\n", session
.Error
.erfOper
);
386 ok(session
.Error
.erfType
== 0, "Expected 0, got %d\n", session
.Error
.erfType
);
387 ok(session
.Error
.fError
== FALSE
, "Expected FALSE, got %d\n", session
.Error
.fError
);
388 ok(session
.FileCount
== 4, "Expected 4, got %d\n", session
.FileCount
);
389 ok(session
.Operation
== (EXTRACT_FILLFILELIST
| EXTRACT_EXTRACTFILES
),
390 "Expected EXTRACT_FILLFILELIST | EXTRACT_EXTRACTFILES, got %d\n", session
.Operation
);
391 ok(!lstrcmpA(session
.Destination
, "dest"), "Expected dest, got %s\n", session
.Destination
);
392 ok(!lstrcmpA(session
.CurrentFile
, "dest\\testdir\\d.txt"),
393 "Expected dest\\testdir\\d.txt, got %s\n", session
.CurrentFile
);
394 ok(!*session
.Reserved
, "Expected empty string, got %s\n", session
.Reserved
);
395 ok(!session
.FilterList
, "Expected empty filter list\n");
396 ok(DeleteFileA("dest\\a.txt"), "Expected dest\\a.txt to exist\n");
397 ok(DeleteFileA("dest\\b.txt"), "Expected dest\\b.txt to exist\n");
398 ok(DeleteFileA("dest\\testdir\\c.txt"), "Expected dest\\testdir\\c.txt to exist\n");
399 ok(DeleteFileA("dest\\testdir\\d.txt"), "Expected dest\\testdir\\d.txt to exist\n");
400 ok(RemoveDirectoryA("dest\\testdir"), "Expected dest\\testdir to exist\n");
401 ok(check_list(&node
, "testdir\\d.txt", FALSE
), "list entry wrong\n");
402 ok(check_list(&node
, "testdir\\c.txt", FALSE
), "list entry wrong\n");
403 ok(check_list(&node
, "b.txt", FALSE
), "list entry wrong\n");
404 ok(check_list(&node
, "a.txt", FALSE
), "list entry wrong\n");
405 free_file_list(&session
);
407 /* try fill file list operation */
408 ZeroMemory(&session
, sizeof(SESSION
));
409 lstrcpyA(session
.Destination
, "dest");
410 session
.Operation
= EXTRACT_FILLFILELIST
;
411 res
= pExtract(&session
, "extract.cab");
412 node
= session
.FileList
;
413 ok(res
== S_OK
, "Expected S_OK, got %d\n", res
);
414 ok(session
.FileSize
== 40, "Expected 40, got %d\n", session
.FileSize
);
415 ok(session
.Error
.erfOper
== FDIERROR_NONE
,
416 "Expected FDIERROR_NONE, got %d\n", session
.Error
.erfOper
);
417 ok(session
.Error
.erfType
== 0, "Expected 0, got %d\n", session
.Error
.erfType
);
418 ok(session
.Error
.fError
== FALSE
, "Expected FALSE, got %d\n", session
.Error
.fError
);
419 ok(session
.FileCount
== 4, "Expected 4, got %d\n", session
.FileCount
);
420 ok(session
.Operation
== EXTRACT_FILLFILELIST
,
421 "Expected EXTRACT_FILLFILELIST, got %d\n", session
.Operation
);
422 ok(!lstrcmpA(session
.Destination
, "dest"), "Expected dest, got %s\n", session
.Destination
);
423 ok(!lstrcmpA(session
.CurrentFile
, "dest\\testdir\\d.txt"),
424 "Expected dest\\testdir\\d.txt, got %s\n", session
.CurrentFile
);
425 ok(!*session
.Reserved
, "Expected empty string, got %s\n", session
.Reserved
);
426 ok(!session
.FilterList
, "Expected empty filter list\n");
427 ok(!DeleteFileA("dest\\a.txt"), "Expected dest\\a.txt to not exist\n");
428 ok(!DeleteFileA("dest\\testdir\\c.txt"), "Expected dest\\testdir\\c.txt to not exist\n");
429 ok(check_list(&node
, "testdir\\d.txt", TRUE
), "list entry wrong\n");
430 ok(check_list(&node
, "testdir\\c.txt", TRUE
), "list entry wrong\n");
431 ok(check_list(&node
, "b.txt", TRUE
), "list entry wrong\n");
432 ok(check_list(&node
, "a.txt", TRUE
), "list entry wrong\n");
434 /* try extract files operation once file list is filled */
435 session
.Operation
= EXTRACT_EXTRACTFILES
;
436 res
= pExtract(&session
, "extract.cab");
437 node
= session
.FileList
;
438 ok(res
== S_OK
, "Expected S_OK, got %d\n", res
);
439 ok(session
.FileSize
== 40, "Expected 40, got %d\n", session
.FileSize
);
440 ok(session
.Error
.erfOper
== FDIERROR_NONE
,
441 "Expected FDIERROR_NONE, got %d\n", session
.Error
.erfOper
);
442 ok(session
.Error
.erfType
== 0, "Expected 0, got %d\n", session
.Error
.erfType
);
443 ok(session
.Error
.fError
== FALSE
, "Expected FALSE, got %d\n", session
.Error
.fError
);
444 ok(session
.FileCount
== 4, "Expected 4, got %d\n", session
.FileCount
);
445 ok(session
.Operation
== EXTRACT_EXTRACTFILES
,
446 "Expected EXTRACT_EXTRACTFILES, got %d\n", session
.Operation
);
447 ok(!lstrcmpA(session
.Destination
, "dest"), "Expected dest, got %s\n", session
.Destination
);
448 ok(!lstrcmpA(session
.CurrentFile
, "dest\\testdir\\d.txt"),
449 "Expected dest\\testdir\\d.txt, got %s\n", session
.CurrentFile
);
450 ok(!*session
.Reserved
, "Expected empty string, got %s\n", session
.Reserved
);
451 ok(!session
.FilterList
, "Expected empty filter list\n");
452 ok(DeleteFileA("dest\\a.txt"), "Expected dest\\a.txt to exist\n");
453 ok(DeleteFileA("dest\\b.txt"), "Expected dest\\b.txt to exist\n");
454 ok(DeleteFileA("dest\\testdir\\c.txt"), "Expected dest\\testdir\\c.txt to exist\n");
455 ok(DeleteFileA("dest\\testdir\\d.txt"), "Expected dest\\testdir\\d.txt to exist\n");
456 ok(RemoveDirectoryA("dest\\testdir"), "Expected dest\\testdir to exist\n");
457 ok(RemoveDirectoryA("dest"), "Expected dest to exist\n");
458 ok(check_list(&node
, "testdir\\d.txt", FALSE
), "list entry wrong\n");
459 ok(check_list(&node
, "testdir\\c.txt", FALSE
), "list entry wrong\n");
460 ok(check_list(&node
, "b.txt", FALSE
), "list entry wrong\n");
461 ok(check_list(&node
, "a.txt", FALSE
), "list entry wrong\n");
463 /* Extract does not extract files if the dest dir does not exist */
464 res
= pExtract(&session
, "extract.cab");
465 node
= session
.FileList
;
466 ok(res
== S_OK
, "Expected S_OK, got %d\n", res
);
467 ok(session
.FileSize
== 40, "Expected 40, got %d\n", session
.FileSize
);
468 ok(session
.Error
.erfOper
== FDIERROR_NONE
,
469 "Expected FDIERROR_NONE, got %d\n", session
.Error
.erfOper
);
470 ok(session
.Error
.erfType
== 0, "Expected 0, got %d\n", session
.Error
.erfType
);
471 ok(session
.Error
.fError
== FALSE
, "Expected FALSE, got %d\n", session
.Error
.fError
);
472 ok(session
.FileCount
== 4, "Expected 4, got %d\n", session
.FileCount
);
473 ok(session
.Operation
== EXTRACT_EXTRACTFILES
,
474 "Expected EXTRACT_EXTRACTFILES, got %d\n", session
.Operation
);
475 ok(!lstrcmpA(session
.Destination
, "dest"), "Expected dest, got %s\n", session
.Destination
);
476 ok(!lstrcmpA(session
.CurrentFile
, "dest\\testdir\\d.txt"),
477 "Expected dest\\testdir\\d.txt, got %s\n", session
.CurrentFile
);
478 ok(!*session
.Reserved
, "Expected empty string, got %s\n", session
.Reserved
);
479 ok(!session
.FilterList
, "Expected empty filter list\n");
480 ok(!DeleteFileA("dest\\a.txt"), "Expected dest\\a.txt to not exist\n");
481 ok(!DeleteFileA("dest\\b.txt"), "Expected dest\\b.txt to not exist\n");
482 ok(!DeleteFileA("dest\\testdir\\c.txt"), "Expected dest\\testdir\\c.txt to not exist\n");
483 ok(!DeleteFileA("dest\\testdir\\d.txt"), "Expected dest\\testdir\\d.txt to not exist\n");
484 ok(check_list(&node
, "testdir\\d.txt", FALSE
), "list entry wrong\n");
485 ok(check_list(&node
, "testdir\\c.txt", FALSE
), "list entry wrong\n");
486 ok(check_list(&node
, "b.txt", FALSE
), "list entry wrong\n");
487 ok(check_list(&node
, "a.txt", FALSE
), "list entry wrong\n");
489 /* remove two of the files in the list */
490 node
= session
.FileList
->next
;
491 session
.FileList
->next
= session
.FileList
->next
->next
;
492 free_file_node(node
);
493 free_file_node(session
.FileList
->next
->next
);
494 session
.FileList
->next
->next
= NULL
;
495 session
.FilterList
= NULL
;
496 CreateDirectoryA("dest", NULL
);
497 res
= pExtract(&session
, "extract.cab");
498 node
= session
.FileList
;
499 ok(res
== S_OK
, "Expected S_OK, got %d\n", res
);
500 ok(session
.FileSize
== 40, "Expected 40, got %d\n", session
.FileSize
);
501 ok(session
.Error
.erfOper
== FDIERROR_NONE
,
502 "Expected FDIERROR_NONE, got %d\n", session
.Error
.erfOper
);
503 ok(session
.Error
.erfType
== 0, "Expected 0, got %d\n", session
.Error
.erfType
);
504 ok(session
.Error
.fError
== FALSE
, "Expected FALSE, got %d\n", session
.Error
.fError
);
505 ok(session
.FileCount
== 4, "Expected 4, got %d\n", session
.FileCount
);
506 ok(session
.Operation
== EXTRACT_EXTRACTFILES
,
507 "Expected EXTRACT_EXTRACTFILES, got %d\n", session
.Operation
);
508 ok(!lstrcmpA(session
.Destination
, "dest"), "Expected dest, got %s\n", session
.Destination
);
509 ok(!lstrcmpA(session
.CurrentFile
, "dest\\testdir\\d.txt"),
510 "Expected dest\\testdir\\d.txt, got %s\n", session
.CurrentFile
);
511 ok(!*session
.Reserved
, "Expected empty string, got %s\n", session
.Reserved
);
512 ok(!session
.FilterList
, "Expected empty filter list\n");
513 ok(DeleteFileA("dest\\a.txt"), "Expected dest\\a.txt to exist\n");
514 ok(DeleteFileA("dest\\testdir\\c.txt"), "Expected dest\\testdir\\c.txt to exist\n");
515 ok(!DeleteFileA("dest\\b.txt"), "Expected dest\\b.txt to not exist\n");
516 ok(!DeleteFileA("dest\\testdir\\d.txt"), "Expected dest\\testdir\\d.txt to not exist\n");
517 ok(check_list(&node
, "testdir\\d.txt", FALSE
), "list entry wrong\n");
518 ok(!check_list(&node
, "testdir\\c.txt", FALSE
), "list entry wrong\n");
519 ok(check_list(&node
, "b.txt", FALSE
), "list entry wrong\n");
520 ok(!check_list(&node
, "a.txt", FALSE
), "list entry wrong\n");
521 free_file_list(&session
);
523 session
.Operation
= EXTRACT_FILLFILELIST
;
524 session
.FileList
= NULL
;
525 res
= pExtract(&session
, "extract.cab");
526 node
= session
.FileList
;
527 ok(res
== S_OK
, "Expected S_OK, got %d\n", res
);
528 ok(session
.FileSize
== 40, "Expected 40, got %d\n", session
.FileSize
);
529 ok(session
.Error
.erfOper
== FDIERROR_NONE
,
530 "Expected FDIERROR_NONE, got %d\n", session
.Error
.erfOper
);
531 ok(session
.Error
.erfType
== 0, "Expected 0, got %d\n", session
.Error
.erfType
);
532 ok(session
.Error
.fError
== FALSE
, "Expected FALSE, got %d\n", session
.Error
.fError
);
533 ok(session
.FileCount
== 8, "Expected 8, got %d\n", session
.FileCount
);
534 ok(session
.Operation
== EXTRACT_FILLFILELIST
,
535 "Expected EXTRACT_FILLFILELIST, got %d\n", session
.Operation
);
536 ok(!lstrcmpA(session
.Destination
, "dest"), "Expected dest, got %s\n", session
.Destination
);
537 ok(!lstrcmpA(session
.CurrentFile
, "dest\\testdir\\d.txt"),
538 "Expected dest\\testdir\\d.txt, got %s\n", session
.CurrentFile
);
539 ok(!*session
.Reserved
, "Expected empty string, got %s\n", session
.Reserved
);
540 ok(!session
.FilterList
, "Expected empty filter list\n");
541 ok(!DeleteFileA("dest\\a.txt"), "Expected dest\\a.txt to not exist\n");
542 ok(!DeleteFileA("dest\\testdir\\c.txt"), "Expected dest\\testdir\\c.txt to not exist\n");
543 ok(!DeleteFileA("dest\\b.txt"), "Expected dest\\b.txt to not exist\n");
544 ok(!DeleteFileA("dest\\testdir\\d.txt"), "Expected dest\\testdir\\d.txt to not exist\n");
545 ok(check_list(&node
, "testdir\\d.txt", TRUE
), "list entry wrong\n");
546 ok(!check_list(&node
, "testdir\\c.txt", FALSE
), "list entry wrong\n");
547 ok(!check_list(&node
, "b.txt", FALSE
), "list entry wrong\n");
548 ok(!check_list(&node
, "a.txt", FALSE
), "list entry wrong\n");
550 session
.Operation
= 0;
551 res
= pExtract(&session
, "extract.cab");
552 node
= session
.FileList
;
553 ok(res
== S_OK
, "Expected S_OK, got %d\n", res
);
554 ok(session
.FileSize
== 40, "Expected 40, got %d\n", session
.FileSize
);
555 ok(session
.Error
.erfOper
== FDIERROR_NONE
,
556 "Expected FDIERROR_NONE, got %d\n", session
.Error
.erfOper
);
557 ok(session
.Error
.erfType
== 0, "Expected 0, got %d\n", session
.Error
.erfType
);
558 ok(session
.Error
.fError
== FALSE
, "Expected FALSE, got %d\n", session
.Error
.fError
);
559 ok(session
.FileCount
== 8, "Expected 8, got %d\n", session
.FileCount
);
560 ok(session
.Operation
== 0, "Expected 0, got %d\n", session
.Operation
);
561 ok(!lstrcmpA(session
.Destination
, "dest"), "Expected dest, got %s\n", session
.Destination
);
562 ok(!lstrcmpA(session
.CurrentFile
, "dest\\testdir\\d.txt"),
563 "Expected dest\\testdir\\d.txt, got %s\n", session
.CurrentFile
);
564 ok(!*session
.Reserved
, "Expected empty string, got %s\n", session
.Reserved
);
565 ok(!session
.FilterList
, "Expected empty filter list\n");
566 ok(!DeleteFileA("dest\\a.txt"), "Expected dest\\a.txt to exist\n");
567 ok(!DeleteFileA("dest\\testdir\\c.txt"), "Expected dest\\testdir\\c.txt to exist\n");
568 ok(!DeleteFileA("dest\\b.txt"), "Expected dest\\b.txt to exist\n");
569 ok(!DeleteFileA("dest\\testdir\\d.txt"), "Expected dest\\testdir\\d.txt to exist\n");
570 ok(check_list(&node
, "testdir\\d.txt", TRUE
), "list entry wrong\n");
571 ok(check_list(&node
, "testdir\\c.txt", TRUE
), "list entry wrong\n");
572 ok(check_list(&node
, "b.txt", TRUE
), "list entry wrong\n");
573 ok(check_list(&node
, "a.txt", TRUE
), "list entry wrong\n");
575 session
.Operation
= 0;
576 session
.FilterList
= session
.FileList
;
577 res
= pExtract(&session
, "extract.cab");
578 node
= session
.FileList
;
579 ok(res
== S_OK
, "Expected S_OK, got %d\n", res
);
580 ok(session
.FileSize
== 40, "Expected 40, got %d\n", session
.FileSize
);
581 ok(session
.Error
.erfOper
== FDIERROR_NONE
,
582 "Expected FDIERROR_NONE, got %d\n", session
.Error
.erfOper
);
583 ok(session
.Error
.erfType
== 0, "Expected 0, got %d\n", session
.Error
.erfType
);
584 ok(session
.Error
.fError
== FALSE
, "Expected FALSE, got %d\n", session
.Error
.fError
);
585 ok(session
.FileCount
== 8, "Expected 8, got %d\n", session
.FileCount
);
586 ok(session
.Operation
== 0, "Expected 0, got %d\n", session
.Operation
);
587 ok(!lstrcmpA(session
.Destination
, "dest"), "Expected dest, got %s\n", session
.Destination
);
588 ok(!lstrcmpA(session
.CurrentFile
, "dest\\testdir\\d.txt"),
589 "Expected dest\\testdir\\d.txt, got %s\n", session
.CurrentFile
);
590 ok(!*session
.Reserved
, "Expected empty string, got %s\n", session
.Reserved
);
591 ok(DeleteFileA("dest\\a.txt"), "Expected dest\\a.txt to exist\n");
592 ok(DeleteFileA("dest\\testdir\\c.txt"), "Expected dest\\testdir\\c.txt to exist\n");
593 ok(DeleteFileA("dest\\b.txt"), "Expected dest\\b.txt to exist\n");
594 ok(DeleteFileA("dest\\testdir\\d.txt"), "Expected dest\\testdir\\d.txt to exist\n");
595 ok(check_list(&node
, "testdir\\d.txt", FALSE
), "list entry wrong\n");
596 ok(check_list(&node
, "testdir\\c.txt", FALSE
), "list entry wrong\n");
597 ok(check_list(&node
, "b.txt", FALSE
), "list entry wrong\n");
598 ok(check_list(&node
, "a.txt", FALSE
), "list entry wrong\n");
599 node
= session
.FilterList
;
600 ok(check_list(&node
, "testdir\\d.txt", FALSE
), "list entry wrong\n");
601 ok(check_list(&node
, "testdir\\c.txt", FALSE
), "list entry wrong\n");
602 ok(check_list(&node
, "b.txt", FALSE
), "list entry wrong\n");
603 ok(check_list(&node
, "a.txt", FALSE
), "list entry wrong\n");
604 free_file_list(&session
);
606 /* cabinet does not exist */
607 ZeroMemory(&session
, sizeof(SESSION
));
608 lstrcpyA(session
.Destination
, "dest");
609 session
.Operation
= EXTRACT_FILLFILELIST
| EXTRACT_EXTRACTFILES
;
610 res
= pExtract(&session
, "nonexistent.cab");
611 node
= session
.FileList
;
612 ok(res
== HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
),
613 "Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %08x\n", res
);
614 ok(session
.Error
.erfOper
== FDIERROR_CABINET_NOT_FOUND
,
615 "Expected FDIERROR_CABINET_NOT_FOUND, got %d\n", session
.Error
.erfOper
);
616 ok(session
.FileSize
== 0, "Expected 0, got %d\n", session
.FileSize
);
617 ok(session
.Error
.erfType
== 0, "Expected 0, got %d\n", session
.Error
.erfType
);
618 ok(session
.Error
.fError
== TRUE
, "Expected TRUE, got %d\n", session
.Error
.fError
);
619 ok(session
.FileCount
== 0, "Expected 0, got %d\n", session
.FileCount
);
620 ok(session
.Operation
== (EXTRACT_FILLFILELIST
| EXTRACT_EXTRACTFILES
),
621 "Expected EXTRACT_FILLFILELIST | EXTRACT_EXTRACTFILES, got %d\n", session
.Operation
);
622 ok(!lstrcmpA(session
.Destination
, "dest"), "Expected dest, got %s\n", session
.Destination
);
623 ok(!*session
.CurrentFile
, "Expected empty string, got %s\n", session
.CurrentFile
);
624 ok(!*session
.Reserved
, "Expected empty string, got %s\n", session
.Reserved
);
625 ok(!session
.FilterList
, "Expected empty filter list\n");
626 ok(!DeleteFileA("dest\\a.txt"), "Expected dest\\a.txt to not exist\n");
627 ok(!DeleteFileA("dest\\b.txt"), "Expected dest\\b.txt to not exist\n");
628 ok(!DeleteFileA("dest\\testdir\\c.txt"), "Expected dest\\testdir\\c.txt to not exist\n");
629 ok(!DeleteFileA("dest\\testdir\\d.txt"), "Expected dest\\testdir\\d.txt to not exist\n");
630 ok(!check_list(&node
, "testdir\\d.txt", FALSE
), "list entry should not exist\n");
631 ok(!check_list(&node
, "testdir\\c.txt", FALSE
), "list entry should not exist\n");
632 ok(!check_list(&node
, "b.txt", FALSE
), "list entry should not exist\n");
633 ok(!check_list(&node
, "a.txt", FALSE
), "list entry should not exist\n");
634 free_file_list(&session
);
636 /* first file exists but is read-only */
637 createTestFile("dest\\a.txt");
638 SetFileAttributesA("dest\\a.txt", FILE_ATTRIBUTE_READONLY
);
639 ok(getFileSize("dest\\a.txt") == 11, "Expected dest\\a.txt to be 11 bytes\n");
640 ZeroMemory(&session
, sizeof(SESSION
));
641 lstrcpyA(session
.Destination
, "dest");
642 session
.Operation
= EXTRACT_FILLFILELIST
| EXTRACT_EXTRACTFILES
;
643 res
= pExtract(&session
, "extract.cab");
644 node
= session
.FileList
;
645 ok(res
== HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED
) || res
== E_FAIL
,
646 "Expected HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED) or E_FAIL, got %08x\n", res
);
647 ok(session
.FileSize
== 6, "Expected 6, got %d\n", session
.FileSize
);
648 ok(session
.Error
.erfOper
== FDIERROR_USER_ABORT
,
649 "Expected FDIERROR_USER_ABORT, got %d\n", session
.Error
.erfOper
);
650 ok(session
.Error
.fError
== TRUE
, "Expected TRUE, got %d\n", session
.Error
.fError
);
651 ok(session
.FileCount
== 1, "Expected 1, got %d\n", session
.FileCount
);
652 ok(!lstrcmpA(session
.CurrentFile
, "dest\\a.txt"),
653 "Expected dest\\a.txt, got %s\n", session
.CurrentFile
);
654 ok(session
.Error
.erfType
== 0, "Expected 0, got %d\n", session
.Error
.erfType
);
655 ok(session
.Operation
== (EXTRACT_FILLFILELIST
| EXTRACT_EXTRACTFILES
),
656 "Expected EXTRACT_FILLFILELIST | EXTRACT_EXTRACTFILES, got %d\n", session
.Operation
);
657 ok(!lstrcmpA(session
.Destination
, "dest"), "Expected dest, got %s\n", session
.Destination
);
658 ok(!*session
.Reserved
, "Expected empty string, got %s\n", session
.Reserved
);
659 ok(!session
.FilterList
, "Expected empty filter list\n");
660 ok(getFileSize("dest\\a.txt") == 11, "Expected dest\\a.txt to be 11 bytes\n");
661 ok(!DeleteFileA("dest\\a.txt"), "Expected dest\\a.txt to be read-only\n");
662 ok(!DeleteFileA("dest\\b.txt"), "Expected dest\\b.txt to not exist\n");
663 ok(!DeleteFileA("dest\\testdir\\c.txt"), "Expected dest\\testdir\\c.txt to not exist\n");
664 ok(!DeleteFileA("dest\\testdir\\d.txt"), "Expected dest\\testdir\\d.txt to not exist\n");
665 ok(!check_list(&node
, "testdir\\d.txt", FALSE
), "list entry should not exist\n");
666 ok(!check_list(&node
, "testdir\\c.txt", FALSE
), "list entry should not exist\n");
667 ok(!check_list(&node
, "b.txt", FALSE
), "list entry should not exist\n");
668 ok(!check_list(&node
, "a.txt", FALSE
), "list entry should not exist\n");
669 free_file_list(&session
);
671 SetFileAttributesA("dest\\a.txt", FILE_ATTRIBUTE_NORMAL
);
672 DeleteFileA("dest\\a.txt");
674 /* first file exists and is writable, third file exists but is read-only */
675 createTestFile("dest\\a.txt");
676 createTestFile("dest\\testdir\\c.txt");
677 SetFileAttributesA("dest\\testdir\\c.txt", FILE_ATTRIBUTE_READONLY
);
678 ZeroMemory(&session
, sizeof(SESSION
));
679 lstrcpyA(session
.Destination
, "dest");
680 session
.Operation
= EXTRACT_FILLFILELIST
| EXTRACT_EXTRACTFILES
;
681 res
= pExtract(&session
, "extract.cab");
682 node
= session
.FileList
;
683 ok(res
== HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED
) || res
== E_FAIL
,
684 "Expected HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED) or E_FAIL, got %08x\n", res
);
685 ok(session
.FileSize
== 26, "Expected 26, got %d\n", session
.FileSize
);
686 ok(session
.Error
.erfOper
== FDIERROR_USER_ABORT
,
687 "Expected FDIERROR_USER_ABORT, got %d\n", session
.Error
.erfOper
);
688 ok(session
.Error
.fError
== TRUE
, "Expected TRUE, got %d\n", session
.Error
.fError
);
689 ok(session
.FileCount
== 3, "Expected 3, got %d\n", session
.FileCount
);
690 ok(!lstrcmpA(session
.CurrentFile
, "dest\\testdir\\c.txt"),
691 "Expected dest\\c.txt, got %s\n", session
.CurrentFile
);
692 ok(session
.Error
.erfType
== 0, "Expected 0, got %d\n", session
.Error
.erfType
);
693 ok(session
.Operation
== (EXTRACT_FILLFILELIST
| EXTRACT_EXTRACTFILES
),
694 "Expected EXTRACT_FILLFILELIST | EXTRACT_EXTRACTFILES, got %d\n", session
.Operation
);
695 ok(!lstrcmpA(session
.Destination
, "dest"), "Expected dest, got %s\n", session
.Destination
);
696 ok(!*session
.Reserved
, "Expected empty string, got %s\n", session
.Reserved
);
697 ok(!session
.FilterList
, "Expected empty filter list\n");
698 ok(getFileSize("dest\\a.txt") == 6, "Expected dest\\a.txt to be 6 bytes\n");
699 ok(DeleteFileA("dest\\a.txt"), "Expected dest\\a.txt to exist\n");
700 ok(DeleteFileA("dest\\b.txt"), "Expected dest\\b.txt to exist\n");
701 ok(!DeleteFileA("dest\\testdir\\c.txt"), "Expected dest\\testdir\\c.txt to be read-only\n");
702 ok(!DeleteFileA("dest\\testdir\\d.txt"), "Expected dest\\testdir\\d.txt to not exist\n");
703 ok(!check_list(&node
, "testdir\\d.txt", FALSE
), "list entry should not exist\n");
704 ok(!check_list(&node
, "testdir\\c.txt", FALSE
), "list entry wrong\n");
705 ok(!check_list(&node
, "b.txt", FALSE
), "list entry wrong\n");
706 ok(!check_list(&node
, "a.txt", TRUE
), "list entry wrong\n");
707 free_file_list(&session
);
709 SetFileAttributesA("dest\\testdir\\c.txt", FILE_ATTRIBUTE_NORMAL
);
710 DeleteFileA("dest\\testdir\\c.txt");
712 ok(RemoveDirectoryA("dest\\testdir"), "Expected dest\\testdir to exist\n");
713 ok(RemoveDirectoryA("dest"), "Expected dest to exist\n");
718 init_function_pointers();