ReactOS 0.4.15-dev-7953-g1f49173
extract.c
Go to the documentation of this file.
1/*
2 * Unit tests for cabinet.dll extract functions
3 *
4 * Copyright (C) 2006 James Hawkins
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#include <stdio.h>
22#include <windows.h>
23#include "fci.h"
24#include "fdi.h"
25#include "wine/test.h"
26
27/* make the max size large so there is only one cab file */
28#define MEDIA_SIZE 999999999
29#define FOLDER_THRESHOLD 900000
30
31/* The following definitions were copied from dlls/cabinet/cabinet.h
32 * because they are undocumented in windows.
33 */
34
35/* SESSION Operation */
36#define EXTRACT_FILLFILELIST 0x00000001
37#define EXTRACT_EXTRACTFILES 0x00000002
38
39struct FILELIST{
41 struct FILELIST *next;
43};
44
45typedef struct {
47 ERF Error;
48 struct FILELIST *FileList;
52 CHAR CurrentFile[MAX_PATH];
54 struct FILELIST *FilterList;
55} SESSION;
56
57/* function pointers */
59static HRESULT (WINAPI *pExtract)(SESSION*, LPCSTR);
60
62
63static void init_function_pointers(void)
64{
65 hCabinet = GetModuleHandleA("cabinet.dll");
66
67 pExtract = (void *)GetProcAddress(hCabinet, "Extract");
68}
69
70/* creates a file with the specified name for tests */
71static void createTestFile(const CHAR *name)
72{
74 DWORD written;
75
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);
81}
82
83static int getFileSize(const CHAR *name)
84{
86 int size;
89 return -1;
92 return size;
93}
94
95static void create_test_files(void)
96{
97 int len;
98
101
102 if(len && (CURR_DIR[len-1] == '\\'))
103 CURR_DIR[len-1] = 0;
104
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);
111}
112
113static void delete_test_files(void)
114{
115 DeleteFileA("a.txt");
116 DeleteFileA("b.txt");
117 DeleteFileA("testdir\\c.txt");
118 DeleteFileA("testdir\\d.txt");
119 RemoveDirectoryA("testdir");
120
121 DeleteFileA("extract.cab");
122}
123
124/* the FCI callbacks */
125
126static void * CDECL mem_alloc(ULONG cb)
127{
128 return HeapAlloc(GetProcessHeap(), 0, cb);
129}
130
131static void CDECL mem_free(void *memory)
132{
134}
135
136static BOOL CDECL get_next_cabinet(PCCAB pccab, ULONG cbPrevCab, void *pv)
137{
138 return TRUE;
139}
140
141static LONG CDECL progress(UINT typeStatus, ULONG cb1, ULONG cb2, void *pv)
142{
143 return 0;
144}
145
146static int CDECL file_placed(PCCAB pccab, char *pszFile, LONG cbFile,
147 BOOL fContinuation, void *pv)
148{
149 return 0;
150}
151
152static INT_PTR CDECL fci_open(char *pszFile, int oflag, int pmode, int *err, void *pv)
153{
155 DWORD dwAccess = 0;
156 DWORD dwShareMode = 0;
157 DWORD dwCreateDisposition = OPEN_EXISTING;
158
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;
162
164 dwCreateDisposition = OPEN_EXISTING;
165 else
166 dwCreateDisposition = CREATE_NEW;
167
168 handle = CreateFileA(pszFile, dwAccess, dwShareMode, NULL,
169 dwCreateDisposition, 0, NULL);
170
171 ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszFile);
172
173 return (INT_PTR)handle;
174}
175
176static UINT CDECL fci_read(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
177{
178 HANDLE handle = (HANDLE)hf;
179 DWORD dwRead;
180 BOOL res;
181
182 res = ReadFile(handle, memory, cb, &dwRead, NULL);
183 ok(res, "Failed to ReadFile\n");
184
185 return dwRead;
186}
187
188static UINT CDECL fci_write(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
189{
190 HANDLE handle = (HANDLE)hf;
191 DWORD dwWritten;
192 BOOL res;
193
194 res = WriteFile(handle, memory, cb, &dwWritten, NULL);
195 ok(res, "Failed to WriteFile\n");
196
197 return dwWritten;
198}
199
200static int CDECL fci_close(INT_PTR hf, int *err, void *pv)
201{
202 HANDLE handle = (HANDLE)hf;
203 ok(CloseHandle(handle), "Failed to CloseHandle\n");
204
205 return 0;
206}
207
208static LONG CDECL fci_seek(INT_PTR hf, LONG dist, int seektype, int *err, void *pv)
209{
210 HANDLE handle = (HANDLE)hf;
211 DWORD ret;
212
213 ret = SetFilePointer(handle, dist, NULL, seektype);
214 ok(ret != INVALID_SET_FILE_POINTER, "Failed to SetFilePointer\n");
215
216 return ret;
217}
218
219static int CDECL fci_delete(char *pszFile, int *err, void *pv)
220{
221 BOOL ret = DeleteFileA(pszFile);
222 ok(ret, "Failed to DeleteFile %s\n", pszFile);
223
224 return 0;
225}
226
227static BOOL CDECL get_temp_file(char *pszTempName, int cbTempName, void *pv)
228{
229 LPSTR tempname;
230
231 tempname = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
232 GetTempFileNameA(".", "xx", 0, tempname);
233
234 if (tempname && (strlen(tempname) < (unsigned)cbTempName))
235 {
236 lstrcpyA(pszTempName, tempname);
237 HeapFree(GetProcessHeap(), 0, tempname);
238 return TRUE;
239 }
240
241 HeapFree(GetProcessHeap(), 0, tempname);
242
243 return FALSE;
244}
245
246static INT_PTR CDECL get_open_info(char *pszName, USHORT *pdate, USHORT *ptime,
247 USHORT *pattribs, int *err, void *pv)
248{
252 DWORD attrs;
253 BOOL res;
254
257
258 ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszName);
259
261 ok(res, "Expected GetFileInformationByHandle to succeed\n");
262
264 FileTimeToDosDateTime(&filetime, pdate, ptime);
265
266 attrs = GetFileAttributesA(pszName);
267 ok(attrs != INVALID_FILE_ATTRIBUTES, "Failed to GetFileAttributes\n");
268
269 return (INT_PTR)handle;
270}
271
272static void add_file(HFCI hfci, char *file)
273{
274 char path[MAX_PATH];
275 BOOL res;
276
278 lstrcatA(path, "\\");
280
283 ok(res, "Expected FCIAddFile to succeed\n");
284}
285
286static void set_cab_parameters(PCCAB pCabParams)
287{
288 ZeroMemory(pCabParams, sizeof(CCAB));
289
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");
296}
297
298static void create_cab_file(void)
299{
300 CCAB cabParams;
301 HFCI hfci;
302 ERF erf;
303 static CHAR a_txt[] = "a.txt",
304 b_txt[] = "b.txt",
305 testdir_c_txt[] = "testdir\\c.txt",
306 testdir_d_txt[] = "testdir\\d.txt";
307 BOOL res;
308
309 set_cab_parameters(&cabParams);
310
313 get_temp_file, &cabParams, NULL);
314
315 ok(hfci != NULL, "Failed to create an FCI context\n");
316
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);
321
323 ok(res, "Failed to flush the cabinet\n");
324
325 res = FCIDestroy(hfci);
326 ok(res, "Failed to destroy the cabinet\n");
327}
328
329static BOOL check_list(struct FILELIST **node, const char *filename, BOOL do_extract)
330{
331 if (!*node)
332 return FALSE;
333
334 if (lstrcmpA((*node)->FileName, filename))
335 return FALSE;
336
337 if ((*node)->DoExtract != do_extract)
338 return FALSE;
339
340 *node = (*node)->next;
341 return TRUE;
342}
343
344static void free_file_node(struct FILELIST *node)
345{
346 HeapFree(GetProcessHeap(), 0, node->FileName);
348}
349
351{
352 struct FILELIST *next, *curr = session->FileList;
353
354 while (curr)
355 {
356 next = curr->next;
357 free_file_node(curr);
358 curr = next;
359 }
360
361 session->FileList = NULL;
362}
363
364static void test_Extract(void)
365{
367 HRESULT res;
368 struct FILELIST *node;
369
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
374 */
375
376 /* try to extract all files */
377 ZeroMemory(&session, sizeof(SESSION));
378 lstrcpyA(session.Destination, "dest");
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);
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");
406
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");
433
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");
462
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");
488
489 /* remove two of the files in the list */
490 node = session.FileList->next;
491 session.FileList->next = session.FileList->next->next;
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");
522
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");
549
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");
574
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");
605
606 /* cabinet does not exist */
607 ZeroMemory(&session, sizeof(SESSION));
608 lstrcpyA(session.Destination, "dest");
610 res = pExtract(&session, "nonexistent.cab");
611 node = session.FileList;
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);
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");
635
636 /* first file exists but is read-only */
637 createTestFile("dest\\a.txt");
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");
643 res = pExtract(&session, "extract.cab");
644 node = session.FileList;
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);
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");
670
672 DeleteFileA("dest\\a.txt");
673
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");
681 res = pExtract(&session, "extract.cab");
682 node = session.FileList;
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);
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");
708
709 SetFileAttributesA("dest\\testdir\\c.txt", FILE_ATTRIBUTE_NORMAL);
710 DeleteFileA("dest\\testdir\\c.txt");
711
712 ok(RemoveDirectoryA("dest\\testdir"), "Expected dest\\testdir to exist\n");
713 ok(RemoveDirectoryA("dest"), "Expected dest to exist\n");
714}
715
717{
721
722 test_Extract();
723
725}
vector< FileInfo > FileList
Definition: DriveVolume.h:63
LIST_ENTRY FilterList
Definition: Filter.c:24
PULONG FileCount
Definition: SfcGetFiles.c:18
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define ok(value,...)
Definition: atltest.h:57
#define START_TEST(x)
Definition: atltest.h:75
BOOL Error
Definition: chkdsk.c:66
cd_progress_ptr progress
Definition: cdjpeg.h:152
#define E_FAIL
Definition: ddrawi.h:102
#define mem_free(ptr, bsize)
Definition: types.h:124
#define NULL
Definition: types.h:112
#define mem_alloc(bsize)
Definition: types.h:123
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CDECL
Definition: compat.h:29
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define INVALID_SET_FILE_POINTER
Definition: compat.h:732
#define OPEN_EXISTING
Definition: compat.h:775
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
#define SetFilePointer
Definition: compat.h:743
#define GetProcAddress(x, y)
Definition: compat.h:753
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:740
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
#define FILE_SHARE_READ
Definition: compat.h:136
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
BOOL WINAPI RemoveDirectoryA(IN LPCSTR lpPathName)
Definition: dir.c:714
BOOL WINAPI CreateDirectoryA(IN LPCSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:37
BOOL WINAPI GetFileInformationByHandle(HANDLE hFile, LPBY_HANDLE_FILE_INFORMATION lpFileInformation)
Definition: fileinfo.c:458
BOOL WINAPI SetFileAttributesA(LPCSTR lpFileName, DWORD dwFileAttributes)
Definition: fileinfo.c:776
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:331
DWORD WINAPI GetFileAttributesA(LPCSTR lpFileName)
Definition: fileinfo.c:636
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
DWORD WINAPI GetCurrentDirectoryA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2146
BOOL WINAPI FileTimeToLocalFileTime(IN CONST FILETIME *lpFileTime, OUT LPFILETIME lpLocalFileTime)
Definition: time.c:221
BOOL WINAPI FileTimeToDosDateTime(IN CONST FILETIME *lpFileTime, OUT LPWORD lpFatDate, OUT LPWORD lpFatTime)
Definition: time.c:37
static void extract(LPCWSTR cabfile, LPWSTR destdir)
Definition: extrac32.c:99
static CHAR CURR_DIR[MAX_PATH]
Definition: extract.c:61
#define MEDIA_SIZE
Definition: extract.c:28
static BOOL CDECL get_next_cabinet(PCCAB pccab, ULONG cbPrevCab, void *pv)
Definition: extract.c:136
static void createTestFile(const CHAR *name)
Definition: extract.c:71
static BOOL check_list(struct FILELIST **node, const char *filename, BOOL do_extract)
Definition: extract.c:329
static void delete_test_files(void)
Definition: extract.c:113
static HMODULE hCabinet
Definition: extract.c:58
#define EXTRACT_EXTRACTFILES
Definition: extract.c:37
static void init_function_pointers(void)
Definition: extract.c:63
static UINT CDECL fci_write(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
Definition: extract.c:188
static void add_file(HFCI hfci, char *file)
Definition: extract.c:272
static BOOL CDECL get_temp_file(char *pszTempName, int cbTempName, void *pv)
Definition: extract.c:227
static void set_cab_parameters(PCCAB pCabParams)
Definition: extract.c:286
static UINT CDECL fci_read(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
Definition: extract.c:176
#define FOLDER_THRESHOLD
Definition: extract.c:29
static void create_test_files(void)
Definition: extract.c:95
static void free_file_list(SESSION *session)
Definition: extract.c:350
static INT_PTR CDECL get_open_info(char *pszName, USHORT *pdate, USHORT *ptime, USHORT *pattribs, int *err, void *pv)
Definition: extract.c:246
static void free_file_node(struct FILELIST *node)
Definition: extract.c:344
static INT_PTR CDECL fci_open(char *pszFile, int oflag, int pmode, int *err, void *pv)
Definition: extract.c:152
static void create_cab_file(void)
Definition: extract.c:298
static int CDECL fci_delete(char *pszFile, int *err, void *pv)
Definition: extract.c:219
#define EXTRACT_FILLFILELIST
Definition: extract.c:36
static int CDECL file_placed(PCCAB pccab, char *pszFile, LONG cbFile, BOOL fContinuation, void *pv)
Definition: extract.c:146
static LONG CDECL fci_seek(INT_PTR hf, LONG dist, int seektype, int *err, void *pv)
Definition: extract.c:208
static LPCSTR
Definition: extract.c:59
static int getFileSize(const CHAR *name)
Definition: extract.c:83
static int CDECL fci_close(INT_PTR hf, int *err, void *pv)
Definition: extract.c:200
static void test_Extract(void)
Definition: extract.c:364
BOOL __cdecl FCIAddFile(HFCI hfci, char *pszSourceFile, char *pszFileName, BOOL fExecute, PFNFCIGETNEXTCABINET pfnfcignc, PFNFCISTATUS pfnfcis, PFNFCIGETOPENINFO pfnfcigoi, TCOMP typeCompress)
Definition: fci.c:1397
BOOL __cdecl FCIDestroy(HFCI hfci)
Definition: fci.c:1709
HFCI __cdecl FCICreate(PERF perf, PFNFCIFILEPLACED pfnfiledest, PFNFCIALLOC pfnalloc, PFNFCIFREE pfnfree, PFNFCIOPEN pfnopen, PFNFCIREAD pfnread, PFNFCIWRITE pfnwrite, PFNFCICLOSE pfnclose, PFNFCISEEK pfnseek, PFNFCIDELETE pfndelete, PFNFCIGETTEMPFILE pfnfcigtf, PCCAB pccab, void *pv)
Definition: fci.c:998
BOOL __cdecl FCIFlushCabinet(HFCI hfci, BOOL fGetNextCab, PFNFCIGETNEXTCABINET pfnfcignc, PFNFCISTATUS pfnfcis)
Definition: fci.c:1675
#define tcompTYPE_MSZIP
Definition: fci.h:65
@ FDIERROR_USER_ABORT
Definition: fdi.h:126
@ FDIERROR_NONE
Definition: fdi.h:115
@ FDIERROR_CABINET_NOT_FOUND
Definition: fdi.h:116
UINT WINAPI GetTempFileNameA(IN LPCSTR lpPathName, IN LPCSTR lpPrefixString, IN UINT uUnique, OUT LPSTR lpTempFileName)
Definition: filename.c:26
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
FP_OP Operation
Definition: fpcontrol.c:150
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
GLsizeiptr size
Definition: glext.h:5919
GLuint res
Definition: glext.h:9613
GLenum GLsizei len
Definition: glext.h:6722
#define S_OK
Definition: intsafe.h:52
const char * filename
Definition: ioapi.h:137
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
int WINAPI lstrcmpA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:18
LPSTR WINAPI lstrcatA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:123
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
double __cdecl erf(double)
#define CREATE_ALWAYS
Definition: disk.h:72
#define CREATE_NEW
Definition: disk.h:69
#define FILE_FLAG_SEQUENTIAL_SCAN
Definition: disk.h:43
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static HMODULE MODULEINFO DWORD cb
Definition: module.c:33
static char memory[1024 *256]
Definition: process.c:116
unsigned int UINT
Definition: ndis.h:50
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:3004
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define GENERIC_WRITE
Definition: nt_native.h:90
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
static unsigned __int64 next
Definition: rand_nt.c:6
#define err(...)
Definition: fci.h:144
ULONG cbFolderThresh
Definition: fci.h:146
USHORT setID
Definition: fci.h:157
char szCabPath[CB_MAX_CAB_PATH]
Definition: fci.h:161
ULONG cb
Definition: fci.h:145
char szCab[CB_MAX_CABINET_NAME]
Definition: fci.h:160
Definition: fci.h:44
struct FILELIST * next
Definition: files.c:549
LPSTR FileName
Definition: files.c:548
BOOL DoExtract
Definition: files.c:550
Definition: files.c:553
Definition: fci.c:127
Definition: name.c:39
int32_t INT_PTR
Definition: typedefs.h:64
PVOID HANDLE
Definition: typedefs.h:73
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59
Definition: dlist.c:348
void * next
Definition: dlist.c:360
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
int ret
#define ZeroMemory
Definition: winbase.h:1712
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
#define HRESULT
Definition: msvc.h:7
#define WINAPI
Definition: msvc.h:6
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
char * LPSTR
Definition: xmlstorage.h:182
char CHAR
Definition: xmlstorage.h:175