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

📄 cabinet.cpp

📁 cab文件压缩、解压程序源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//---------------------------------------------------------------------------
// Copyright (C) 1998, Interscope Ltd. All rights reserved.
// Reproduction or distribution of this program, or any portion of it, 
// is permitted only if this header is kept as it is.
// For more information, contact:
//
// Interscope Ltd., 5 Culturii St., 5th floor, 4800 Baia Mare, Romania
//    Phone/Fax: +40-62-215023
//    E-mail: office@interscope.ro
//
//   $Author: Levente Farkas $
//     $Date: 5/12/98 11:49p $
//  $Modtime: 4/27/98 6:50a $
// $Revision: 68 $
//  $Archive: /Interscope/Thebe/InstallMaster/Cabinet.cpp $
// $Workfile: Cabinet.cpp $
//-----------------------------------------------------------------------

#ifdef __STDAFX__
#include "StdAfx.H"
#endif

#include <Sys/Stat.H>
#include <IO.H>
#include <FCntl.H>
#include <DOS.H>
#include <TypeInfo.H>

#ifndef __MFC__
#include "Trace.H"
#endif

#include "AssertX.H"
#include "Reminder.Hpp"
#include "Cabinet.Hpp"


//--- Debugee --------------------------------------------------------------

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#ifdef __MFC__
#define new DEBUG_NEW
#endif // __MFC__
#endif // _DEBUG


//-------------------------------------------------------------------------
// Pre     :
// Post    :
// Globals :
// I/O     :
// Task    : Allocate memory
//-------------------------------------------------------------------------
void HUGE * FAR DIAMONDAPI CCabinetBase::MemAlloc(ULONG cbSize)
{
#ifdef __TRACE_CAB_MEMORY__
    TRACEFN(_T("CCabinetBase::MemAlloc(%lu)"),cbSize);
#endif

    return malloc(cbSize);
}

//-------------------------------------------------------------------------
// Pre     :
// Post    :
// Globals :
// I/O     :
// Task    : Free allocated memory
//-------------------------------------------------------------------------
void FAR DIAMONDAPI CCabinetBase::MemFree(void HUGE *ptrMemory)
{
#ifdef __TRACE_CAB_MEMORY__
    TRACEFN(_T("CCabinetBase::MemFree(0x%lx)\n"),ptrMemory);
#endif

    free(ptrMemory);
}

