Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/dlls/cabinet/tests/extract.c
4393 views
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
39
struct FILELIST{
40
LPSTR FileName;
41
struct FILELIST *next;
42
BOOL DoExtract;
43
};
44
45
typedef struct {
46
INT FileSize;
47
ERF Error;
48
struct FILELIST *FileList;
49
INT FileCount;
50
INT Operation;
51
CHAR Destination[MAX_PATH];
52
CHAR CurrentFile[MAX_PATH];
53
CHAR Reserved[MAX_PATH];
54
struct FILELIST *FilterList;
55
} SESSION;
56
57
/* function pointers */
58
static HMODULE hCabinet;
59
static HRESULT (WINAPI *pExtract)(SESSION*, LPCSTR);
60
61
static CHAR CURR_DIR[MAX_PATH];
62
63
static 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 */
71
static void createTestFile(const CHAR *name)
72
{
73
HANDLE file;
74
DWORD written;
75
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);
80
CloseHandle(file);
81
}
82
83
static int getFileSize(const CHAR *name)
84
{
85
HANDLE file;
86
int size;
87
file = CreateFileA(name, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
88
if (file == INVALID_HANDLE_VALUE)
89
return -1;
90
size = GetFileSize(file, NULL);
91
CloseHandle(file);
92
return size;
93
}
94
95
static void create_test_files(void)
96
{
97
int len;
98
99
GetCurrentDirectoryA(MAX_PATH, CURR_DIR);
100
len = lstrlenA(CURR_DIR);
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
113
static 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
126
static void * CDECL mem_alloc(ULONG cb)
127
{
128
return HeapAlloc(GetProcessHeap(), 0, cb);
129
}
130
131
static void CDECL mem_free(void *memory)
132
{
133
HeapFree(GetProcessHeap(), 0, memory);
134
}
135
136
static BOOL CDECL get_next_cabinet(PCCAB pccab, ULONG cbPrevCab, void *pv)
137
{
138
return TRUE;
139
}
140
141
static LONG CDECL progress(UINT typeStatus, ULONG cb1, ULONG cb2, void *pv)
142
{
143
return 0;
144
}
145
146
static int CDECL file_placed(PCCAB pccab, char *pszFile, LONG cbFile,
147
BOOL fContinuation, void *pv)
148
{
149
return 0;
150
}
151
152
static INT_PTR CDECL fci_open(char *pszFile, int oflag, int pmode, int *err, void *pv)
153
{
154
HANDLE handle;
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
163
if (GetFileAttributesA(pszFile) != INVALID_FILE_ATTRIBUTES)
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
176
static 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
188
static 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
200
static 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
208
static 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
219
static 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
227
static 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
246
static INT_PTR CDECL get_open_info(char *pszName, USHORT *pdate, USHORT *ptime,
247
USHORT *pattribs, int *err, void *pv)
248
{
249
BY_HANDLE_FILE_INFORMATION finfo;
250
FILETIME filetime;
251
HANDLE handle;
252
DWORD attrs;
253
BOOL res;
254
255
handle = CreateFileA(pszName, GENERIC_READ, FILE_SHARE_READ, NULL,
256
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
257
258
ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszName);
259
260
res = GetFileInformationByHandle(handle, &finfo);
261
ok(res, "Expected GetFileInformationByHandle to succeed\n");
262
263
FileTimeToLocalFileTime(&finfo.ftLastWriteTime, &filetime);
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
272
static void add_file(HFCI hfci, char *file)
273
{
274
char path[MAX_PATH];
275
BOOL res;
276
277
lstrcpyA(path, CURR_DIR);
278
lstrcatA(path, "\\");
279
lstrcatA(path, file);
280
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");
284
}
285
286
static 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
298
static 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
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);
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
322
res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
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
329
static 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
344
static void free_file_node(struct FILELIST *node)
345
{
346
HeapFree(GetProcessHeap(), 0, node->FileName);
347
HeapFree(GetProcessHeap(), 0, node);
348
}
349
350
static void free_file_list(SESSION* session)
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
364
static void test_Extract(void)
365
{
366
SESSION session;
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");
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 %ld\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);
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 %ld\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 %ld\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 %ld\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;
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 %ld\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);
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 %ld\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 %ld\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 %ld\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);
605
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 %08lx\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);
635
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 %08lx\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);
670
671
SetFileAttributesA("dest\\a.txt", FILE_ATTRIBUTE_NORMAL);
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");
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 %08lx\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);
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
716
START_TEST(extract)
717
{
718
init_function_pointers();
719
create_test_files();
720
create_cab_file();
721
722
test_Extract();
723
724
delete_test_files();
725
}
726
727