Windows CE向けEVCによるレジストリ操作ユーティリティクラスの設計

Windows CEプラットフォームでの組み込みアプリケーション開発において、レジストリ操作はシステム設定や永続データ管理の基本要素です。Win32 APIを直接使用する場合、エラーハンドリングやリソース管理が複雑になるため、ラッパークラスによる抽象化が有効です。以下に実装例を示します。

#ifndef REGISTRY_ACCESSOR_H
#define REGISTRY_ACCESSOR_H
#include <windows.h>

class RegistryAccessor {
public:
    bool removeKey(const TCHAR* path);
    bool removeValue(const TCHAR* name);
    bool setMultiString(const TCHAR* name, const TCHAR* value, DWORD length);
    bool setBinaryData(const TCHAR* name, const BYTE* data, DWORD size);
    bool setDwordValue(const TCHAR* name, DWORD value);
    bool setStringValue(const TCHAR* name, const TCHAR* value);
    bool setStringValue(const TCHAR* name, const TCHAR* value, DWORD length);
    DWORD getDwordValue(const TCHAR* name, DWORD defaultValue = 0);
    const TCHAR* getStringValue(const TCHAR* name);
    BYTE* getBinaryData(const TCHAR* name);
    DWORD getBinaryData(const TCHAR* name, BYTE* buffer, DWORD bufferSize);
    bool getStringValue(const TCHAR* name, TCHAR* buffer, DWORD bufferSize);
    bool enumerateValue(TCHAR* nameBuffer, DWORD nameSize, 
                      TCHAR* valueBuffer, DWORD valueSize);
    bool enumerateSubkey(TCHAR* buffer, DWORD bufferSize);
    bool isValid() const;
    operator HKEY() const;
    void reset();
    
    RegistryAccessor(HKEY rootKey, const TCHAR* subkeyPath);
    bool openKey(HKEY rootKey, const TCHAR* subkeyPath, REGSAM access = KEY_READ);
    bool createKey(HKEY rootKey, const TCHAR* subkeyPath);
    RegistryAccessor();
    ~RegistryAccessor();

private:
    HKEY registryHandle;
    DWORD currentIndex;
    BYTE* valueBuffer;
};
#endif

実装クラスでは、Win32レジストリAPIを安全にラップするためのメカニズムを提供します。特にリソースリーク防止のため、デストラクタで確実にハンドルを解放し、動的メモリを適切に管理します。

#include "RegistryAccessor.h"

#define SAFE_FREE(ptr) { \
    if (ptr) { \
        LocalFree(ptr); \
        ptr = nullptr; \
    } \
}

RegistryAccessor::RegistryAccessor() 
    : registryHandle(nullptr), 
      currentIndex(0), 
      valueBuffer(nullptr) {}

RegistryAccessor::RegistryAccessor(HKEY rootKey, const TCHAR* subkeyPath) 
    : registryHandle(nullptr), 
      currentIndex(0), 
      valueBuffer(nullptr) 
{
    openKey(rootKey, subkeyPath);
}

RegistryAccessor::~RegistryAccessor() {
    if (registryHandle) {
        RegCloseKey(registryHandle);
    }
    SAFE_FREE(valueBuffer);
}

bool RegistryAccessor::createKey(HKEY rootKey, const TCHAR* subkeyPath) {
    DWORD disposition;
    return RegCreateKeyEx(
        rootKey, 
        subkeyPath, 
        0, 
        nullptr, 
        REG_OPTION_NON_VOLATILE, 
        KEY_ALL_ACCESS, 
        nullptr, 
        &registryHandle, 
        &disposition
    ) == ERROR_SUCCESS;
}

bool RegistryAccessor::openKey(HKEY rootKey, const TCHAR* subkeyPath, REGSAM access) {
    return RegOpenKeyEx(
        rootKey, 
        subkeyPath, 
        0, 
        access, 
        &registryHandle
    ) == ERROR_SUCCESS;
}

void RegistryAccessor::reset() {
    if (registryHandle) {
        RegCloseKey(registryHandle);
        registryHandle = nullptr;
    }
    SAFE_FREE(valueBuffer);
    currentIndex = 0;
}

RegistryAccessor::operator HKEY() const {
    return registryHandle;
}

bool RegistryAccessor::isValid() const {
    return registryHandle != nullptr;
}

bool RegistryAccessor::enumerateSubkey(TCHAR* buffer, DWORD bufferSize) {
    if (!registryHandle) return false;
    return RegEnumKeyEx(
        registryHandle, 
        currentIndex++, 
        buffer, 
        &bufferSize, 
        nullptr, 
        nullptr, 
        nullptr, 
        nullptr
    ) == ERROR_SUCCESS;
}

bool RegistryAccessor::enumerateValue(TCHAR* nameBuffer, DWORD nameSize, 
                                    TCHAR* valueBuffer, DWORD valueSize) {
    if (!registryHandle) return false;
    
    DWORD valueType;
    DWORD actualValueSize = valueSize * sizeof(TCHAR);
    
    return RegEnumValue(
        registryHandle, 
        currentIndex++, 
        nameBuffer, 
        &nameSize, 
        nullptr, 
        &valueType, 
        (BYTE*)valueBuffer, 
        &actualValueSize
    ) == ERROR_SUCCESS;
}

DWORD RegistryAccessor::getDwordValue(const TCHAR* name, DWORD defaultValue) {
    if (!registryHandle) return defaultValue;
    
    DWORD result = defaultValue;
    DWORD size = sizeof(DWORD);
    RegQueryValueEx(
        registryHandle, 
        name, 
        nullptr, 
        nullptr, 
        (BYTE*)&result, 
        &size
    );
    return result;
}

bool RegistryAccessor::setDwordValue(const TCHAR* name, DWORD value) {
    if (!registryHandle) return false;
    return RegSetValueEx(
        registryHandle, 
        name, 
        0, 
        REG_DWORD, 
        (BYTE*)&value, 
        sizeof(DWORD)
    ) == ERROR_SUCCESS;
}

bool RegistryAccessor::setStringValue(const TCHAR* name, const TCHAR* value) {
    return setStringValue(name, value, _tcslen(value) + 1);
}

bool RegistryAccessor::setStringValue(const TCHAR* name, 
                                    const TCHAR* value, 
                                    DWORD length) {
    if (!registryHandle) return false;
    return RegSetValueEx(
        registryHandle, 
        name, 
        0, 
        REG_SZ, 
        (BYTE*)value, 
        length * sizeof(TCHAR)
    ) == ERROR_SUCCESS;
}

bool RegistryAccessor::removeValue(const TCHAR* name) {
    if (!registryHandle) return false;
    return RegDeleteValue(registryHandle, name) == ERROR_SUCCESS;
}

タグ: Windows CE EVC Registry API Embedded Systems Win32 API

5月31日 04:39 投稿