//-------------------------------------------------------------------------
// Pre     : If not NULL, the wild parameter pv is a pointer 2 an instance 
//           of a class CCabinetBase
// Post    :
// Globals :
// I/O     :
// Task    : Open a file
//-------------------------------------------------------------------------
int FAR DIAMONDAPI CCabinetBase::FileOpen(char FAR *pszFile, int oFlag, int pMode, int FAR *ptrErr, void FAR *pv)
{
#if defined(__TRACE_CAB_COMPRESSION__) || defined(__TRACE_CAB_EXTRACTION__)
    TRACEFN(_T("CCabinetBase::FileOpen(%s,0x%04x,0x%04x)\n"),pszFile,oFlag,pMode);
#endif

    // No error yet
    ASSERTX(ptrErr);
    *ptrErr =NOERROR;

    // Text-mode files are not supported, everything is
    // considered 2 be raw binary
    if((oFlag & _O_TEXT) == _O_TEXT)
    {
        ASSERTX(FALSE);
        *ptrErr =EINVAL;
        return -1;
    }

    // Extract access mode from oFlag
    DWORD dwDesiredAccess =GENERIC_READ;
    if((oFlag & _O_WRONLY) == _O_WRONLY)
        dwDesiredAccess =GENERIC_WRITE;
    else if((oFlag & _O_RDWR) == _O_RDWR)
        dwDesiredAccess |=GENERIC_WRITE;

    if(dwDesiredAccess == GENERIC_READ)
        // When we only want 2 read from a file, make sure
        // we open it with share-read, otherwise we won't be 
        // able 2 read from files which are in use by Windows
        pMode |=_S_IREAD;

    // Extract creation mode from oFlag
    DWORD dwCreateMode;
    if((oFlag & _O_CREAT) == _O_CREAT)
    {
        // Creating a file
        if((oFlag & _O_EXCL) == _O_EXCL)
            dwCreateMode =CREATE_NEW;
        else if((oFlag & _O_TRUNC) == _O_TRUNC)
            dwCreateMode =CREATE_ALWAYS;
        else
            dwCreateMode =OPEN_ALWAYS;
    }
    else
    {
        // Opening a file
        if((oFlag & _O_TRUNC) == _O_TRUNC)
            dwCreateMode =TRUNCATE_EXISTING;
        else
            dwCreateMode =OPEN_EXISTING;
    }

    // Extract other flags from oFlag
    DWORD dwFlagsAttrs =FILE_ATTRIBUTE_NORMAL;
    if((oFlag & _O_RANDOM) == _O_RANDOM)
        dwFlagsAttrs |=FILE_FLAG_RANDOM_ACCESS;
    if((oFlag & _O_SEQUENTIAL) == _O_SEQUENTIAL)
        dwFlagsAttrs |=FILE_FLAG_SEQUENTIAL_SCAN;
    if((oFlag & _O_CREAT) == _O_CREAT)
    {
        // Thease are valid only when creating a new file
        if((oFlag & _O_SHORT_LIVED) == _O_SHORT_LIVED)
            dwFlagsAttrs |=FILE_ATTRIBUTE_TEMPORARY;
        if((oFlag & _O_TEMPORARY) == _O_TEMPORARY)
            dwFlagsAttrs |=FILE_FLAG_DELETE_ON_CLOSE;
    }

    // Converting share mode
    DWORD dwShareMode =0;
    if((pMode & _S_IREAD) == _S_IREAD)
        dwShareMode |=FILE_SHARE_READ;
    if((pMode & _S_IWRITE) == _S_IWRITE)
        dwShareMode |=FILE_SHARE_WRITE;

    HANDLE hFile   =CreateFile(pszFile,dwDesiredAccess,dwShareMode,NULL,dwCreateMode,dwFlagsAttrs,NULL);
    BOOL   bResult =(hFile != INVALID_HANDLE_VALUE);

    if(bResult)
    {
        if((oFlag & _O_APPEND) == _O_APPEND)
            // Move file pointer 2 the end of the file first
            SetFilePointer(hFile,0,NULL,FILE_END);
    }
    else
    {
        // Store the error code
        DWORD dwError =GetLastError();
        switch(dwError)
        {
            case ERROR_ACCESS_DENIED:
            case ERROR_LOCK_VIOLATION:
            case ERROR_SHARING_VIOLATION:
                *ptrErr =EACCES;
                break;

            case ERROR_INVALID_PARAMETER:
                *ptrErr =EINVAL;
                break;

            case ERROR_FILE_EXISTS:
            case ERROR_ALREADY_EXISTS:
                *ptrErr =EEXIST;
                break;

            case ERROR_TOO_MANY_OPEN_FILES:
                *ptrErr =EMFILE;
                break;

            case ERROR_FILE_NOT_FOUND:
            case ERROR_PATH_NOT_FOUND:
                *ptrErr =ENOENT;
                break;

            default:
                *ptrErr =(int)dwError;
        }
    }

    return bResult ? (int)hFile : -1;
}

//-------------------------------------------------------------------------
// Pre     : If not NULL, the wild parameter pv is a pointer 2 an instance 
//           of a class CCabinetBase
// Post    :
// Globals :
// I/O     :
// Task    : Read cbRead bytes from file specified by handle into buffer ptrBuffer
//-------------------------------------------------------------------------
UINT FAR DIAMONDAPI CCabinetBase::FileRead(int hFile, void FAR *ptrBuffer, UINT cbRead, int FAR *ptrErr, void FAR *pv)
{
#if defined(__TRACE_CAB_COMPRESSION__) || defined(__TRACE_CAB_EXTRACTION__)
    TRACEFN(_T("CCabinetBase::FileRead(%d,0x%p,%u)\n"),hFile,ptrBuffer,cbRead);
#endif

    // No error yet
    ASSERTX(ptrErr);
    *ptrErr =NOERROR;

    DWORD dwBytesRead;
    BOOL  bResult =ReadFile((HANDLE)hFile,ptrBuffer,cbRead,&dwBytesRead,NULL);

    // Check 4 end-of-file condition
    if(bResult && (dwBytesRead == 0))
        // EOF
        return 0;

    if(!bResult)
        // Store the error code
        *ptrErr =EBADF;

    return bResult ? (UINT)dwBytesRead : (UINT)-1;
}

