サンプルで用いたヘルパ関数

いちごパック > COM/ActiveXの解説 > サンプルで用いたヘルパ関数

ヘルパ関数の一覧

ichigopackのサンプルでは次の関数を用いています。 ヘルパ関数はsuppで開始するようにしています。
関数名内容
suppLogFileAppendWデータをファイルに追加出力する
suppGetModuleFileNameモジュールのファイル名を取得する
suppGuidToStringGUIDを文字列形式に変換する
suppIsPerUserRequest引数にuserが指定されているか調べる
suppGetRegKeyHKEY_LOCAL_MACHINEまたはHKEY_CURRENT_USERのルートキーを取得する
suppGetRegKeyProgIDProgID文字列のサブキーを取得する
suppGetRegKeyAppIDAppIDのレジストリサブキーを取得する
suppGetRegKeyCLSIDCLSIDのレジストリサブキーを取得する
suppGetRegKeyInterfaceIIDのレジストリサブキーを取得する
suppRegSetStringWキー、値の名前、文字列で指定されたレジストリの値を設定する
suppRegRemoveKeyWキーで指定されたレジストリを、そのサブキーも含め削除する
C++の例外を発生させない関数にはthrow()をつけています。 DLLを実装する際は、C++の例外を発生させる可能性について意識し、 C++の例外を発生する可能性があればtry、catchで保護する必要があります。

ヘルパ関数の実装

コード全体をコピーしたい場合は、著作権表示といちごパックへのリンクを残した形でコピーしてください。 サンプルコードとしてその一部を利用、参照いただくぶんには問題ありません。
//
// Copyright (c) 2016 The Ichigopack Project (http://ichigopack.net/).
//

#include <windows.h>    // advapi32.lib
#include <rpc.h>        // rpcrt4.lib
#include <string>
#include <fstream>
#include <sstream>
#include <algorithm>


