解压cab的代码 msdn上的
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;
}
FNOPEN(fnFileOpen)
{
HANDLE hFile = NULL;
DWORD dwDesiredAccess = 0;
DWORD dwCreationDisposition = 0;
UNREFERENCED_PARAMETER(pmode);
if ( oflag & _O_RDWR )
{
dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
}
else if ( oflag & _O_WRONLY )
{
dwDesiredAccess = GENERIC_WRITE;
}
else
{
dwDesiredAccess = GENERIC_READ;
}
if ( oflag & _O_CREAT )
{
dwCreationDisposition = CREATE_ALWAYS;
}
else
{
dwCreationDisposition = OPEN_EXISTING;
}
hFile = CreateFileA(pszFile,
dwDesiredAccess,
FILE_SHARE_READ,
NULL,
dwCreationDisposition,
FILE_ATTRIBUTE_NORMAL,
NULL);
return (INT_PTR)hFile;
}
FNREAD(fnFileRead)
{
DWORD dwBytesRead = 0;
if ( ReadFile((HANDLE)hf, pv, cb, &dwBytesRead, NULL) == FALSE )
{
dwBytesRead = (DWORD)-1L;
}
return dwBytesRead;
}
FNWRITE(fnFileWrite)
{
DWORD dwBytesWritten = 0;
if ( WriteFile((HANDLE)hf, pv, cb, &dwBytesWritten, NULL) == FALSE )
{
dwBytesWritten = (DWORD)-1;
}
return dwBytesWritten;
}
FNCLOSE(fnFileClose)
{
return ( CloseHandle((HANDLE)hf) == TRUE ) ? 0 : -1;
}
FNSEEK(fnFileSeek)
{
return SetFilePointer((HANDLE)hf, dist, NULL, seektype);
}
FNFDINOTIFY(fnNotify)
{
INT_PTR iResult = 0;
switch(fdint)
{
case fdintCOPY_FILE:
{
CHAR cResponse;
CHAR pszNewFileName[MAX_PATH];
LPSTR pszFileName;
HRESULT hr = S_OK;
//TODO Validate if file name contains characters
//that are not allowed by the file system.
//Remove any directory structure from the file name in cabinet
pszFileName = strrchr(pfdin->psz1, '\\');
if ( pszFileName == NULL )
{
pszFileName = pfdin->psz1;
}
//Append the destination directory to the file name.
hr = StringCchPrintfA(pszNewFileName,
ARRAYSIZE(pszNewFileName),
"%s\\%s",
pfdin->pv, //Destination directory provided by user
pszFileName);
if ( SUCCEEDED(hr) )
{
printf("Extract File \"%s\" (Size: %d bytes) -> \"%s\"? (Yes/No/Quit): ",
pfdin->psz1,
pfdin->cb,
pszNewFileName); //uncompressed size of file
do
{
cResponse = (CHAR)_getch();
cResponse = (CHAR)toupper(cResponse);
} while ( cResponse != 'Y' && cResponse != 'N' && cResponse != 'Q');
printf("\n");
if ( cResponse == 'Y' )
{
iResult = fnFileOpen(pszNewFileName, _O_WRONLY | _O_CREAT, 0);
}
else if ( cResponse == 'Q' )
{
iResult = -1;
}
}
else
{
printf("Failed to append file name \"%s\" to destination directory \"%s\"\n",
pszFileName,
pfdin->pv);
iResult = -1;
}
break;
}
case fdintCLOSE_FILE_INFO:
{
FILETIME fileTime;
FILETIME fileTimeLocal;
FILE_BASIC_INFO fbi;
//Converts MS-DOS date and time values to a file time
if ( DosDateTimeToFileTime(pfdin->date, pfdin->time, &fileTime) == TRUE &&
LocalFileTimeToFileTime(&fileTime, &fileTimeLocal) == TRUE )
{
fbi.CreationTime.LowPart = fileTimeLocal.dwLowDateTime;
fbi.CreationTime.HighPart = fileTimeLocal.dwHighDateTime;
fbi.LastWriteTime.QuadPart = -1;
fbi.ChangeTime.QuadPart = -1;
fbi.LastAccessTime.QuadPart = -1;
//Retrieve the file attributes.
fbi.FileAttributes = pfdin->attribs;
fbi.FileAttributes &= ( _A_RDONLY | _A_HIDDEN |
_A_SYSTEM | _A_ARCH );
//Set the date, time and attributes
SetFileInformationByHandle((HANDLE)pfdin->hf,
FileBasicInfo,
&fbi,
sizeof(FILE_BASIC_INFO));
}
iResult = !fnFileClose(pfdin->hf);
break;
}
case fdintNEXT_CABINET:
if ( pfdin->fdie != FDIERROR_NONE )
{
printf("Failed to process the spanned cabinet file \"%s\""
"with error code %d: %s\n",
pfdin->psz1,
pfdin->fdie,
FDIErrorToString(pfdin->fdie));
iResult = -1;
}
break;
case fdintPARTIAL_FILE:
iResult = 0;
break;
case fdintCABINET_INFO:
iResult = 0;
break;
case fdintENUMERATE:
iResult = 0;
break;
default:
iResult = -1;
break;
}
return iResult;
}