DLLを扱うクラス (CModule)

(2007.05.10)
#pragma once
 
// WAC.com Class Liblary for Visual C++
// Copyright (C) WAC.com Inc. All rights reserved.
//
// This file is a part of the WAC.com Class Liblary.
// The use and distribution terms for this software are covered by the
// Common Public License 1.0 (http://opensource.org/licenses/cpl.php)
// which can be found in the file CPL.TXT at the root of this distribution.
// By using this software in any fashion, you are agreeing to be bound by
// the terms of this license. You must not remove this notice, or
// any other, from this software.
 
// '04.05.10 : UNICODE版でも使用できるように修正 (sha)
// '04.05.15 : SizeofResource()を復活させた (sha)
// '04.05.27 : SizeofResource()の不具合?を修正 (sha)
// '07.02.27 : コードの整備 (sekine)
// '07.03.07 : コードの整備 & メソッド追加 (sekine)
// '07.03.09 : COUNTOFから_countofに変更 (sha)
// '07.03.19 : FreeLibraryAndExitThreadでハンドルをNULLクリアするように変更 (sekine)
// '07.04.12 : コードの整備 (sha)
 
#define _MODULE_H
 
#if _MSC_VER < 1400
#if !defined(_countof)
#define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0]))
#endif
#endif
 
 
////////////////////////////////////////////////////////////////////////////////
// CModuleT
 
