📄 cabinet.cpp
字号:
m_strContinueDisk =m_strNextDisk;
m_nContinueIndex =m_nNextIndex;
if(!m_bCabinetSetFinished)
{
m_nNextIndex++;
m_NextCabinet.SetDriveDirectory(lpcszCabPath);
m_NextCabinet.SetNameExtension(lpcszCabName);
m_strNextDisk.erase();
m_strNextDisk =lpcszDiskName;
}
return TRUE;
}
#endif
#ifdef __CAB_EXTRACT__
//---------------------------------------------------------------------------
// Pre : lpcszFileName is name of file continued from a previous cabinet
// lpcszFirstCab is name of cabinet where the file starts
// lpcszFirstDisk is name of disk where the file starts
// Post : Return FALSE 2 abort
// Globals :
// I/O :
// Task : Simple notification that first file in the cabinet is continuation
// from some previous cabinet
//---------------------------------------------------------------------------
BOOL CCabinetExtractor::NotifyPartialFile(LPCTSTR lpcszFileName, LPCTSTR lpcszFirstCab, LPCTSTR lpcszFirstDisk)
{
#ifdef __TRACE_CAB_EXTRACTION__
TRACEFN(_T("CCabinetExtractor::NotifyPartialFile(%s,%s,%s)\n"),lpcszFileName,lpcszFirstCab,lpcszFirstDisk);
#endif
return TRUE;
}
#endif
#ifdef __CAB_EXTRACT__
//---------------------------------------------------------------------------
// Pre : lpcszFileName is name of file being extracted
// cbSize is real (uncompressed) size of file
// Post : Return FALSE 2 abort
// Globals :
// I/O :
// Task : Simple notification that a file is about 2 be extracted from cabinet
// we can specify where 2 extract it by filling strExtractTo with an
// extract path. Before returning, make sure that the path you specified exists
// If you want 2 skip this file, and do not extract it, set bSkipFile 2 TRUE
//---------------------------------------------------------------------------
BOOL CCabinetExtractor::NotifyFileCopy(LPCTSTR lpcszFileName, ULONG cbSize, string &strExtractTo, BOOL &bSkipFile)
{
#ifdef __TRACE_CAB_EXTRACTION__
TRACEFN(_T("CCabinetExtractor::NotifyFileCopy(%s,%lu,%s,%s)\n"),lpcszFileName,cbSize,strExtractTo.c_str(),bSkipFile ? _T("TRUE") : _T("FALSE"));
#endif
// Extracting files 2 default extraction path and
// using the same name as stored in the cabinet file
m_DefaultExtractPath.GetDriveDirectory(strExtractTo);
EnsureTrailingBackslash(strExtractTo);
strExtractTo +=lpcszFileName;
return TRUE;
}
#endif
#ifdef __CAB_EXTRACT__
//---------------------------------------------------------------------------
// Pre : lpcszFileName is the name of the extracted file
// Post : Return FALSE 2 abort
// Globals :
// I/O :
// Task : Simple notification that a file was extracted OK, now it's time 2
// set it's attributes and date/time. Clients can specify the date/time
// and attributes they want the extracted file 2 have
// Note that at the time when this notification is called, the file is
// still open. If you want 2 manipulate the file after it's extracted,
// you can do so from NotifyFileCopiedAndClosed()
//---------------------------------------------------------------------------
BOOL CCabinetExtractor::NotifyFileCopied(LPCTSTR lpcszFileName, USHORT &nDate, USHORT &nTime, USHORT &nAttribs)
{
#ifdef __TRACE_CAB_EXTRACTION__
TRACEFN(_T("CCabinetExtractor::NotifyFileCopied(%s,%u,%u,%u)\n"),lpcszFileName,nDate,nTime,nAttribs);
#endif
return TRUE;
}
#endif
#ifdef __CAB_EXTRACT__
//---------------------------------------------------------------------------
// Pre : lpcszFileName is the name of the extracted file
// Post : Return FALSE 2 abort
// Globals :
// I/O :
// Task : Simple notification that a file was extracted OK
// At this time the decompression interface got it's hands off the
// extracted file, clients can do whatever they want with it
// Here clients can also use the members:
// m_nLastFileStartCabinetIndex
// m_nLastFileEndCabinetIndex
//---------------------------------------------------------------------------
BOOL CCabinetExtractor::NotifyFileCopiedAndClosed(LPCTSTR lpcszFileName)
{
#ifdef __TRACE_CAB_EXTRACTION__
TRACEFN(_T("CCabinetExtractor::NotifyFileCopiedAndClosed(%s)\n"),lpcszFileName);
#endif
return TRUE;
}
#endif
#ifdef __CAB_EXTRACT__
//---------------------------------------------------------------------------
// Pre :
// Post : Return FALSE 2 abort
// Globals :
// I/O :
// Task : Simple notification of file enumeration
//---------------------------------------------------------------------------
BOOL CCabinetExtractor::NotifyEnumerate(USHORT nID, long &nCurrentPosition, USHORT &nFilesRemaining)
{
#ifdef __TRACE_CAB_EXTRACTION__
TRACEFN(_T("CCabinetExtractor::NotifyEnumerate(%u,%ld,%u)\n"),nID,nCurrentPosition,nFilesRemaining);
#endif
return TRUE;
}
#endif
#ifdef __CAB_EXTRACT__
//---------------------------------------------------------------------------
// Pre : lpcszNextCab is the name of the next cabinet
// lpcszNextDisk is the name of the next disk
// nErrorCode is the last error code (The decompression interface will keep calling this,
// until the correct cabinet is returned or the extraction is aborted)
// Post : Return FALSE 2 abort
// Globals :
// I/O :
// Task : Simple notification that another cabinet is needed
// Clients should here locate the next cabinet (eventually asking
// users 4 the next disk or allowing browse 4 the next cabinet's location)
// and return it 2 the decompression engine
// Before returning a path, make sure that there is a cabinet with the proper name
// (eventually also checking that is from the correct set) and is readable
//---------------------------------------------------------------------------
BOOL CCabinetExtractor::NotifyNextCabinet(LPCTSTR lpcszNextCab, LPCTSTR lpcszNextDisk, string &strNextCabPath, int nErrorCode)
{
#ifdef __TRACE_CAB_EXTRACTION__
TRACEFN(_T("CCabinetExtractor::NotifyNextCabinet(%s,%s,%s,%d)\n"),lpcszNextCab,lpcszNextDisk,strNextCabPath.c_str(),nErrorCode);
#endif
// Assuming that next cabinet file is in the same folder
return TRUE;
}
#endif
#ifdef __CAB_EXTRACT__
//-------------------------------------------------------------------------
// Pre : The wild pointer notifyInfo->pv field points 2 a CCabinetExtractor
// If notifyType == fdintCABINET_INFO:
// Called exactly once for each cabinet opened by FDICopy(), including
// continuation cabinets opened due to file(s) spanning cabinet
// boundaries. Primarily intended to permit 2 automatically select
// the next cabinet in a cabinet sequence even if not copying files
// that span cabinet boundaries
// notifyInfo->psz1 is name of next cabinet (no path)
// notifyInfo->psz2 is name of next disk
// notifyInfo->psz3 is cabinet path name
// notifyInfo->setID is cabinet set ID
// notifyInfo->iCabinet is Cabinet number within cabinet set of the cabinet being processed now (0-based)
// This call is made *every* time a new cabinet is examined by
// FDICopy(). So if "foo2.cab" is examined because a file is
// continued from "foo1.cab", and then you call FDICopy() again
// on "foo2.cab", you will get *two* fdintCABINET_INFO calls
//
// If notifyType == fdintCOPY_FILE:
// Called for each file that *starts* in the current cabinet, giving
// the client the opportunity to request that the file be copied or skipped
// notifyInfo->psz1 is file name in cabinet
// notifyInfo->cb is uncompressed size of file
// notifyInfo->date is file date
// notifyInfo->time is file time
// notifyInfo->attribs is file attributes
// notifyInfo->iFolder is file's folder index
//
// If notifyType == fdintCLOSE_FILE_INFO:
// Called after all of the data has been written to a target file.
// This function must close the file and set the file date, time and attributes
// notifyInfo->psz1 is file name in cabinet
// notifyInfo->hf is file handle
// notifyInfo->date is file date
// notifyInfo->time is file time
// notifyInfo->attribs is file attributes
// notifyInfo->iFolder is file's folder index
// notifyInfo->cb is Run After Extract flag (0 don't run, 1 run)
// FDI assumes that the target file was closed, even if this
// callback returns failure. FDI will NOT attempt to use
// the PFNCLOSE function supplied on FDICreate() to close the file
//
// If notifyType == fdintPARTIAL_FILE:
// Called for files at the front of the cabinet that are CONTINUED
// from a previous cabinet. This callback occurs only when FDICopy is
// started on second or subsequent cabinet in a series that has files
// continued from a previous cabinet
// notifyInfo->psz1 is file name of file CONTINUED from a PREVIOUS cabinet
// notifyInfo->psz2 is name of cabinet where file starts
// notifyInfo->psz3 is name of disk where file starts
//
// If notifyType == fdintENUMERATE:
// Called once after a call to FDICopy() starts scanning a CAB's
// CFFILE entries, and again when there are no more CFFILE entries.
// If CAB spanning occurs, an additional call will occur after the
// first spanned file is completed. If the notifyInfo->iFolder value is
// changed from zero, additional calls will occur next time it reaches
// zero. If iFolder is changed to zero, FDICopy will terminate, as if
// there were no more CFFILE entries. Primarily intended to allow an
// application with it's own file list to help FDI advance quickly to
// a CFFILE entry of interest. Can also be used to allow an
// application to determine the cb values for each file in the CAB
// notifyInfo->cb is current CFFILE position
// notifyInfo->iFolder is number of files remaining
// notifyInfo->setID is current CAB's setID value
// This call can be ignored by applications which want normal file
// searching. The application can adjust the supplied values to
// force FDICopy() to continue it's search at another location, or
// to force FDICopy() to terminate the search, by setting iFolder to 0.
// (FDICopy() will report no error when terminated this way)
// FDI has no means to verify the supplied cb or iFolder values
// Arbitrary values are likely to cause undesirable results. An
// application should cross-check notifyInfo->setID to be certain the
// external database is in sync with the CAB. Reverse-skips are OK
// (but may be inefficient) unless fdintNEXT_CABINET has been called
//
// If notifyType == fdintNEXT_CABINET:
// This function is *only* called when fdintCOPY_FILE was told to copy
// a file in the current cabinet that is continued to a subsequent
// cabinet file. It is important that the cabinet path name (psz3)
// be validated before returning! This function should ensure that
// the cabinet exists and is readable before returning. So, this
// is the function that should, for example, issue a disk change
// prompt and make sure the cabinet file exists
// When this function returns to FDI, FDI will check that the setID
// and iCabinet match the expected values for the next cabinet.
// If not, FDI will continue to call this function until the correct
// cabinet file is specified, or until this function returns -1 to
// abort the FDICopy() function. notifyInfo->fdie is set to
// FDIERROR_WRONG_CABINET to indicate this case
// notifyInfo->psz1 is name of next cabinet where current file is continued
// notifyInfo->psz2 is name of next disk where current file is continued
// notifyInfo->psz3 is cabinet path name; FDI concatenates psz3 with psz1
// to produce the fully-qualified path for the cabinet
// file. The 256-byte buffer pointed at by psz3 may
// be modified, but psz1 may not!
// notifyInfo->fdie is FDIERROR_WRONG_CABINET if the previous call to
// fdintNEXT_CABINET specified a cabinet file that
// did not match the setID/iCabinet that was expected
// If you *haven't* ensured that the cabinet file is present and
// readable, or the cabinet file has been damaged, notifyInfo->fdie will
// receive other appropriate error codes
// FDIERROR_CABINET_NOT_FOUND
// FDIERROR_NOT_A_CABINET
// FDIERROR_UNKNOWN_CABINET_VERSION
// FDIERROR_CORRUPT_CABINET
// FDIERROR_BAD_COMPR_TYPE
// FDIERROR_RESERVE_MISMATCH
// FDIERROR_WRONG_CABINET
// This call is almost always made when a target file is open and
// being written to, and the next cabinet is needed to get more
// data for the file
// Post : If notifyType == fdintCABINET_INFO:
// If notifyType == fdintPARTIAL_FILE:
// If notifyType == fdintNEXT_CABINET:
// Return -1 to abort file copying
//
// If notifyType == fdintCLOSE_FILE_INFO:
// Return 0 or -1 to abort copying
//
// If notifyType == fdintCOPY_FILE:
// Return non-zero file handle for destination file; FDI writes
// data to this file use the PFNWRITE function supplied to FDICreate,
// and then calls fdintCLOSE_FILE_INFO to close the file and set
// the date, time, and attributes. NOTE: This file handle returned
// must also be closeable by the PFNCLOSE function supplied to
// FDICreate, since if an error occurs while writing to this handle,
// FDI will use the PFNCLOSE function to close the file so that the
// client may delete it
// Return 0 to skip file, do not copy
// Return -1 to abort file copying
//
// If notifyType == fdintENUMERATE:
// Return anything but -1 if we don't care
// If we wish to force a skip, return anything but -1 and
// notifyInfo->cb set to desired CFFILE position
// notifyInfo->iFolder set desired # of files remaining
// If we wish to stop enumeration, Return anything but -1 and
// notifyInfo->iFolder set to 0
// Return -1 to abort file copying ("user aborted")
// Globals :
// I/O :
// Task : This notification proc is called by the decompression interface 2
// inform us what it is doing with our cabinet file(s)
//-------------------------------------------------------------------------
int FAR DIAMONDAPI CCabinetExtractor::NotifyProgress(FDINOTIFICATIONTYPE notifyType, PFDINOTIFICATION notifyInfo)
{
#ifdef __TRACE_CAB_EXTRACTION__
TRACEFN(_T("CCabinetExtractor::NotifyProgress("));
#endif
int result =0;
BOOL ok_2_continue;
CCabinetExtractor *pce =(CCabinetExtractor *)notifyInfo->pv;
ASSERTX(pce);
// Handle notifications differently...
switch(notifyType)
{
case fdintCABINET_INFO:
// Get general information about the cabinet
#ifdef __TRACE_CAB_EXTRACTION__
TRACEX(_T("CABINET_INFO,"));
TRACEX(_T("%u,%s,%s,%s,%u)\n"),notifyInfo->setID,notifyInfo->psz3,notifyInfo->psz1,notifyInfo->psz2,notifyInfo->iCabinet);
#endif
{
// Notifying client...
ok_2_continue =pce->NotifyCabinetInfo(notifyInfo->setID, // ID of cabinet set
notifyInfo->psz3, // Cabinet path
notifyInfo->psz1, // Cabinet name (might be empty)
notifyInfo->psz2, // Disk name (might be empty)
notifyInfo->iCabinet); // Index of cabinet being processed (the one used in ExtractFiles) (0-based)
result =ok_2_continue ? 0 : -1;
}
break;
case fdintCOPY_FILE:
// File to be copied
#ifdef __TRACE_CAB_EXTRACTION__
TRACEX(_T("COPY_FILE,"));
TRACEX(_T("%s,%lu,0x%04x,0x%04x,0x%04x)...\n"),notifyInfo->psz1,notifyInfo->cb,notifyInfo->date,notifyInfo->time,notifyInfo->attribs);
#endif
{
pce->m_bLastFileSkipped =FALSE;
// Notifying client...
string strExtractTo;
BOOL bSkipFile =FALSE;
ok_2_continue =pce->NotifyFileCopy(notifyInfo->psz1, // File name
notifyInfo->cb, // File size uncompressed
strEx
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -