⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cabinet.cpp

📁 cabinet file (.CAB) file handlig.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// 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 + -