blob: 74e255df4abb755076c9d361eb5f00ac78fdc64b [file] [log] [blame]
// Windows/Registry.cpp
#include "StdAfx.h"
#ifndef _UNICODE
#include "Common/StringConvert.h"
#endif
#include "Windows/Registry.h"
#include <wx/config.h>
class HKEY_Impl
{
public:
wxString path;
HKEY_Impl(wxString a) : path(a) {}
};
namespace NWindows {
namespace NRegistry {
#define ERROR_SET_VALUE (E_INVALIDARG) // FIXME
#define ERROR_GET_VALUE (E_INVALIDARG) // FIXME
#define PROGRAM_NAME L"p7zip"
static wxConfig * g_config = 0;
static int g_config_ref = 0;
static void configAddRef() {
if (g_config == 0) {
g_config = new wxConfig(PROGRAM_NAME);
g_config->Flush(true);
wxConfigBase::Set(g_config);
}
g_config_ref++;
}
static void configSubRef() {
if (g_config_ref >= 1)
{
g_config_ref--;
if (g_config_ref == 0) {
delete g_config;
g_config = 0;
wxConfigBase::Set(NULL);
} else {
g_config->Flush(true);
}
}
}
LONG CKey::Close()
{
if (_object)
{
configSubRef();
delete _object;
}
_object = 0;
return ERROR_SUCCESS;
}
LONG CKey::Create(HKEY parentKey, LPCTSTR keyName)
{
Close();
configAddRef();
wxString path;
if (parentKey == HKEY_CURRENT_USER) {
path=L"/" + wxString(keyName);
} else {
path = parentKey->path + L"/" + wxString(keyName);
}
_object = new HKEY_Impl(path);
return ERROR_SUCCESS;
}
LONG CKey::Open(HKEY parentKey, LPCTSTR keyName, REGSAM accessMask)
{
Close();
configAddRef();
wxString path;
if (parentKey == HKEY_CURRENT_USER) {
path=L"/" + wxString(keyName);
} else {
path = parentKey->path + L"/" + wxString(keyName);
}
_object = new HKEY_Impl(path);
return ERROR_SUCCESS;
}
LONG CKey::RecurseDeleteKey(LPCTSTR subKeyName)
{
g_config->SetPath(_object->path);
bool ret = g_config->DeleteGroup(subKeyName);
if (ret) return ERROR_SUCCESS;
return ERROR_GET_VALUE;
}
LONG CKey::DeleteValue(LPCTSTR name)
{
g_config->SetPath(_object->path);
bool ret = g_config->DeleteEntry(name);
if (ret) return ERROR_SUCCESS;
return ERROR_GET_VALUE;
}
LONG CKey::QueryValue(LPCTSTR name, UInt32 &value)
{
g_config->SetPath(_object->path);
long val;
bool ret = g_config->Read(name,&val);
if (ret) {
value = (UInt32)val;
return ERROR_SUCCESS;
}
return ERROR_GET_VALUE;
}
LONG CKey::QueryValue(LPCTSTR name, bool &value)
{
g_config->SetPath(_object->path);
bool ret = g_config->Read(name,&value);
if (ret) return ERROR_SUCCESS;
return ERROR_GET_VALUE;
}
LONG CKey::QueryValue(LPCTSTR name, CSysString &value)
{
g_config->SetPath(_object->path);
wxString val;
bool ret = g_config->Read(name,&val);
if (ret) {
value = val;
return ERROR_SUCCESS;
}
return ERROR_GET_VALUE;
}
LONG CKey::GetValue_IfOk(LPCTSTR name, UInt32 &value)
{
UInt32 newVal;
LONG res = QueryValue(name, newVal);
if (res == ERROR_SUCCESS)
value = newVal;
return res;
}
LONG CKey::GetValue_IfOk(LPCTSTR name, bool &value)
{
bool newVal;
LONG res = QueryValue(name, newVal);
if (res == ERROR_SUCCESS)
value = newVal;
return res;
}
LONG CKey::SetValue(LPCTSTR valueName, UInt32 value)
{
g_config->SetPath(_object->path);
bool ret = g_config->Write(valueName,(long)value);
if (ret == true) return ERROR_SUCCESS;
return ERROR_SET_VALUE;
}
LONG CKey::SetValue(LPCTSTR valueName, bool value)
{
g_config->SetPath(_object->path);
bool ret = g_config->Write(valueName,value);
if (ret == true) return ERROR_SUCCESS;
return ERROR_SET_VALUE;
}
LONG CKey::SetValue(LPCTSTR valueName, LPCTSTR value)
{
g_config->SetPath(_object->path);
bool ret = g_config->Write(valueName,value);
if (ret == true) return ERROR_SUCCESS;
return ERROR_SET_VALUE;
}
LONG CKey::SetValue(LPCTSTR name, const void *value, UInt32 size)
{
static char hexa[] = "0123456789ABCDEF";
/* FIXME
MYASSERT(value != NULL);
MYASSERT(_object != NULL);
return RegSetValueEx(_object, name, NULL, REG_BINARY, (const BYTE *)value, size);
*/
BYTE *buf = (BYTE *)value;
wxString str;
for(UInt32 i=0;i<size;i++)
{
str += hexa[ (buf[i]>>4) & 0x0f];
str += hexa[ buf[i] & 0x0f];
}
return SetValue(name,(LPCTSTR)str);
}
LONG CKey::EnumKeys(CSysStringVector &keyNames)
{
g_config->SetPath(_object->path);
keyNames.Clear();
// enumeration variables
wxString str;
long dummy;
bool bCont = g_config->GetFirstEntry(str, dummy);
while ( bCont ) {
keyNames.Add((const TCHAR *)str);
bCont = g_config->GetNextEntry(str, dummy);
}
// now all groups...
bCont = g_config->GetFirstGroup(str, dummy);
while ( bCont ) {
keyNames.Add((const TCHAR *)str);
bCont = g_config->GetNextGroup(str, dummy);
}
return ERROR_SUCCESS;
}
LONG CKey::QueryValue(LPCTSTR name, void *value, UInt32 &dataSize)
{
g_config->SetPath(_object->path);
wxString str;
bool ret = g_config->Read(name,&str);
if (ret == false) return ERROR_GET_VALUE;
size_t l = str.Len() / 2;
if (l > dataSize) l = dataSize;
else dataSize=l;
BYTE *buf = (BYTE *)value;
for(UInt32 i=0;i<dataSize;i++)
{
char cval[3];
cval[0] = (char)str[2*i];
cval[1] = (char)str[2*i+1];
cval[2] = 0;
unsigned uval = 0;
sscanf(cval,"%x",&uval);
buf[i]=(BYTE)uval;
}
return ERROR_SUCCESS;
}
LONG CKey::QueryValue(LPCTSTR name, CByteBuffer &value, UInt32 &dataSize)
{
g_config->SetPath(_object->path);
wxString str;
bool ret = g_config->Read(name,&str);
if (ret == false) return ERROR_GET_VALUE;
dataSize = str.Len() / 2;
value.SetCapacity(dataSize);
return QueryValue(name, (BYTE *)value, dataSize);
}
LONG CKey::SetValue_Strings(LPCTSTR valueName, const UStringVector &strings)
{
UInt32 numChars = 0;
int i;
for (i = 0; i < strings.Size(); i++)
numChars += strings[i].Length() + 1;
CBuffer<wchar_t> buffer;
buffer.SetCapacity(numChars);
int pos = 0;
for (i = 0; i < strings.Size(); i++)
{
const UString &s = strings[i];
MyStringCopy((wchar_t *)buffer + pos, (const wchar_t *)s);
pos += s.Length() + 1;
}
return SetValue(valueName, buffer, numChars * sizeof(wchar_t));
}
LONG CKey::GetValue_Strings(LPCTSTR valueName, UStringVector &strings)
{
strings.Clear();
CByteBuffer buffer;
UInt32 dataSize;
LONG res = QueryValue(valueName, buffer, dataSize);
if (res != ERROR_SUCCESS)
return res;
if (dataSize % sizeof(wchar_t) != 0)
return E_FAIL;
const wchar_t *data = (const wchar_t *)(const Byte *)buffer;
int numChars = dataSize / sizeof(wchar_t);
UString s;
for (int i = 0; i < numChars; i++)
{
wchar_t c = data[i];
if (c == 0)
{
strings.Add(s);
s.Empty();
}
else
s += c;
}
return res;
}
}
}