📄 cabinet.cpp
字号:
// I/O :
// Task : Simple notification that FCI is adding a folder 2 a cabinet
//---------------------------------------------------------------------------
BOOL CCabinetBuilder::NotifyFolderFlush(ULONG cbSize, ULONG cbWritten)
{
#ifdef __TRACE_CAB_COMPRESSION__
TRACEFN(_T("CCabinetBuilder::NotifyFolderFlush(%lu,%lu)\n"),cbSize,cbWritten);
#endif
return TRUE;
}
#endif
#ifdef __CAB_BUILD__
//---------------------------------------------------------------------------
// Pre : cbEstimatedSize is the estimated cabinet size
// cbActualSize is the actual cabinet size
// Post : Return the desired cabinet size
// Globals :
// I/O :
// Task : Simple notification that FCI is writing out a cabinet
//---------------------------------------------------------------------------
ULONG CCabinetBuilder::NotifyCabinetFlush(ULONG cbEstimatedSize, ULONG cbActualSize)
{
#ifdef __TRACE_CAB_COMPRESSION__
TRACEFN(_T("CCabinetBuilder::NotifyCabinetFlush(%lu,%lu)\n"),cbEstimatedSize,cbActualSize);
#endif
return cbActualSize;
}
#endif
#ifdef __CAB_BUILD__
//-------------------------------------------------------------------------
// Pre : The wild parameter pv is a pointer 2 an instance of class CCabinetBuilder
// If typeStatus == statusFile CFI is compressing a block into a folder
// cb1 = Size of compressed block
// cb2 = Size of uncompressed block
//
// If typeStatus == statusFolder CFI is adding a folder to a cabinet
// cb1 = Amount of folder copied to cabinet so far
// cb2 = Total size of folder
//
// If typeStatus == statusCabinet CFI is writing out a complete cabinet
// cb1 = Estimated cabinet size that was previously passed to GetNextCabinet()
// cb2 = Actual cabinet size
// Post : Return -1 to signal that FCI should abort except if typeStatus == statusCabinet, when
// the return value is the desired client size for cabinet file. FCI updates the maximum
// cabinet size remaining using this value. This allows a client to generate multiple
// cabinets per disk, and have FCI limit the size correctly (the client can do cluster
// size rounding on the cabinet size!)
// The client should either return cb2, or round cb2 up to some larger value and return that
// Globals :
// I/O :
// Task : Notification from compression interface that some action is in progress
//-------------------------------------------------------------------------
long FAR DIAMONDAPI CCabinetBuilder::NotifyProgress(UINT typeStatus, ULONG cb1, ULONG cb2, void FAR *pv)
{
#ifdef __TRACE_CAB_COMPRESSION__
TRACEFN(_T("CCabinetBuilder::NotifyProgress(%u,%lu,%lu)\n"),typeStatus,cb1,cb2);
#endif
// Handle notification
long result =0;
BOOL ok_2_continue;
CCabinetBuilder *pcb =(CCabinetBuilder *)pv;
ASSERTX(pcb);
switch(typeStatus)
{
case statusFile:
// A block is being compressed
ok_2_continue =pcb->NotifyCompress(cb2,cb1);
result =ok_2_continue ? 0 : -1;
break;
case statusFolder:
// Flushing a folder
ok_2_continue =pcb->NotifyFolderFlush(cb2,cb1);
result =ok_2_continue ? 0 : -1;
break;
case statusCabinet:
// Writing out a cabinet
result =pcb->NotifyCabinetFlush(cb1,cb2);
break;
}
return result;
}
#endif
#ifdef __CAB_BUILD__
//-------------------------------------------------------------------------
// Pre :
// Post :
// Globals :
// I/O :
// Task : Build a disk name and store it in the passed CCAB struct
//-------------------------------------------------------------------------
void CCabinetBuilder::ManufactureDiskName(PCCAB cabinfo)
{
if(cabinfo)
{
// Manufacture name
TCHAR disk_name[CB_MAX_DISK_NAME];
SPRINTF(disk_name,_T("%s%d"),m_strDiskName.c_str(),cabinfo->iDisk);
STRNCPY(cabinfo->szDisk,disk_name,CB_MAX_DISK_NAME);
}
}
#endif
#ifdef __CAB_BUILD__
//-------------------------------------------------------------------------
// Pre :
// Post :
// Globals :
// I/O :
// Task : Build a cabinet name and store it in the passed CCAB struct
//-------------------------------------------------------------------------
void CCabinetBuilder::ManufactureCabinetName(PCCAB cabinfo)
{
if(cabinfo)
{
// Manufacture name
TCHAR cabinet_name[CB_MAX_CABINET_NAME];
SPRINTF(cabinet_name,_T("%s%d.cab"),m_strCabinetName.c_str(),cabinfo->iCab);
STRNCPY(cabinfo->szCab,cabinet_name,CB_MAX_CABINET_NAME);
}
}
#endif
#ifdef __CAB_BUILD__
//-------------------------------------------------------------------------
// Pre : If bCreatePath is TRUE, the .CAB file's path is created if not exists
// Post : Return TRUE on success
// Globals :
// I/O :
// Task : Initialize the cabinet
//-------------------------------------------------------------------------
BOOL CCabinetBuilder::InitCabinet(LPCTSTR lpcszCabPath, LPCTSTR lpcszCabName, LPCTSTR lpcszDiskName, BOOL bCreatePath)
{
// Init the name of the first cabinet and the number of the first disk
TCHAR cabinet_name[CB_MAX_CABINET_NAME];
SPRINTF(cabinet_name,_T("%s%d.cab"),lpcszCabName,1);
m_nLastStartDisk =1;
m_strLastCabinet =cabinet_name;
// Check path (and create it if not exists and so specified)
string cab_str(lpcszCabPath);
EnsureTrailingBackslash(cab_str);
m_CabinetPath =cab_str.c_str();
if(!m_CabinetPath.DirectoryExists())
{
// Cabinet path does not exist
if(!bCreatePath)
return FALSE;
m_CabinetPath.CreateDirectory();
}
// Prepare compression parameters
m_strCabinetName =lpcszCabName;
m_strDiskName =lpcszDiskName;
m_strDiskName +=_T(" "); // So that the name of the disks will be e.g. "Disk 1" and we can use
// this name to prompt user for new disks when necessary
ZeroMemory(&m_CabinetInfo,sizeof(m_CabinetInfo));
m_CabinetInfo.setID =m_nID;
m_CabinetInfo.cb =m_cbFirstCabSize;
m_CabinetInfo.cbFolderThresh =m_cbTreshold;
m_CabinetInfo.cbReserveCFHeader =m_cbReserveCFHeader;
m_CabinetInfo.cbReserveCFFolder =m_cbReserveCFFolder;
m_CabinetInfo.cbReserveCFData =m_cbReserveCFData;
m_CabinetInfo.iCab =1;
m_CabinetInfo.iDisk =1;
STRNCPY(m_CabinetInfo.szCabPath,cab_str.c_str(),CB_MAX_CAB_PATH);
ManufactureDiskName(&m_CabinetInfo);
ManufactureCabinetName(&m_CabinetInfo);
// Create a compression context
m_hContext =FCICreate(&m_CabinetError,
NotifyFilePlacedProc(),
MemAllocProc(),
MemFreeProc(),
FileOpenProc(),
FileReadProc(),
FileWriteProc(),
FileCloseProc(),
FileSeekProc(),
FileDeleteProc(),
GetTempFileProc(),
&m_CabinetInfo,
this); // Pass an instance 2 ourselves, so that we are accessible from the statix
if(m_hContext == NULL)
// Could not create compression context
// Client can call GetErrorCode() 2 get a code of what happened
return FALSE;
return (m_bStatus =TRUE); // Success
}
#endif
#ifdef __CAB_BUILD__
//-------------------------------------------------------------------------
// Pre : lpcszFileName is the fully qualified name of file 2 add
// lpcszStoreAs is the name without path info under which 2 store the file in the cabinet
// Post : Return TRUE on success
// Globals :
// I/O :
// Task : Add a file in2 the cabinet
//-------------------------------------------------------------------------
BOOL CCabinetBuilder::AddFile(LPTSTR lpszFileName, LPTSTR lpszStoreAs, BOOL bCompress, BOOL bExecuteOnExtract)
{
// Check our internal status
CPath file_path(lpszFileName);
if(!m_bStatus || !file_path.Exists())
return FALSE;
// Strip path info from filename 2 add, in case we are not specified
// any name 2 store file being added as
string strStrippedName;
TCHAR szStrippedName[MAX_PATH];
file_path.GetNameExtension(strStrippedName);
STRNCPY(szStrippedName,strStrippedName.c_str(),sizeof(szStrippedName)/sizeof(TCHAR));
// Adding file...
BOOL added_OK =FCIAddFile(m_hContext,
lpszFileName,
lpszStoreAs ? lpszStoreAs : szStrippedName,
bExecuteOnExtract,
GetNextCabinetProc(),
NotifyProgressProc(),
GetFileInfoProc(),
bCompress ? tcompTYPE_MSZIP : tcompTYPE_NONE);
if(!added_OK)
{
// Could not add the file 2 cabinet, cleanup
FCIDestroy(m_hContext);
m_hContext =NULL;
m_bStatus =FALSE;
}
return added_OK;
}
#endif
#ifdef __CAB_BUILD__
//-------------------------------------------------------------------------
// Pre :
// Post : Return TRUE on success
// Globals :
// I/O :
// Task : Force the current feolder under construction 2 be completed
// immediately and written 2 disk
//-------------------------------------------------------------------------
BOOL CCabinetBuilder::FlushFolder()
{
// Check our internal status
if(!m_bStatus)
return FALSE;
return FCIFlushFolder(m_hContext,GetNextCabinetProc(),NotifyProgressProc());
}
#endif
#ifdef __CAB_BUILD__
//-------------------------------------------------------------------------
// Pre :
// Post : Return TRUE on success
// Globals :
// I/O :
// Task : Force the current cabinet under construction 2 be completed
// immediately and written 2 disk
//-------------------------------------------------------------------------
BOOL CCabinetBuilder::FlushCabinet()
{
// Check our internal status
if(!m_bStatus)
return FALSE;
return FCIFlushCabinet(m_hContext,FALSE,GetNextCabinetProc(),NotifyProgressProc());
}
#endif
#ifdef __CAB_BUILD__
//-------------------------------------------------------------------------
// Pre :
// Post :
// Globals :
// I/O :
// Task : Cleanup and delete a cabinet builder object
//-------------------------------------------------------------------------
CCabinetBuilder::~CCabinetBuilder()
{
#ifdef __TRACE_CAB_COMPRESSION__
TRACEFN(_T("CCabinetBuilder::~CCabinetBuilder\n"));
#endif
// Free the compression context (if any)
if(m_bStatus && (m_hContext != NULL))
{
FCIDestroy(m_hContext);
}
}
#endif
#ifdef __CAB_EXTRACT__
//-------------------------------------------------------------------------
// Pre :
// Post :
// Globals :
// I/O :
// Task : Create a cabinet extractor object
//-------------------------------------------------------------------------
CCabinetExtractor::CCabinetExtractor()
{
// Allocate a decompression context
m_hContext =FDICreate(MemAllocProc(),
MemFreeProc(),
FileOpenProc(),
FileReadProc(),
FileWriteProc(),
FileCloseProc(),
FileSeekProc(),
cpu80386,
&m_CabinetError);
// Check if context allocated OK and update our internal status
m_bStatus =(m_hContext != NULL);
// Set the default extraction path in2 a temp folder
m_DefaultExtractPath.TempDirectory();
}
#endif
#ifdef __CAB_EXTRACT__
//-------------------------------------------------------------------------
// Pre :
// Post :
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -