Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
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