//-------------------------------------------------------------------------
// Pre     : If not NULL, the wild parameter pv is a pointer 2 an instance 
//           of a class CCabinetBase
// Post    :
// Globals :
// I/O     :
// Task    : Write cbWrite bytes from buffer ptrBuffer int file specified by handle
//-------------------------------------------------------------------------
UINT FAR DIAMONDAPI CCabinetBase::FileWrite(int hFile, void FAR *ptrBuffer, UINT cbWrite, int FAR *ptrErr, void FAR *pv)
{
#if defined(__TRACE_CAB_COMPRESSION__) || defined(__TRACE_CAB_EXTRACTION__)
    TRACEFN(_T("CCabinetBase::FileWrite(%d,0x%p,%u)\n"),hFile,ptrBuffer,cbWrite);
#endif

    // No error yet
    ASSERTX(ptrErr);
    *ptrErr =NOERROR;

    DWORD dwBytesWritten;
    BOOL  bResult =WriteFile((HANDLE)hFile,ptrBuffer,cbWrite,&dwBytesWritten,NULL);

    if(!bResult)
    {
        // Store the error code
        DWORD dwError =GetLastError();
        switch(dwError)
        {
            case ERROR_HANDLE_DISK_FULL:
            case ERROR_DISK_FULL:
                *ptrErr =ENOSPC;
                break;

            default:
                *ptrErr =EBADF;
        }
    }

    return bResult ? (UINT)dwBytesWritten : (UINT)-1;
}

//-------------------------------------------------------------------------
// Pre     : If not NULL, the wild parameter pv is a pointer 2 an instance 
//           of a class CCabinetBase
// Post    :
// Globals :
// I/O     :
// Task    : Seek the file pointer
//-------------------------------------------------------------------------
long FAR DIAMONDAPI CCabinetBase::FileSeek(int hFile, long offset, int seekType, int FAR *ptrErr, void FAR *pv)
{
#if defined(__TRACE_CAB_COMPRESSION__) || defined(__TRACE_CAB_EXTRACTION__)
    TRACEFN(_T("CCabinetBase::FileSeek(%d,%ld,%d)\n"),hFile,offset,seekType);
#endif

    // No error yet
    ASSERTX(ptrErr);
    *ptrErr =NOERROR;

    // Convert seek type
    DWORD dwMoveMethod;
    switch(seekType)
    {
        case SEEK_SET:
            dwMoveMethod =FILE_BEGIN;
            break;

        case SEEK_CUR:
            dwMoveMethod =FILE_CURRENT;
            break;

        case SEEK_END:
            dwMoveMethod =FILE_END; 
            break;

        default:
            // This should never happen
            ASSERTX(FALSE);
            *ptrErr =EINVAL;
            return -1;
    }

    DWORD dwNewOffset =SetFilePointer((HANDLE)hFile,offset,NULL,dwMoveMethod);
    BOOL  bResult =(dwNewOffset != (DWORD)-1);

    if(!bResult)
    {
        // Store the error code
        DWORD dwError =GetLastError();
        switch(dwError)
        {
            case ERROR_INVALID_PARAMETER:
                *ptrErr =EINVAL;
                break;

            default:
                *ptrErr =EBADF;
        }
    }

    return bResult ? (long)dwNewOffset : -1;
}

//-------------------------------------------------------------------------
// Pre     : If not NULL, the wild parameter pv is a pointer 2 an instance 
//           of a class CCabinetBase
// Post    :
// Globals :

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -