version 1.8, 2005/02/11 09:56:01
|
version 2.2, 2005/02/15 07:11:25
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
*/ | */ |
| |
|
//#include <windows.h> |
#include <stdlib.h> | #include <stdlib.h> |
|
#include <string.h> |
|
//#include <io.h> |
|
//#include <fcntl.h> |
|
//#include <dos.h> |
|
#include <sys/stat.h> |
| |
#ifndef STANDALONE | #ifndef STANDALONE |
#include <wine/test.h> | #include <wine/test.h> |
|
|
static int fakeFD = 22881; | static int fakeFD = 22881; |
| |
/* | /* |
This hex data is the output of compress.exe (Windows Server 2003 Resource Kit) |
This hex data is the output of makecab.exe (Windows Cabinet SDK/bin) |
|
****** IS USING THE OUTPUT OF A NON LGPL program okay ****** |
| |
The cab file is mirrored in the file system as simple.cab | The cab file is mirrored in the file system as simple.cab |
| |
|
|
0xD2,0x32,0x8B,0x33,0xF4,0xB8,0x00}; | 0xD2,0x32,0x8B,0x33,0xF4,0xB8,0x00}; |
static int szcompressed_file = sizeof(compressed_file); | static int szcompressed_file = sizeof(compressed_file); |
| |
|
|
/* | /* |
static const char uncompressed_data[] = "This is a test file."; |
Multiple File Cabs are included, as cabinet.dll supports multiple file archive types. |
static const DWORD uncompressed_data_size = sizeof(uncompressed_data) - 1; |
The compressed file size had to be greater than 50k, cabarc restricts 'diskette spanning' to |
|
archives above 50k. |
|
The peculiar options were selected specifically to test cabinet.dll more throughly. |
| |
static char *buf; |
complex_lzw.cab cabarc -m LZX:16 -pr -i 32356 N complex_lzw.cab amontillado.txt lgpl.txt gpl.txt midsummer\* |
*/ |
complex_lzw2.cab cabarc -m LZX:17 -d 50000 -pr -i 32356 N complex_lzw*.cab amontillado.txt + lgpl.txt gpl.txt midsummer\* |
|
|
|
complex_zip.cab cabarc -m MSZIP -pr -i 32356 N complex_lzw.cab amontillado.txt lgpl.txt gpl.txt midsummer\* |
|
complex_zip2.cab cabarc -m MSZIP -d 50000 -pr -i 32356 N complex_zip*.cab amontillado.txt + lgpl.txt gpl.txt midsummer\* |
|
|
|
complex_none.cab cabarc -m NONE -pr -i 32356 N complex_none.cab amontillado.txt midsummer\act1* |
| |
/* | /* |
To do in FDI: -from wine/include/fdi.h | To do in FDI: -from wine/include/fdi.h |
|
|
FDIDestroy | FDIDestroy |
*/ | */ |
| |
/* Currently mostly dummy function pointers */ |
|
|
|
#ifndef DEBUG_ALLOC | #ifndef DEBUG_ALLOC |
FNALLOC(final_alloc) { | FNALLOC(final_alloc) { |
return malloc(cb); | return malloc(cb); |
|
|
| |
| |
/* | /* |
It is not necessary for these functions to actually call _open etc.; |
|
these functions could instead call fopen, fread, fwrite, fclose, and fseek, |
|
or CreateFile, ReadFile, WriteFile, CloseHandle, and SetFilePointer, etc. |
|
However, the parameters and return codes will have to be translated |
|
appropriately (e.g. the file open mode passed in to pfnopen). |
|
|
|
Match i/o specs of _open, _read, _write, _close, and _lseek. | Match i/o specs of _open, _read, _write, _close, and _lseek. |
|
|
*/ | */ |
| |
/* | /* |
|
|
} | } |
| |
| |
|
|
|
|
|
|
FNWRITE(dummy_write) { | FNWRITE(dummy_write) { |
printf(" FNWRITE just called with %d, %d, %d\n",hf, pv, cb); | printf(" FNWRITE just called with %d, %d, %d\n",hf, pv, cb); |
return 0; | return 0; |
} | } |
| |
|
FNWRITE(real_write) { |
|
int write_value = _write(hf, pv, cb); |
|
printf(" FNWRITE just called with %d, %d, %d - returning %d\n",hf, pv, cb, write_value); |
|
return write_value; |
|
} |
|
|
|
|
|
|
|
|
FNSEEK(dummy_seek) { | FNSEEK(dummy_seek) { |
printf(" FNSEEK just called with %d, %d, %d\n",hf, dist, seektype); | printf(" FNSEEK just called with %d, %d, %d\n",hf, dist, seektype); |
return 0; | return 0; |
} | } |
| |
|
FNSEEK(real_seek) { |
|
long lseek_value = _lseek(hf, dist, seektype); |
|
printf(" FNSEEK just called with %d, %d, %d - returning %d\n",hf, dist, seektype,lseek_value); |
|
return lseek_value; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
FNFDINOTIFY(dummy_notification){ |
|
printf(" FNFDINOTIFY just called with %d, %d \n",fdint,pfdin); |
|
return 0; |
|
} |
|
|
|
FNFDINOTIFY(notification_function) |
|
{ |
|
printf(" FNFDINOTIFY real just called with %d, %d \n",fdint,pfdin); |
|
switch (fdint) |
|
{ |
|
case fdintCABINET_INFO: |
|
{ |
|
printf("fdintCABINET_INFO\n"); |
|
return 0; |
|
} |
|
case fdintPARTIAL_FILE: |
|
{ |
|
printf("dintPARTIAL_FILE\n"); |
|
return 0; |
|
} |
|
case fdintCOPY_FILE: |
|
{ |
|
int fih = 0; |
|
char target[256]; |
|
|
|
printf("fdintCOPY_FILE\n"); |
|
printf(" file name: %s\n", pfdin->psz1); |
|
sprintf(target, "./%s",pfdin->psz1); |
|
printf("%s\n",target); |
|
|
|
fih = real_open( |
|
target, |
|
_O_BINARY | _O_CREAT | _O_WRONLY | _O_SEQUENTIAL, |
|
_S_IREAD | _S_IWRITE |
|
); |
|
|
|
return fih; |
|
} |
|
|
|
|
|
case fdintCLOSE_FILE_INFO: |
|
{ |
|
|
|
printf("fdintCLOSE_FILE_INFO\n"); |
|
return 0; |
|
} |
|
case fdintNEXT_CABINET: |
|
{ |
|
|
|
printf("fdintNEXT_CABINET\n"); |
|
return 0; |
|
} |
|
case fdintENUMERATE: |
|
{ |
|
printf("fdintENUMERATE\n"); |
|
return 0; |
|
} |
|
} |
|
return 0; |
|
} |
|
|
|
|
|
|
|
|
|
static void printCabInfo(FDICABINETINFO cabinfo){ |
|
//printf("INSIDE PRINT CABINFO\n"); |
|
printf("Cabinet Data : cbC %d cF %d cFi %d si %d iC %d fr %b hp %d hn %d\n", |
|
cabinfo.cbCabinet, |
|
cabinfo.cFolders , |
|
cabinfo.cFiles , |
|
cabinfo.setID, |
|
cabinfo.iCabinet, |
|
cabinfo.fReserve , |
|
cabinfo.hasprev , |
|
cabinfo.hasnext ); |
|
} |
|
|
|
static void CheckCabInfo(char * cabname, |
|
FDICABINETINFO cabinfo, |
|
long TcbCabinet, |
|
USHORT TcFolders, |
|
USHORT TcFiles, |
|
USHORT TsetID, |
|
USHORT TiCabinet, |
|
BOOL TfReserve, |
|
BOOL Thasprev, |
|
BOOL Thasnext){ |
|
|
|
ok2 ( cabinfo.cbCabinet == TcbCabinet, "FDIIsCabinet,cabinfo %s data did not match! Failed!\n", cabname); |
|
ok2 ( cabinfo.cFolders == TcFolders, "FDIIsCabinet,cabinfo %s data did not match! Failed!\n", cabname); |
|
ok2 ( cabinfo.cFiles == TcFiles, "FDIIsCabinet,cabinfo %s data did not match! Failed!\n", cabname); |
|
ok2 ( cabinfo.setID == TsetID, "FDIIsCabinet,cabinfo %s data did not match! Failed!\n", cabname); |
|
ok2 ( cabinfo.iCabinet == TiCabinet, "FDIIsCabinet,cabinfo %s data did not match! Failed!\n", cabname); |
|
ok2 ( cabinfo.fReserve == TfReserve, "FDIIsCabinet,cabinfo %s data did not match! Failed!\n", cabname); |
|
ok2 ( cabinfo.hasprev == Thasprev, "FDIIsCabinet,cabinfo %s data did not match! Failed!\n", cabname); |
|
ok2 ( cabinfo.hasnext == Thasnext, "FDIIsCabinet,cabinfo %s data did not match! Failed!\n", cabname); |
|
} |
|
|
|
|
|
|
|
|
HFDI hfdi_unknown_dummy, hfdi_unknown_fake,hfdi_unknown_real; | HFDI hfdi_unknown_dummy, hfdi_unknown_fake,hfdi_unknown_real; |
/* yes its global and ugly */ | /* yes its global and ugly */ |
| |
|
/* Is CPU386 or Unknown more commonly used? */ |
| |
static void TestCreate(void) { | static void TestCreate(void) { |
| |
|
|
final_free, | final_free, |
real_open, | real_open, |
real_read, | real_read, |
dummy_write, |
real_write, |
real_close, | real_close, |
dummy_seek, |
real_seek, |
cpuUNKNOWN, | cpuUNKNOWN, |
&error_structure | &error_structure |
); | ); |
|
|
printf("Ending TestCreate()\n"); | printf("Ending TestCreate()\n"); |
} | } |
| |
|
|
|
|
|
|
static void TestInfo(void) { | static void TestInfo(void) { |
/* Noticed Behavior : | /* Noticed Behavior : |
FDIIsCabinet does not open the file on its own, it requires a file open/close to be done externally. | FDIIsCabinet does not open the file on its own, it requires a file open/close to be done externally. |
|
|
ok ( FDIIsCabinet( hfdi_unknown_fake, fakeFD, &fdi_cabinfo_simple) == TRUE, | ok ( FDIIsCabinet( hfdi_unknown_fake, fakeFD, &fdi_cabinfo_simple) == TRUE, |
"FDIIsCabinet (FakeFile = Cabinet) failed!\n"); | "FDIIsCabinet (FakeFile = Cabinet) failed!\n"); |
| |
ok ( fdi_cabinfo_simple.cbCabinet == 117, "FDIIsCabinet,cabinfo (FakeFile = Cabinet) data did not match! Failed!\n"); |
CheckCabInfo("simple.cab",fdi_cabinfo_simple,117,1,1,12345,0,0,0,0); |
ok ( fdi_cabinfo_simple.cFolders == 1, "FDIIsCabinet,cabinfo (FakeFile = Cabinet) data did not match! Failed!\n"); |
|
ok ( fdi_cabinfo_simple.cFiles == 1, "FDIIsCabinet,cabinfo (FakeFile = Cabinet) data did not match! Failed!\n"); |
/* simply this with macros? |
ok ( fdi_cabinfo_simple.setID == 12345, "FDIIsCabinet,cabinfo (FakeFile = Cabinet) data did not match! Failed!\n"); |
yes, make one macro with inputs (cabname, testname, [expected values] ) --- using lambda notation |
ok ( fdi_cabinfo_simple.iCabinet == 0, "FDIIsCabinet,cabinfo (FakeFile = Cabinet) data did not match! Failed!\n"); |
add checks for cabinfo data! |
ok ( fdi_cabinfo_simple.fReserve == 'b', "FDIIsCabinet,cabinfo (FakeFile = Cabinet) data did not match! Failed!\n"); |
Is it ok to reuse the same hfdi_unknown_real ? */ |
ok ( fdi_cabinfo_simple.hasprev == 117, "FDIIsCabinet,cabinfo (FakeFile = Cabinet) data did not match! Failed!\n"); |
|
ok ( fdi_cabinfo_simple.hasnext == 117, "FDIIsCabinet,cabinfo (FakeFile = Cabinet) data did not match! Failed!\n"); |
/* TEST : Opened filehandle associated, corrupted cab loaded, should return FALSE */ |
|
/* We can see that the Windows implementation only reads the first 36 bytes - what if we corrupted a CAB after 36 bytes?*/ |
|
|
|
realfd = real_open( "broken.cab" , _O_BINARY | _O_RDONLY | _O_SEQUENTIAL, 0); |
|
|
|
ok ( FDIIsCabinet( hfdi_unknown_real, realfd, &fdi_cabinfo_complex) == FALSE, |
|
"FDIIsCabinet (File = Bad-Cabinet) broken.cab failed!\n"); |
|
real_close(realfd); |
|
|
|
realfd = real_open( "cabinet_fdi.c" , _O_BINARY | _O_RDONLY | _O_SEQUENTIAL, 0); |
|
|
|
ok ( FDIIsCabinet( hfdi_unknown_real, realfd, &fdi_cabinfo_complex) == FALSE, |
|
"FDIIsCabinet (File = Non-Cabinet) cabinet_fdi.c failed!\n"); |
|
real_close(realfd); |
|
|
|
|
|
/* TEST : Opened filehandle associated, valid cab loaded, should return TRUE */ |
|
realfd = real_open( "complex_lzw.cab" , _O_BINARY | _O_RDONLY | _O_SEQUENTIAL, 0); |
|
|
|
ok ( FDIIsCabinet( hfdi_unknown_real, realfd, &fdi_cabinfo_complex) == TRUE, |
|
"FDIIsCabinet (File = Cabinet) complex_lzw.cab failed!\n"); |
|
real_close(realfd); |
|
|
|
printCabInfo(fdi_cabinfo_complex); |
|
|
|
realfd = real_open( "complex_lzw2.cab" , _O_BINARY | _O_RDONLY | _O_SEQUENTIAL, 0); |
|
|
|
ok ( FDIIsCabinet( hfdi_unknown_real, realfd, &fdi_cabinfo_complex) == TRUE, |
|
"FDIIsCabinet (File = Cabinet) complex_lzw2.cab failed!\n"); |
|
real_close(realfd); |
|
|
|
printCabInfo(fdi_cabinfo_complex); |
|
|
|
realfd = real_open( "complex_zip.cab" , _O_BINARY | _O_RDONLY | _O_SEQUENTIAL, 0); |
|
|
|
ok ( FDIIsCabinet( hfdi_unknown_real, realfd, &fdi_cabinfo_complex) == TRUE, |
|
"FDIIsCabinet (File = Cabinet) complex_zip.cab failed!\n"); |
|
real_close(realfd); |
|
|
|
printCabInfo(fdi_cabinfo_complex); |
|
|
|
realfd = real_open( "complex_zip2.cab" , _O_BINARY | _O_RDONLY | _O_SEQUENTIAL, 0); |
|
|
|
ok ( FDIIsCabinet( hfdi_unknown_real, realfd, &fdi_cabinfo_complex) == TRUE, |
|
"FDIIsCabinet (File = Cabinet) complex_zip2.cab failed!\n"); |
|
real_close(realfd); |
|
|
|
|
|
printCabInfo(fdi_cabinfo_complex); |
|
|
|
realfd = real_open( "complex_none.cab" , _O_BINARY | _O_RDONLY | _O_SEQUENTIAL, 0); |
| |
realfd = real_open( "working.cab" , _O_BINARY | _O_RDONLY | _O_SEQUENTIAL, 0); |
|
ok ( FDIIsCabinet( hfdi_unknown_real, realfd, &fdi_cabinfo_complex) == TRUE, | ok ( FDIIsCabinet( hfdi_unknown_real, realfd, &fdi_cabinfo_complex) == TRUE, |
"FDIIsCabinet (File = Cabinet) failed!\n"); |
"FDIIsCabinet (File = Cabinet) complex_zip.cab failed!\n"); |
real_close(realfd); | real_close(realfd); |
| |
printf("Cabinet Data : cbC %d cF %d cFi %d si %d iC %d fr %b hp %d hn %d\n,", |
|
fdi_cabinfo_complex.cbCabinet, |
printCabInfo(fdi_cabinfo_complex); |
fdi_cabinfo_complex.cFolders , |
|
fdi_cabinfo_complex.cFiles , |
|
fdi_cabinfo_complex.setID, |
|
fdi_cabinfo_complex.iCabinet, |
|
fdi_cabinfo_complex.fReserve , |
|
fdi_cabinfo_complex.hasprev , |
|
fdi_cabinfo_complex.hasnext ); |
|
| |
} | } |
| |
|
static void TestCopy(void){ |
|
printf("Starting TestCopy()\n"); |
|
printf("---simple.cab\n"); |
|
FDICopy(hfdi_unknown_real, |
|
"simple.cab", |
|
"./", |
|
//"C:\\cygwin\\home\\Administrator\\group3\\wine\\dlls\\cabinet\\tests\\", |
|
0, |
|
notification_function, |
|
NULL, |
|
NULL); |
|
/*printf("---complex_none.cab\n"); |
|
FDICopy(hfdi_unknown_real, |
|
"complex_none.cab", |
|
"C:\\cygwin\\home\\Administrator\\group3\\wine\\dlls\\cabinet\\tests\\", |
|
0, |
|
notification_function, |
|
NULL, |
|
NULL); |
|
printf("---complex_zip.cab\n"); |
|
FDICopy(hfdi_unknown_real, |
|
"complex_zip.cab", |
|
"C:\\cygwin\\home\\Administrator\\group3\\wine\\dlls\\cabinet\\tests\\", |
|
0, |
|
notification_function, |
|
NULL, |
|
NULL); |
|
printf("---complex_lzw.cab\n"); |
|
FDICopy(hfdi_unknown_real, |
|
"complex_lzw.cab", |
|
"C:\\cygwin\\home\\Administrator\\group3\\wine\\dlls\\cabinet\\tests\\", |
|
0, |
|
notification_function, |
|
NULL, |
|
NULL); |
|
*/ |
|
|
|
printf("Ending TestCopy()\n"); |
|
} |
|
|
| |
static void TestDestroy(void) { | static void TestDestroy(void) { |
printf("Starting TestDestroy()\n"); | printf("Starting TestDestroy()\n"); |
/* Only two things to check in FDIDestroy |
/* Should return TRUE if given a valid hfdi, else FALSE (only due to context errors?) */ |
1=> Does it return T if its passed an hfdi |
|
2=> Does it return F if its passed a non hfdi |
|
EDIT : Causes GPL if FDIDestroy is called on an invalid pointer. |
|
ok( 0 == FDIDestroy(0), "Return true incorrectly in TestDestroy()!\n"); |
|
*/ |
|
| |
ok(FDIDestroy(hfdi_unknown_dummy), "FDIDestroy (CPU = unknown) (functions=fake) failed!\n"); | ok(FDIDestroy(hfdi_unknown_dummy), "FDIDestroy (CPU = unknown) (functions=fake) failed!\n"); |
ok(FDIDestroy(hfdi_unknown_fake), "FDIDestroy (CPU = unknown) (functions=fake) failed!\n"); | ok(FDIDestroy(hfdi_unknown_fake), "FDIDestroy (CPU = unknown) (functions=fake) failed!\n"); |
|
ok(FDIDestroy(hfdi_unknown_real), "FDIDestroy (CPU = unknown) (functions=real) failed!\n"); |
printf("Ending TestDestroy()\n"); | printf("Ending TestDestroy()\n"); |
| |
} | } |
| |
|
|
START_TEST(paths) | START_TEST(paths) |
{ | { |
|
|
TestCreate(); | TestCreate(); |
TestInfo(); | TestInfo(); |
/* |
|
TestCopy(); | TestCopy(); |
*/ |
|
TestDestroy(); |
|
| |
|
TestDestroy(); |
} | } |