Creating a Cabinet
The following syntax illustrates the creation of a cabinet.
Note
This code is for illustrative purposes only. To compile, the callback functions must be defined.
Example
#include <windows.h>
#include <strsafe.h>
#pragma comment(lib,"cabinet.lib")
//Function prototypes
BOOL InitCab(PCCAB pccab);
LPCSTR FCIErrorToString(FCIERROR err);
int main(INT argc, CHAR *argv[])
{
ERF erf; //FCI error structure
HFCI hfci = NULL; //FCI handle
CCAB ccab; //cabinet information structure
INT iArg; //Argument counter
INT iExitCode = -1; //The exit code
LPSTR pszFileName; //The file name to store in the cabinet
(VOID)HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);
ZeroMemory(&erf, sizeof(ERF));
if ( argc < 2 )
{
printf("Usage: %s [file1] [file2] [+] [file3] ...\n"
"\n"
"file - The file to be added to the cabinet.\n"
"+ - Creates a new folder for the succeeding files.\n"
, argv[0]);
goto CLEANUP;
}
if ( InitCab(&ccab) == FALSE )
{
printf("Failed to initialize the cabinet information structure.\n");
goto CLEANUP;
}
//Creates the FCI context
hfci = FCICreate(&erf, //pointer the FCI error structure
fnFilePlaced, //function to call when a file is placed
fnMemAlloc, //function to allocate memory
fnMemFree, //function to free memory
fnFileOpen, //function to open a file
fnFileRead, //function to read data from a file
fnFileWrite, //function to write data to a file
fnFileClose, //function to close a file
fnFileSeek, //function to move the file pointer
fnFileDelete, //function to delete a file
fnGetTempFileName, //function to obtain a temporary file name
&ccab, //pointer to the FCI cabinet information structure
NULL); //client context parameter, NULL for this sample.
if ( hfci == NULL )
{
printf("FCICreate failed with error code %d: %s\n",
erf.erfOper,
FCIErrorToString((FCIERROR)erf.erfOper));
goto CLEANUP;
}
//Add the files to the cabinet
for ( iArg = 1; iArg < argc; iArg++ )
{
if ( strcmp(argv[iArg],"+") == 0 )
{
if ( FCIFlushFolder(hfci, //FCI handle
fnGetNextCabinet, //function to get the next cabinet specifications
fnStatus) == FALSE ) //function to update the cabinet status
{
printf("FCIFlushFolder failed with error code %d: %s\n",
erf.erfOper,
FCIErrorToString((FCIERROR)erf.erfOper));
goto CLEANUP;
}
}
else
{
//Remove the directory structure from the file name to store
pszFileName = strrchr(argv[iArg], '\\');
if ( pszFileName == NULL )
{
pszFileName = argv[iArg];
}
//Adds a file to the cabinet under construction
if ( FCIAddFile(hfci, //FCI handle
argv[iArg], //file to add
pszFileName, //file name to store
FALSE, //do not run when extracted
fnGetNextCabinet, //function to get the next cabinet specifications
fnStatus, //function to update the cabinet status
fnGetOpenInfo, //function to get the file date, time and attributes
tcompTYPE_MSZIP) == FALSE ) //use MSZIP compression
{
printf("FCIAddFile failed with error code %d: %s\n",
erf.erfOper,
FCIErrorToString((FCIERROR)erf.erfOper));
goto CLEANUP;
}
}
}
//Complete the cabinet
if ( FCIFlushCabinet(hfci, //FCI handle
FALSE, //do not call fnGetNextCabinet
fnGetNextCabinet, //function to get the next cabinet specifications
fnStatus) == FALSE ) //function to update the cabinet status
{
printf("FCIFlushCabinet failed with error code %d: %s\n",
erf.erfOper,
FCIErrorToString((FCIERROR)erf.erfOper));
goto CLEANUP;
}
iExitCode = 0;
CLEANUP:
//Destory the FCI context
if ( hfci != NULL )
{
if ( FCIDestroy(hfci) != TRUE )
{
printf("FCIDestroy failed with error code %d: %s\n",
erf.erfOper,
FCIErrorToString((FCIERROR)erf.erfOper));
}
}
return iExitCode;
}
BOOL InitCab(PCCAB pccab)
{
BOOL bInit = FALSE;
DWORD dCurrentDir;
HRESULT hr;
ZeroMemory(pccab, sizeof(CCAB));
pccab->cb = 0x100000; //Maximum cabinet size in bytes
pccab->cbFolderThresh = 0x10000; //Maximum folder size in bytes
pccab->setID = 555; //Cabinet set ID
pccab->iCab = 1; //Number of this cabinet in a set
pccab->iDisk = 0; //Disk number
if( fnGetNextCabinet(pccab, 0, NULL) == TRUE ) //Get the next cabinet name
{
//Set the disk name to empty
pccab->szDisk[0] = '\0';
//Set the cabinet path to the current directory
dCurrentDir = GetCurrentDirectoryA(ARRAYSIZE(pccab->szCabPath),
pccab->szCabPath);
if( dCurrentDir != 0 )
{
hr = StringCchCatA(pccab->szCabPath,
ARRAYSIZE(pccab->szCabPath),
"\\");
bInit = SUCCEEDED(hr);
}
}
return bInit;
}
LPCSTR FCIErrorToString(FCIERROR err)
{
switch (err)
{
case FCIERR_NONE:
return "No error";
case FCIERR_OPEN_SRC:
return "Failure opening file to be stored in cabinet";
case FCIERR_READ_SRC:
return "Failure reading file to be stored in cabinet";
case FCIERR_ALLOC_FAIL:
return "Insufficient memory in FCI";
case FCIERR_TEMP_FILE:
return "Could not create a temporary file";
case FCIERR_BAD_COMPR_TYPE:
return "Unknown compression type";
case FCIERR_CAB_FILE:
return "Could not create cabinet file";
case FCIERR_USER_ABORT:
return "Client requested abort";
case FCIERR_MCI_FAIL:
return "Failure compressing data";
default:
return "Unknown error";
}
}
Related topics