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>
#include "fdisample.h"
#include "fdicallbacks.h"
#pragma comment(lib,"cabinet.lib")
//Function prototypes
BOOL ExtractCabinetFiles(
LPSTR pszCabinetName,
LPSTR pszCabinetPath,
LPSTR pszDestinationDir
);
LPCSTR FDIErrorToString(FDIERROR err);
int main(INT argc, CHAR *argv[])
{
INT iExitCode = -1;
HRESULT hr = S_OK;
HANDLE hFile = INVALID_HANDLE_VALUE;
LPSTR pszCabinetName = NULL; //the cabinet name
LPSTR pszDestinationDir = NULL; //the destination directory
CHAR pszCabinetPath[MAX_PATH]; //the cabinet path
WIN32_FIND_DATAA findFileData;
(VOID)HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);
if ( argc != 3 )
{
printf("Usage: %s [cabinet] [destination]\n", argv[0]);
goto CLEANUP;
}
//Split the cabinet name and path
pszCabinetName = strrchr(argv[1], '\\');
if ( pszCabinetName == NULL )
{
pszCabinetName = argv[1];
pszCabinetPath[0] = '\0';
}
else
{
pszCabinetName++;
hr = StringCchCopyA(pszCabinetPath, MAX_PATH, argv[1]);
if ( SUCCEEDED(hr) )
{
pszCabinetPath[(INT)( pszCabinetName - argv[1] )] = '\0';
}
else
{
printf("Failed to split the cabinet name \"%s\".\n",
argv[1]);
goto CLEANUP;
}
}
pszDestinationDir = argv[2]; //Destination directory
//Determine whether the destination directory provided by the user exists
hFile = FindFirstFileA(pszDestinationDir, &findFileData);
if ( hFile == INVALID_HANDLE_VALUE )
{
printf("Destination directory \"%s\" does not exist.\n",
pszDestinationDir);
goto CLEANUP;
}
if ( (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FALSE )
{
printf("Destination, \"%s\", is not a directory.\n",
pszDestinationDir);
goto CLEANUP;
}
//Get the files from the cabinet
if ( ExtractCabinetFiles(pszCabinetName, pszCabinetPath, pszDestinationDir) == TRUE )
{
iExitCode = 0;
}
CLEANUP:
if ( hFile != INVALID_HANDLE_VALUE )
{
FindClose(hFile);
}
return iExitCode;
}
BOOL ExtractCabinetFiles(
LPSTR pszCabinetName,
LPSTR pszCabinetPath,
LPSTR pszDestinationDir
)
{
ERF erf; //FDI error structure
HFDI hfdi = NULL; //FDI handle
BOOL bSuccessful = FALSE;
//Creates the FDI context
hfdi = FDICreate(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
cpuUNKNOWN, //only used by the 16-bit version of FDI
&erf); //pointer the FDI error structure
if ( hfdi == NULL )
{
printf("FDICreate failed with error code %d: %s\n",
erf.erfOper,
FDIErrorToString((FDIERROR)erf.erfOper));
goto CLEANUP;
}
//Extract the files from the cabinet
if ( FDICopy(hfdi, //FDI handle
pszCabinetName, //the cabinet name
pszCabinetPath, //the cabinet path
0, //not used, set to zero
fnNotify, //function for notifications
NULL, //not used, set to NULL
pszDestinationDir) == FALSE )//this value is application-specific
{
printf("FDICopy failed with error code %d: %s\n",
erf.erfOper,
FDIErrorToString((FDIERROR)erf.erfOper));
goto CLEANUP;
}
bSuccessful = TRUE;
CLEANUP:
//Destory the FDI context
if ( hfdi != NULL )
{
if ( FDIDestroy(hfdi) != TRUE )
{
printf("FDIDestroy failed with error code %d: %s\n",
erf.erfOper,
FDIErrorToString((FDIERROR)erf.erfOper));
}
}
return bSuccessful;
}
LPCSTR FDIErrorToString(FDIERROR err)
{
switch (err)
{
case FDIERROR_NONE:
return "No error";
case FDIERROR_CABINET_NOT_FOUND:
return "Cabinet not found";
case FDIERROR_NOT_A_CABINET:
return "Not a cabinet";
case FDIERROR_UNKNOWN_CABINET_VERSION:
return "Unknown cabinet version";
case FDIERROR_CORRUPT_CABINET:
return "Corrupt cabinet";
case FDIERROR_ALLOC_FAIL:
return "Memory allocation failed";
case FDIERROR_BAD_COMPR_TYPE:
return "Unknown compression type";
case FDIERROR_MDI_FAIL:
return "Failure decompressing data";
case FDIERROR_TARGET_FILE:
return "Failure writing to target file";
case FDIERROR_RESERVE_MISMATCH:
return "Cabinets in set have different RESERVE sizes";
case FDIERROR_WRONG_CABINET:
return "Cabinet returned on fdintNEXT_CABINET is incorrect";
case FDIERROR_USER_ABORT:
return "Application aborted";
default:
return "Unknown error";
}
}
}
Related topics