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

📄 cfilemap.cpp

📁 研读AxCrypt对加解密的处理方法
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*! \file
    \brief Implementation of AxPipe::CSourceFileMap and AxPipe::CSinkFileMap, memory mapped files

    @(#) $Id: CFileMap.cpp,v 1.4 2004/06/28 19:43:01 svante Exp $

    AxPipe - Binary Stream Framework

    Copyright (C) 2003 Svante Seleborg/Axon Data, All rights reserved.

    This program is free software; you can redistribute it and/or modify it under the terms
    of the GNU General Public License as published by the Free Software Foundation;
    either version 2 of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
    without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    See the GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along with this program;
    if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
    Boston, MA 02111-1307 USA

    The author may be reached at mailto:axpipe@axondata.se and http://axpipe.sourceforge.net

    Why is this framework released as GPL and not LGPL? See http://www.gnu.org/philosophy/why-not-lgpl.html

----
\verbatim
    CFileMap.cpp                    Implementation of CSourceFileMap and CSinkFileMap, memory mapped files

    E-mail                          YYYY-MM-DD              Reason
    axpipe@axondata.se              2003-12-01              Initial
\endverbatim
*/
#include "stdafx.h"
#include "CFileMap.h"

#include "AxAssert.h"
#define AXLIB_ASSERT_FILE "CFileMap.cpp"

namespace AxPipe {
    /// \brief Map a view of a file to a given offset.
    ///
    /// Ensure that the view is correctly aligned, but give the caller a convenient
    /// pointer to the right place in the view.
    /// \param hMapping An active file mapping
    /// \param llOffset The offset in the file you want the view to start at
    /// \param cbLen The length of the asked for view
    /// \param ppvUserView A user-friendly pointer into the view, correctly offset.
    /// \param dwAccess Access requested, FILE_MAP_READ or FILE_MAP_WRITE typeically
    /// \return The actual view, NULL if error.
    static void *
    MapUserView(HANDLE hMapping, longlong llOffset, size_t cbLen, void **ppvUserView, DWORD dwAccess) {
        static DWORD dwAllocationGranularity;

        if (ppvUserView == NULL) {
            return NULL;
        }

        // Get system allocation granularity to use with the memory mapping functions
        if (!dwAllocationGranularity) {
            SYSTEM_INFO SystemInfo;
            GetSystemInfo(&SystemInfo); // No error return!
            dwAllocationGranularity = SystemInfo.dwAllocationGranularity;
        }

        DWORD dwMisAlign = (DWORD)(llOffset % dwAllocationGranularity);
        cbLen += dwMisAlign;
        llOffset -= dwMisAlign;

        void *vpView = MapViewOfFile(hMapping, dwAccess, (*(LARGE_INTEGER*)&llOffset).HighPart, (*(LARGE_INTEGER*)&llOffset).LowPart, cbLen);
        ASSAPI(vpView != NULL);
        *ppvUserView = (char *)vpView + dwMisAlign;
        return vpView;
    }
    /// \brief Construct with Owner, size, buffer pointer, view, file pos and possibly readonly
    /// \param pOwner An opaque value identifying the 'owner', probably a 'this' pointer.
    /// \param cb The size of the provided memory mapped file segment
    /// \param pv The pointer to the actual data to be used
    /// \param pView The view pointer, pv may be offset from this due to alignment.
    /// \param llPos The file pointer of this segment.
    /// \param fReadOnly True if this is a read-only segment
    CSegMap::CSegMap(void *pOwner, size_t cb, void *pv, void *pView, longlong llPos, bool fReadOnly) : CSeg(cb, pv, fReadOnly) {
        m_pView = pView;
        m_pOwner = pOwner;
        m_llPos = llPos;
    }

    /// \brief Unmap the view, if any.
    CSegMap::~CSegMap() {
        if (m_pView) {
            UnmapViewOfFile(m_pView);
            m_pView = NULL;
        }
    }
    
    /// \brief Get the corresponding file pointer
    /// \return A position in the mapped file.
    longlong
    CSegMap::GetPos() {
        return m_llPos;
    }

    /// \brief Compile time polymorphic type information
    /// \see CSeg::ClassId()
    void *
    CSegMap::ClassId() {
        static int i;
        return &i;
    }

    /// \brief Run time polymorphic type information
    /// \see CSeg::RTClassId()
    void *
    CSegMap::RTClassId() {
        return ClassId();
    }
    
    /// \brief Check if the provided opaque pointer matches the owner given on construction.
    /// \param pOwner An opaque pointer valute, probably a 'this' pointer
    /// \return true if the same value was provided as owner on construction.
    bool
    CSegMap::IsOwner(void *pOwner) {
        return m_pOwner == pOwner;
    }

    /// \brief Just initialize member variables
    CSourceMemFile::CSourceMemFile() {
        m_szFileName = NULL;
        m_hFile = INVALID_HANDLE_VALUE;
        m_hMapping = NULL;
    }

    /// \brief Additional destruction necessary...
    CSourceMemFile::~CSourceMemFile() {
        delete [] m_szFileName;
    }

    /// \brief Get the handle to the opened file
    /// \return An operating system handle to the open file.
    HANDLE
    CSourceMemFile::GetHandle() {
        return m_hFile;
    }

    /// \brief Set file and chunk size
    /// \param szFileName The name of the file, it is copied and saved here.
    /// \param cbChunk The size of the chunks we send downstream
    /// \return A pointer to 'this' CSourceMemFile
    CSourceMemFile *CSourceMemFile::Init(const _TCHAR *szFileName, size_t cbChunk) {
        m_cbChunk = cbChunk;
        size_t cbLen = lstrlen(szFileName);
        CopyMemory(m_szFileName = new _TCHAR[cbLen+1], szFileName, (cbLen + 1) * sizeof (_TCHAR));
        return this;
    }

    /// \brief Open the file and create a mapping
    ///
    /// The filename is provided in the Init() call.
    /// Check for error with GetErrorCode().
    /// \return true if we are to propagate, which we do if no error occurred. false is not an error indication though.
    bool CSourceMemFile::OutOpen() {
        m_hFile = CreateFile(m_szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
        if (m_hFile == INVALID_HANDLE_VALUE) {
            SetError(ERROR_CODE_GENERIC, _T("CSourceMemFile::CSourceMemFile open error [%s]"), my_ptr<_TCHAR>(AxLib::APerror(m_szFileName)).get());
            return false;                   // No point propagating if we already failed
        }
        ((LARGE_INTEGER *)&m_cbFileSize)->LowPart =
            GetFileSize(m_hFile, (LPDWORD)&(((LARGE_INTEGER *)&m_cbFileSize)->HighPart));
        m_cbStreamPos = 0;
        m_hMapping = CreateFileMapping(m_hFile, NULL, PAGE_READONLY, 0, 0, NULL);
        if (!m_hMapping) {
            SetError(ERROR_CODE_GENERIC, _T("CSourceMemFile::CSourceMemFile failed to create file mapping [%s]"), my_ptr<_TCHAR>(AxLib::APerror(m_szFileName)).get());
            return false;                   // No use propagating of we already failed.
        }
        return true;
    }

    /// \brief Close the file and the mapping
    ///
    /// Check for error with GetErrorCode().
    /// \return true if propagation of the close is recommended, which it is if no error. false is not error indication though.
    bool CSourceMemFile::OutClose(void) {
        if (m_hMapping) {
            if (!CloseHandle(m_hMapping)) {
                SetError(ERROR_CODE_GENERIC, _T("CSourceMemFile::Close failed to close mapping [%s]"), my_ptr<_TCHAR>(AxLib::APerror()).get());
                return true;
            }
            m_hMapping = NULL;
        }
        if (m_hFile != INVALID_HANDLE_VALUE) {
            if (!CloseHandle(m_hFile)) {
                SetError(ERROR_CODE_GENERIC, _T("CSourceMemFile::Close failed to close file [%s]"), my_ptr<_TCHAR>(AxLib::APerror()).get());
                return true;
            }
            m_hFile = INVALID_HANDLE_VALUE;
        }
        return true;
    }
    /// \brief Get the next chunk from the input file
    ///
    /// The segment returned is actually a CSegMem, i.e. a mapping to the actual
    /// file - we do not copy to a memory buffer.
    ///
    /// Multiple calls on EOF conditions are allowed.
    ///
    /// \return A chunk, or zero-length on End-Of-File, or NULL on error.
    CSeg *CSourceMemFile::In() {
        if (m_cbStreamPos == m_cbFileSize) {
            return new CSeg;    // Return a zero-sized segment.
        }

⌨️ 快捷键说明

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