| 1 | #pragma once
|
|---|
| 2 |
|
|---|
| 3 | #include <error.hpp>
|
|---|
| 4 |
|
|---|
| 5 | namespace simple_registry {
|
|---|
| 6 | class registry_exception {
|
|---|
| 7 | std::wstring what_;
|
|---|
| 8 | public:
|
|---|
| 9 | registry_exception(std::wstring what) : what_(what) {}
|
|---|
| 10 | registry_exception(std::wstring path, std::wstring what) : what_(path + _T(" -- ") + what) {}
|
|---|
| 11 | registry_exception(std::wstring path, std::wstring key, std::wstring what) : what_(path + _T(".") + key + _T(" -- ") + what) {}
|
|---|
| 12 | std::wstring what() {
|
|---|
| 13 | return what_;
|
|---|
| 14 | }
|
|---|
| 15 | };
|
|---|
| 16 | class registry_key {
|
|---|
| 17 | HKEY hKey_;
|
|---|
| 18 | std::wstring path_;
|
|---|
| 19 | BYTE *bData_;
|
|---|
| 20 | TCHAR *buffer_;
|
|---|
| 21 | public:
|
|---|
| 22 | registry_key(HKEY hRootKey, std::wstring path) : path_(path), hKey_(NULL), bData_(NULL), buffer_(NULL) {
|
|---|
| 23 | LONG lRet = ERROR_SUCCESS;
|
|---|
| 24 | if (lRet = RegOpenKeyEx(hRootKey, path.c_str(), 0, KEY_QUERY_VALUE|KEY_READ, &hKey_) != ERROR_SUCCESS)
|
|---|
| 25 | throw registry_exception(path, _T("Failed to open key: ") + error::format::from_system(lRet));
|
|---|
| 26 | }
|
|---|
| 27 | ~registry_key() {
|
|---|
| 28 | if (hKey_ != NULL)
|
|---|
| 29 | RegCloseKey(hKey_);
|
|---|
| 30 | delete [] bData_;
|
|---|
| 31 | delete [] buffer_;
|
|---|
| 32 | }
|
|---|
| 33 | std::wstring get_string(std::wstring key, DWORD buffer_length = 2048) {
|
|---|
| 34 | DWORD type;
|
|---|
| 35 | std::wstring ret;
|
|---|
| 36 | DWORD cbData = buffer_length;
|
|---|
| 37 | delete [] bData_;
|
|---|
| 38 | bData_ = new BYTE[cbData+2];
|
|---|
| 39 | // TODO: add get size here !
|
|---|
| 40 | LONG lRet = RegQueryValueEx(hKey_, key.c_str(), NULL, &type, bData_, &cbData);
|
|---|
| 41 | if (lRet != ERROR_SUCCESS)
|
|---|
| 42 | throw registry_exception(path_, key, _T("Failed to get value: ") + error::format::from_system(lRet));
|
|---|
| 43 | if (cbData >= buffer_length || cbData < 0)
|
|---|
| 44 | throw registry_exception(path_, key, _T("Failed to get value: buffer to small"));
|
|---|
| 45 | bData_[cbData] = 0;
|
|---|
| 46 | if (type == REG_SZ) {
|
|---|
| 47 | ret = reinterpret_cast<LPCTSTR>(bData_);
|
|---|
| 48 | } else if (type == REG_EXPAND_SZ) {
|
|---|
| 49 | std::wstring s = reinterpret_cast<LPCTSTR>(bData_);
|
|---|
| 50 | delete [] buffer_;
|
|---|
| 51 | buffer_ = new TCHAR[buffer_length+1];
|
|---|
| 52 | DWORD expRet = ExpandEnvironmentStrings(s.c_str(), buffer_, buffer_length);
|
|---|
| 53 | if (expRet >= buffer_length)
|
|---|
| 54 | throw registry_exception(path_, key, _T("Buffer to small (expand)"));
|
|---|
| 55 | else
|
|---|
| 56 | ret = buffer_;
|
|---|
| 57 | } else {
|
|---|
| 58 | throw registry_exception(path_, key, _T("Unknown type (not a string)"));
|
|---|
| 59 | }
|
|---|
| 60 | return ret;
|
|---|
| 61 | }
|
|---|
| 62 | DWORD get_int(std::wstring key) {
|
|---|
| 63 | DWORD type;
|
|---|
| 64 | DWORD cbData = sizeof(DWORD);
|
|---|
| 65 | DWORD ret = 0;
|
|---|
| 66 | LONG lRet = RegQueryValueEx(hKey_, key.c_str(), NULL, &type, reinterpret_cast<LPBYTE>(&ret), &cbData);
|
|---|
| 67 | if (lRet != ERROR_SUCCESS)
|
|---|
| 68 | throw registry_exception(path_, key, _T("Failed to get value: ") + error::format::from_system(lRet));
|
|---|
| 69 | if (type != REG_DWORD)
|
|---|
| 70 | throw registry_exception(path_, key, _T("Unknown type (not a DWORD)"));
|
|---|
| 71 | return ret;
|
|---|
| 72 | }
|
|---|
| 73 |
|
|---|
| 74 | std::list<std::wstring> get_keys(DWORD buffer_length = 2048) {
|
|---|
| 75 | std::list<std::wstring> ret;
|
|---|
| 76 | DWORD cSubKeys=0;
|
|---|
| 77 | DWORD cMaxKeyLen;
|
|---|
| 78 | // Get the class name and the value count.
|
|---|
| 79 | LONG lRet = RegQueryInfoKey(hKey_,NULL,NULL,NULL,&cSubKeys,&cMaxKeyLen,NULL,NULL,NULL,NULL,NULL,NULL);
|
|---|
| 80 | if (lRet != ERROR_SUCCESS)
|
|---|
| 81 | throw registry_exception(path_, _T("Failed to query key info: ") + error::format::from_system(lRet));
|
|---|
| 82 | if (cSubKeys == 0)
|
|---|
| 83 | return ret;
|
|---|
| 84 | delete [] buffer_;
|
|---|
| 85 | buffer_ = new TCHAR[cMaxKeyLen+20];
|
|---|
| 86 | for (unsigned int i=0; i<cSubKeys; i++) {
|
|---|
| 87 | lRet = RegEnumKey(hKey_, i, buffer_, cMaxKeyLen+10);
|
|---|
| 88 | if (lRet != ERROR_SUCCESS) {
|
|---|
| 89 | throw registry_exception(path_, _T("Failed to enumerate: ") + error::lookup::last_error(lRet));
|
|---|
| 90 | }
|
|---|
| 91 | std::wstring str = buffer_;
|
|---|
| 92 | ret.push_back(str);
|
|---|
| 93 | }
|
|---|
| 94 | return ret;
|
|---|
| 95 | }
|
|---|
| 96 |
|
|---|
| 97 | static std::wstring get_string(HKEY hKey, std::wstring path, std::wstring key) {
|
|---|
| 98 | registry_key reg(hKey, path);
|
|---|
| 99 | return reg.get_string(key);
|
|---|
| 100 | }
|
|---|
| 101 |
|
|---|
| 102 |
|
|---|
| 103 | };
|
|---|
| 104 |
|
|---|
| 105 | }
|
|---|