template <bool t_bManaged>
class CModuleT  
{
protected:
    typedef CModuleT<t_bManaged>                thisClass;
 
public:
    CModuleT()
    {
        m_hModule = NULL;
    }
    CModuleT(HMODULE hModule)
    {
        m_hModule = NULL;
        this->Attach(hModule);
    }
    CModuleT(LPCTSTR lpFileName, bool bLoadLibrary = true)
    {
        m_hModule = NULL;
        if (bLoadLibrary)
        {
            this->LoadLibrary(lpFileName);
        }
        else
        {
            this->GetModuleHandle(lpFileName);
        }
    }
    virtual ~CModuleT()
    {
        if (t_bManaged && m_hModule != NULL)
        {
            this->FreeLibrary();
        }
    }
 
public:
    BOOL IsValid()
    {
        return m_hModule ? TRUE : FALSE;
    }
 
public:
    void Attach(HMODULE hModule)
    {
        ATLASSERT(m_hModule == NULL);
        ATLASSERT(hModule != NULL);
        m_hModule = hModule;
    }
    HMODULE Detach()
    {
        ATLASSERT(m_hModule != NULL);
        HMODULE hModule = m_hModule;
        m_hModule = NULL;
        return hModule;
    }
 
public:
    CModuleT& operator =(HMODULE hModule)
    {
        this->FreeLibrary();
        this->Attach(hModule);
        return *this;
    }
    operator HMODULE() const
    {
        return m_hModule;
    }
    HMODULE GetHandle()
    {
        return m_hModule;
    }
 
public:
    HMODULE LoadLibrary(LPCTSTR lpLibFileName)
    {
        ATLASSERT(m_hModule == NULL);
        m_hModule = ::LoadLibrary(lpLibFileName);
        return m_hModule;
    }
    HMODULE LoadLibraryEx(LPCSTR lpLibFileName, HANDLE hFile = NULL, DWORD dwFlags = 0)
    {
        ATLASSERT(m_hModule == NULL);
        ATLASSERT(hFile != NULL);
        m_hModule = ::LoadLibraryEx(lpLibFileName, hFile, dwFlags);
        return m_hModule;
    }
    BOOL FreeLibrary()
    {
        ATLASSERT(m_hModule != NULL);
        BOOL br = ::FreeLibrary(m_hModule);
        m_hModule = NULL;
        return br;
    }
    void FreeLibraryAndExitThread(DWORD dwExitCode)
    {
        ATLASSERT(m_hModule != NULL);
        ::FreeLibraryAndExitThread(m_hModule, dwExitCode);
        m_hModule = NULL;
    }
    // NOTE: CModuleHandle(ハンドルの解放を行わない)でのみ、使用可能
    HMODULE GetModuleHandle(LPCTSTR lpModuleName)
    {
        ATLASSERT(!t_bManaged);
        ATLASSERT(m_hModule == NULL);
        m_hModule = ::GetModuleHandle(lpModuleName);
        return m_hModule;
    }
    FARPROC GetProcAddress(LPCTSTR lpProcName)
    {
#if 0
        ATLASSERT(m_hModule != NULL);
#else
        // NOTE: 互換性維持のため
        if (m_hModule == NULL)
        {
            ATLASSERT(0);
            return NULL;
        }
#endif
        // m_hModuleがNULLの場合の挙動は、ドキュメントされていない
        return ::GetProcAddress(m_hModule, CT2A((LPTSTR)lpProcName));
    }
    DWORD GetModuleFileName(LPTSTR lpFilename, DWORD nSize)
    {
        ATLASSERT(m_hModule != NULL);
        return ::GetModuleFileName(m_hModule, lpFilename, nSize);
    }
#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
#ifndef _CSTRING_NS
    DWORD GetModuleFileName(CString& strFilename)
#else
    DWORD GetModuleFileName(_CSTRING_NS::CString& strFilename)
#endif
    {
        ATLASSERT(m_hModule != NULL);
 
        strFilename.Empty();
 
        TCHAR szFileName[_MAX_PATH] = { 0 };
        DWORD dwLength = ::GetModuleFileName(m_hModule, szFileName, _countof(szFileName));
        if (dwLength == 0)
        {
            return dwLength;
        }
 
        strFilename = szFileName;
        return dwLength;
    }
#endif
    BOOL DisableThreadLibraryCalls()
    {
        ATLASSERT(m_hModule != NULL);
        return ::DisableThreadLibraryCalls(m_hModule);
    }
 
public:
    HRSRC FindResource(LPCTSTR lpName, LPCTSTR lpType)
    {
        ATLASSERT(m_hModule != NULL);
        return ::FindResource(m_hModule, lpName, lpType);
    }
    HRSRC FindResourceEx(LPCTSTR lpType, LPCTSTR lpName, WORD wLanguage)
    {
        ATLASSERT(m_hModule != NULL);
        return ::FindResourceEx(m_hModule, lpType, lpName, wLanguage);
    }
    HGLOBAL LoadResource(HRSRC hResInfo)
    {
        ATLASSERT(m_hModule != NULL);
        return ::LoadResource(m_hModule, hResInfo);
    }
    DWORD SizeofResource(HRSRC hResInfo)
    {
        ATLASSERT(m_hModule != NULL);
        return ::SizeofResource(m_hModule, hResInfo);
    }
 
/* Del sha '02.07.04
public:
    // AtlGetDllVersion()が見つかったため、削除
    #define PACKVERSION(major,minor) MAKELONG(minor,major)
    static DWORD GetDllVersion(LPCTSTR lpstrDllName)
    {
        HRESULT hr = S_OK;
        DLLVERSIONINFO dllVersionInfo = { sizeof(DLLVERSIONINFO) };
//        hr = thisClass::InvokeDllGetVersion(lpstrDllName, &dllVersionInfo);
        hr = ::AtlGetDllVersion(lpstrDllName, &dllVersionInfo);
        if (FAILED(hr))
        {
            return 0;
        }
        return PACKVERSION(dllVersionInfo.dwMajorVersion, dllVersionInfo.dwMinorVersion);
    }
    // AtlGetDllVersionと同等
    static HRESULT InvokeDllGetVersion(LPCTSTR lpstrDllName, DLLVERSIONINFO* pDllVersionInfo)
    {
        CModule module;
        HMODULE hModule = module.LoadLibrary(lpstrDllName);
        if (hModule == NULL)
        {
            return E_FAIL;
        }
        return thisClass::InvokeDllGetVersion((HINSTANCE)module, pDllVersionInfo);
    }
    // AtlGetDllVersionと同等
    static HRESULT InvokeDllGetVersion(HINSTANCE hInstDLL, DLLVERSIONINFO* pDllVersionInfo)
    {
        if (hInstDLL == NULL)
        {
            return E_FAIL;
        }
        DLLGETVERSIONPROC func = (DLLGETVERSIONPROC)::GetProcAddress(hInstDLL, "DllGetVersion");
        if (func == NULL)
        {
            return E_FAIL;
        }
        return (*func)(&pDllVersionInfo);
    }
...Del sha '02.07.04 */
 
protected:
    HMODULE m_hModule;
};
 
typedef CModuleT<false>                            CModuleHandle;
typedef CModuleT<true>                            CModule;
一覧に戻る
© 2003 WAC.com All Right Reserved.