cabinet.dll conformance test wine 3 aleksandr liber rizwan kassim
TRANSCRIPT
Cabinet.dll Conformance Cabinet.dll Conformance TestTest
Wine 3 Wine 3
Aleksandr LiberAleksandr Liber
Rizwan KassimRizwan Kassim
Purpose of the testPurpose of the test
Check for functional equivalence of Check for functional equivalence of Microsoft and WINE implementationsMicrosoft and WINE implementations
Not really focusing on finding bugs, Not really focusing on finding bugs, but in verifying that the WINE version but in verifying that the WINE version outputs outputs exactlyexactly what the Microsoft what the Microsoft version doesversion does
What is a Cabinet?What is a Cabinet?
Microsoft archive formatMicrosoft archive format Used in the Windows installation, Used in the Windows installation,
Microsoft installers, and ActiveX Microsoft installers, and ActiveX component downloadscomponent downloads
Large Cab files can be split into Large Cab files can be split into groups of smaller ones and then groups of smaller ones and then combined back togethercombined back together
Cabinet File FormatCabinet File Format
Each file is stored in a folder. A folder Each file is stored in a folder. A folder can have many files. can have many files.
Files are compressed as a single unit Files are compressed as a single unit for improved compression ratiosfor improved compression ratios
Random Access speed however is Random Access speed however is adversely affected.adversely affected.
Cabinet currently supports: MSZip Cabinet currently supports: MSZip and LXW compression and LXW compression
Cabinet APICabinet API
FCI (File Compression FCI (File Compression Interface)Interface)
FCICreate - Create an FCI FCICreate - Create an FCI context.context.
FCIAddFile - Add a file to the FCIAddFile - Add a file to the cabinet being created.cabinet being created.
FCIFlushCabinet - Complete FCIFlushCabinet - Complete the cabinet.the cabinet.
FCIFlushFolder - Complete the FCIFlushFolder - Complete the folder and begin a new one.folder and begin a new one.
FCIDestroy - Destroy the FCI FCIDestroy - Destroy the FCI context.context.
FDI (File Decompression FDI (File Decompression InterfaceInterface
FDICreate - Create an FDI FDICreate - Create an FDI context.context.
FDIIsCabinet – Check whether FDIIsCabinet – Check whether or not a file is a cabinet, if it is or not a file is a cabinet, if it is the function returns information the function returns information about it.about it.
FDICopy - Extract files from the FDICopy - Extract files from the cabinet.cabinet.
FDIDestroy – Destroy the FDI FDIDestroy – Destroy the FDI context.context.
Callback FunctionsCallback Functions
The API makes extensive use of The API makes extensive use of callback functionscallback functions
Most are for memory management Most are for memory management and file I/O. and file I/O.
Others: Notify, DecryptOthers: Notify, Decrypt
Struct:ERF-Error Structure
#define:tcompXXX-compression types
FDICreate()Creates the FDI
context
FCIAddFile()
Enum:FDIEROR-for erf.erfOper
Struct:FDICABINETINFO-Info about cab
Enum:FDIDECRYPTTYPE-PFNFDECRYPT command types
Struct:FDIDECRYPT-Data for
PFNFDECRYPT
FNFREE – memory free
FNOPEN – open file
FNALLOC -memory allocation
FNWRITE – write to file
FNREAD -read from file
FNCLOSE – close file
FNSEEK -like lseek
Struct:FDINOTIFICATION -to hold notify info
Enum:FDINOTIFICATIONTYPE-possible kinds of notification
FNFDIDECRCRYPT –
Decryption function
FNFDINOTIFY – The notification
function CPU Type
FDIIsCabinet()Check if cab and
return info
HDFI-handle to FDI
context
FDICopyt()Extract files
FDIDestroy()Destroy FDI
Context
Cabinet API in WINECabinet API in WINE
FCI not implemented since the FCI not implemented since the majority of operations are done with majority of operations are done with extractionextraction
FDI appears to be fully implemented. FDI appears to be fully implemented. So our decision was to focus on FDISo our decision was to focus on FDI
Patch DescriptionPatch DescriptionWine cabinet.dll FDI Conformance Test Patch
Raw files available at :http://www.geekymedia.com/viewcvs/cgi/viewcvs.cgi/group3/wine/
This patch adds tests for the cabinet dll, specifically testing thefunctions FDICreate, FDIDestroy, FDICopy and FDIIsCabinet. As theFCI functions are still marked *FIXME* in wine, they haven't been tested.
The package is self containing, allowing additional cabinetfeatures to be tested by preparing other cabinets in the same mannerthat ours were. A patch of -p1 will be needed.
This patch has been successfully applied to the wine tree and ran.
Files IncludedFiles Included
Modified Makefile.in(s) and configure.acModified Makefile.in(s) and configure.ac cabinet_fdi.c - the actual code of the test for FDIcabinet_fdi.c - the actual code of the test for FDI data.h - cabinet files and files used to make then data.h - cabinet files and files used to make then
stored in hex using C arraysstored in hex using C arrays genfiles.sh - shell script that can recreate data.h, genfiles.sh - shell script that can recreate data.h,
useful for expansions to the testuseful for expansions to the test tvfs.h - Our virtual file system interfacetvfs.h - Our virtual file system interface tvfs.c - Implementation of the abovetvfs.c - Implementation of the above chexify.pl - Perl script that does the actual chexify.pl - Perl script that does the actual
translation of a binary file to an array of translation of a binary file to an array of hexadecimal values and creates C code out of it. hexadecimal values and creates C code out of it.
Running of the TestRunning of the Test
TestCreate()TestCreate() Tests creation of an FDI contextTests creation of an FDI context Just uses allocation functionsJust uses allocation functions
TestInfo()TestInfo() ““Creates” simple.cab, opens and reads it. Checks Creates” simple.cab, opens and reads it. Checks
CABINFO struct. Repeat for complex.cabCABINFO struct. Repeat for complex.cab TestCopy()TestCopy()
““Creates” simple.cab, open, reads it. Enumerates files in Creates” simple.cab, open, reads it. Enumerates files in cabinet and prints list. Extracts all files in cabinet to cabinet and prints list. Extracts all files in cabinet to virtual file system and byte-compares them with virtual file system and byte-compares them with reference. Repeat for complex.reference. Repeat for complex.
TestDestroy()TestDestroy() Destroys FDI contextDestroys FDI context Only fails if its pointed to a non contextOnly fails if its pointed to a non context
Compilation OptionsCompilation Options
To build outside Wine tree, compile To build outside Wine tree, compile with cl -DSTANDALONE -D_X86_ with cl -DSTANDALONE -D_X86_ tvfs.c cabinet_fdi.c FDI.libtvfs.c cabinet_fdi.c FDI.lib
For verbose output in the test, For verbose output in the test, compile with -DVERBOSEcompile with -DVERBOSE
To enable debugging output in the To enable debugging output in the virtual file system use -virtual file system use -DTVFS_DEBUGDTVFS_DEBUG
Virtual File SystemVirtual File System
TVFS-trivial virtual file system TVFS-trivial virtual file system Provides virtual versions of the file system calls Provides virtual versions of the file system calls
needed by FDI: open, read, write, lseek, close. needed by FDI: open, read, write, lseek, close. Each returns the same return values as the Each returns the same return values as the
corresponding _open, _read, _write, _lseek, _close corresponding _open, _read, _write, _lseek, _close calls in Win32 calls in Win32
Functions for creating whole files from binary Functions for creating whole files from binary arrays, and comparing whole files to binary arrays arrays, and comparing whole files to binary arrays as a testing aid as a testing aid
Allows debugging insertion of various errors, Allows debugging insertion of various errors, “Disk Full” “Access Denied” “CRC Error” “Disk Full” “Access Denied” “CRC Error”
Virtual File System Virtual File System StructureStructure
Two arrays of structs, “files” and Two arrays of structs, “files” and “handlers”“handlers”
tvfs_create creates a “file” with a tvfs_create creates a “file” with a specific name, size and contentspecific name, size and content
tvfs_open checks for existing file and tvfs_open checks for existing file and assigns a handlerassigns a handler
tvfs_free performs bookkeeping, tvfs_free performs bookkeeping, freeing dynamically associated freeing dynamically associated memory. memory.
Cabinet File GenerationCabinet File Generation
data.h is generated using the data.h is generated using the genfiles shell script. genfiles shell script.
This allow for easy addition of new This allow for easy addition of new cab files to the test. cab files to the test.
It uses cabarc.exe to create the It uses cabarc.exe to create the cabinet files, and then uses cabinet files, and then uses chexify.pl to convert the file into a chexify.pl to convert the file into a hexadecimal C arrayhexadecimal C array
Snippets of genfiles.shSnippets of genfiles.sh
set -exset -ex test -f cabsdk.exe || wget -c test -f cabsdk.exe || wget -c
http://download.microsoft.com/download/platformsdk/cab/2.0/w98nt42kmexp/en-us/http://download.microsoft.com/download/platformsdk/cab/2.0/w98nt42kmexp/en-us/cabsdk.execabsdk.exe
mkdir cabsdk; cd cabsdkmkdir cabsdk; cd cabsdk unzip ../cabsdk.exe ; cd ..unzip ../cabsdk.exe ; cd .. chmod 744 cabsdk/BIN/CABARC.EXEchmod 744 cabsdk/BIN/CABARC.EXE
# Simple archive, just one 42 byte file# Simple archive, just one 42 byte file echo echo > simple.txt > simple.txt wine cabsdk/BIN/CABARC.EXE N simple.cab simple.txtwine cabsdk/BIN/CABARC.EXE N simple.cab simple.txt
# More complicated archive, with two files# More complicated archive, with two files cp ../../../README READMEcp ../../../README README cp ../../../COPYING.LIB lgpl.txtcp ../../../COPYING.LIB lgpl.txt wine cabsdk/BIN/CABARC.EXE N complex.cab README lgpl.txtwine cabsdk/BIN/CABARC.EXE N complex.cab README lgpl.txt
# Pack source files and archives into hex arrays# Pack source files and archives into hex arrays perl ../../../tools/chexify.pl simple.txt README lgpl.txt simple.cab complex.cab > perl ../../../tools/chexify.pl simple.txt README lgpl.txt simple.cab complex.cab >
data.hdata.h
Sample data.hSample data.h
const static char name_simple_txt[] = const static char name_simple_txt[] = "simple.txt";"simple.txt";
const static char file_simple_txt[] = {0x53, 0x6f, const static char file_simple_txt[] = {0x53, 0x6f, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x2c, 0x20, 0x61, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x6b, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x6b, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x73, 0x68, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x73, 0x68, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x0a};0x0a};
const static int size_simple_txt = const static int size_simple_txt = sizeof(file_simple_txt);sizeof(file_simple_txt);
'So long, and thanks for all the fish.....''So long, and thanks for all the fish.....'
Current TestsCurrent Tests
Simple.cab – contains a single text Simple.cab – contains a single text file whose contents are “So long and file whose contents are “So long and thanks for all the fish….”thanks for all the fish….”
Complex.cab – a larger cabinet Complex.cab – a larger cabinet consisting of two text files, the wine consisting of two text files, the wine README and lgpl.txt. (Previous README and lgpl.txt. (Previous versions compressed “A versions compressed “A Midsummer’s Nights Dream”)Midsummer’s Nights Dream”)
Further PlansFurther Plans
Current patch size with complex.cab Current patch size with complex.cab 300k. (“Too big” – AJ)300k. (“Too big” – AJ) Data.h representation bloats filesize x5Data.h representation bloats filesize x5
Implement programmatic series to generate dataImplement programmatic series to generate data Rand() with given srandRand() with given srand Fibonacci series % 255Fibonacci series % 255 Use this data as the ‘raw uncompressed data’Use this data as the ‘raw uncompressed data’ Data.h will just contain the compressed cabinetData.h will just contain the compressed cabinet
Add features to tvfsAdd features to tvfs ““Disk full”, etc notifications via ENOENT.Disk full”, etc notifications via ENOENT. Directory structure?Directory structure?
Further InformationFurther Information
Wiki Wiki www.geekymedia.com/twiki/bin/view.www.geekymedia.com/twiki/bin/view.cgi/WineDev/Group3cgi/WineDev/Group3
CVS CVS www.geekymedia.com/viewcvs/cgi/viwww.geekymedia.com/viewcvs/cgi/viewcvs.cgi/group3/wine/ewcvs.cgi/group3/wine/