| // 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; |
| } |
| |
| |
| } |
| } |
| |