inline HRESULT
suppLogFileAppendW( LPCWSTR pszFileNameW, const void* pv, ULONG cb,
                    ULONG* pcbWritten = NULL ) throw()
{
    DWORD   cbWrittenTemp;
    if ( pcbWritten == NULL ) {
        pcbWritten = &cbWrittenTemp;
    }
    *pcbWritten = 0;
    HANDLE hFile = CreateFileW(
                       pszFileNameW, GENERIC_READ |
                       GENERIC_WRITE, FILE_SHARE_READ, NULL,
                       OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if ( hFile == INVALID_HANDLE_VALUE ) {
        return E_FAIL;
    }
    LARGE_INTEGER liDist;
    liDist.QuadPart = 0;
    if ( SetFilePointerEx(hFile, liDist, NULL, FILE_END) ) {
        WriteFile(hFile, pv, cb, pcbWritten, NULL);
    }
    CloseHandle(hFile);
    return (*pcbWritten == cb) ? S_OK : E_FAIL;
}

inline std::wstring
suppGetModuleFileName( HINSTANCE hinst )
{
    WCHAR   wszBuf[MAX_PATH + 1];
    DWORD   dw;
    dw = GetModuleFileNameW( (HMODULE)hinst, wszBuf, MAX_PATH + 1 );
    if ( dw > 0 && dw <= MAX_PATH ) {
        return std::wstring( wszBuf );
    }
    return std::wstring();
}

// L"xxxxxxxx-xxxx-...xx"
inline std::wstring
suppGuidToString( const GUID& rguid, bool brackets_flag )
{
    std::wstring    ret;
    RPC_WSTR wstr = NULL;
    if ( RPC_S_OK == UuidToStringW( &rguid, &wstr ) ) {
        if ( brackets_flag ) {
            ret += L'{';
        }
        ret += (WCHAR*)wstr;
        if ( brackets_flag ) {
            ret += L'}';
        }
        RpcStringFreeW( &wstr );
    }
    return ret;
}

inline bool
suppIsPerUserRequest( LPCWSTR pwszCmdline ) throw()
{
    if ( pwszCmdline == NULL ) {
        return false;
    }
    if ( (pwszCmdline[0] == L'U' || pwszCmdline[0] == L'u') &&
         (pwszCmdline[1] == L'S' || pwszCmdline[1] == L's') &&
         (pwszCmdline[2] == L'E' || pwszCmdline[2] == L'e') &&
         (pwszCmdline[3] == L'R' || pwszCmdline[3] == L'r') ) {
        return true;
    }
    return false;
}

inline std::wstring
suppGetRegKey( HKEY* phkeyRoot, bool per_user_flag )
{
    *phkeyRoot = per_user_flag ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE;
    return std::wstring( L"SOFTWARE\\Classes" );
}

inline std::wstring
suppGetRegKeyGUID( HKEY* phkeyRoot, bool per_user_flag, const GUID& rguid,
                   LPCWSTR pwszGUIDType, LPCWSTR pwszSubkey )
{
    std::wostringstream wos;
    std::wstring    wstrGUID;
    std::wstring    wstrKeyRoot;
    wstrKeyRoot = suppGetRegKey( phkeyRoot, per_user_flag );
    wstrGUID = suppGuidToString( rguid, true );
    if ( !wstrKeyRoot.empty() && !wstrGUID.empty() ) {
        wos << wstrKeyRoot << L'\\' << pwszGUIDType << L'\\' << wstrGUID;
        if ( pwszSubkey != NULL ) {
            wos << L'\\' << pwszSubkey;
        }
        return wos.str();
    }
    return std::wstring();
}

inline std::wstring
suppGetRegKeyProgID( HKEY* phkeyRoot, bool per_user_flag,
                     LPCWSTR pwszProgID, LPCWSTR pwszSubkey )
{
    std::wostringstream wos;
    std::wstring    wstrKeyRoot;
    wstrKeyRoot = suppGetRegKey( phkeyRoot, per_user_flag );
    if ( !wstrKeyRoot.empty() ) {
        wos << wstrKeyRoot << L'\\' << pwszProgID;
        if ( pwszSubkey != NULL ) {
            wos << L'\\' << pwszSubkey;
        }
        return wos.str();
    }
    return std::wstring();
}

inline std::wstring
suppGetRegKeyAppID( HKEY* phkeyRoot, bool per_user_flag,
                    const CLSID& rappid, LPCWSTR pwszSubkey )
{
    return suppGetRegKeyGUID( phkeyRoot, per_user_flag, rappid, L"AppID",
                              pwszSubkey );
}

inline std::wstring
suppGetRegKeyCLSID( HKEY* phkeyRoot, bool per_user_flag,
                    const CLSID& rclsid, LPCWSTR pwszSubkey )
{
    return suppGetRegKeyGUID( phkeyRoot, per_user_flag, rclsid, L"CLSID",
                              pwszSubkey );
}

inline std::wstring
suppGetRegKeyInterface( HKEY* phkeyRoot, bool per_user_flag,
                        const IID& riid, LPCWSTR pwszSubkey )
{
    return suppGetRegKeyGUID( phkeyRoot, per_user_flag, riid, L"Interface",
                              pwszSubkey );
}

inline LONG
suppRegSetStringW(HKEY hkeyRoot, LPCWSTR pwszSubkey,
                  LPCWSTR pwszValueName, LPCWSTR pwszValue)
{
    LONG    ret = ERROR_SUCCESS;
    HKEY    hkeySub = hkeyRoot;
    if ( pwszSubkey != NULL ) {
        ret = RegCreateKeyExW(
                  hkeyRoot, pwszSubkey, 0, NULL, REG_OPTION_NON_VOLATILE,
                  KEY_READ | KEY_WRITE, NULL, &hkeySub, NULL);
    }
    if ( ret == ERROR_SUCCESS ) {
        DWORD  cbData = sizeof(pwszValue[0]) * (lstrlenW(pwszValue) + 1);
        ret = RegSetValueExW(
                  hkeySub, pwszValueName, 0, REG_SZ,
                  (const BYTE*)(pwszValue), cbData );
        if ( pwszSubkey != NULL ) {
            RegCloseKey( hkeySub );
        }
    }
    return ret;
}

inline LONG
suppRegRemoveKeyW(HKEY hkeyRoot, LPCWSTR pwszKey) throw()
{
    const int   KEYNAME_MAX =
        256; // full key name limit = 255 characters (MSDN)
    LONG    ret = ERROR_SUCCESS;
    WCHAR   wszSubkey[KEYNAME_MAX];
    DWORD   cSubkey;
    HKEY    hkeySub;
    ret = RegOpenKeyExW( hkeyRoot, pwszKey, 0, KEY_READ, &hkeySub );
    if (ret == ERROR_FILE_NOT_FOUND) {
        return ERROR_SUCCESS;
    }
    if (ret != ERROR_SUCCESS) {
        return ret;
    }
    while (1) {
        cSubkey = KEYNAME_MAX;
        ret = RegEnumKeyExW(hkeySub, 0, wszSubkey,
                            &cSubkey, NULL, NULL, NULL,  NULL);
        if (ret == ERROR_NO_MORE_ITEMS) {
            break;
        }
        if (ret != ERROR_SUCCESS) {
            break;
        }
        ret = suppRegRemoveKeyW(hkeySub, wszSubkey);
        if (ret != ERROR_SUCCESS) {
            break;
        }
    }
    RegCloseKey(hkeySub);
    if (ret != ERROR_NO_MORE_ITEMS) {
        return ret;
    }
    return RegDeleteKeyW(hkeyRoot, pwszKey);
}


関連ページ

  • COM/ActiveXの解説ページ 目次