Registry support enhanced
This commit is contained in:
parent
3948924124
commit
983bcbf9a2
@ -68,6 +68,11 @@ namespace winstd
|
|||||||
///
|
///
|
||||||
class WINSTD_API vmemory;
|
class WINSTD_API vmemory;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Registry wrapper class
|
||||||
|
///
|
||||||
|
class WINSTD_API reg_key;
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -654,6 +659,117 @@ namespace winstd
|
|||||||
protected:
|
protected:
|
||||||
HANDLE m_proc; ///< Handle of memory's process
|
HANDLE m_proc; ///< Handle of memory's process
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class WINSTD_API reg_key : public handle<HKEY>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
///
|
||||||
|
/// Initializes a new class instance with the object handle set to NULL.
|
||||||
|
///
|
||||||
|
inline reg_key() : handle<HKEY>() {}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Initializes a new class instance with an already available object handle.
|
||||||
|
///
|
||||||
|
/// \param[in] h Initial object handle value
|
||||||
|
///
|
||||||
|
inline reg_key(_In_opt_ handle_type h) : handle<HKEY>(h) {}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Move constructor
|
||||||
|
///
|
||||||
|
/// \param[inout] h A rvalue reference of another object
|
||||||
|
///
|
||||||
|
inline reg_key(_Inout_ reg_key &&h) : handle<HKEY>(std::move(h)) {}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Closes a handle to the registry key.
|
||||||
|
///
|
||||||
|
/// \sa [RegCloseKey function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724837.aspx)
|
||||||
|
///
|
||||||
|
virtual ~reg_key();
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Move assignment
|
||||||
|
///
|
||||||
|
/// \param[inout] h A rvalue reference of another object
|
||||||
|
///
|
||||||
|
reg_key& operator=(_Inout_ reg_key &&h)
|
||||||
|
{
|
||||||
|
if (this != std::addressof(h))
|
||||||
|
*(handle<handle_type>*)this = std::move(h);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Creates the specified registry key. If the key already exists, the function opens it.
|
||||||
|
///
|
||||||
|
/// \return
|
||||||
|
/// - true when creation succeeds;
|
||||||
|
/// - false when creation fails. For extended error information, call `GetLastError()`.
|
||||||
|
///
|
||||||
|
/// \sa [RegCreateKeyEx function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724844.aspx)
|
||||||
|
///
|
||||||
|
inline bool create(
|
||||||
|
_In_ HKEY hKey,
|
||||||
|
_In_ LPCTSTR lpSubKey,
|
||||||
|
_In_opt_ LPTSTR lpClass,
|
||||||
|
_In_ DWORD dwOptions,
|
||||||
|
_In_ REGSAM samDesired,
|
||||||
|
_In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes = NULL,
|
||||||
|
_Out_opt_ LPDWORD lpdwDisposition = NULL)
|
||||||
|
{
|
||||||
|
handle_type h;
|
||||||
|
LSTATUS s = RegCreateKeyEx(hKey, lpSubKey, 0, lpClass, dwOptions, samDesired, lpSecurityAttributes, &h, lpdwDisposition);
|
||||||
|
if (s == ERROR_SUCCESS) {
|
||||||
|
attach(h);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
SetLastError(s);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Opens the specified registry key.
|
||||||
|
///
|
||||||
|
/// \return
|
||||||
|
/// - true when creation succeeds;
|
||||||
|
/// - false when creation fails. For extended error information, call `GetLastError()`.
|
||||||
|
///
|
||||||
|
/// \sa [RegOpenKeyEx function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724897.aspx)
|
||||||
|
///
|
||||||
|
inline bool open(
|
||||||
|
_In_ HKEY hKey,
|
||||||
|
_In_opt_ LPCTSTR lpSubKey,
|
||||||
|
_In_ DWORD ulOptions,
|
||||||
|
_In_ REGSAM samDesired)
|
||||||
|
{
|
||||||
|
handle_type h;
|
||||||
|
LONG s = RegOpenKeyEx(hKey, lpSubKey, ulOptions, samDesired, &h);
|
||||||
|
if (s == ERROR_SUCCESS) {
|
||||||
|
attach(h);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
SetLastError(s);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// This class is noncopyable.
|
||||||
|
reg_key(_In_ const reg_key &h);
|
||||||
|
reg_key& operator=(_In_ const reg_key &h);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
///
|
||||||
|
/// Closes a handle to the registry key.
|
||||||
|
///
|
||||||
|
/// \sa [RegCloseKey function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724837.aspx)
|
||||||
|
///
|
||||||
|
virtual void free_internal();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -878,8 +994,6 @@ inline VOID GuidToStringW(_In_ LPCGUID lpGuid, _Out_ std::basic_string<_Elem, _T
|
|||||||
template<class _Elem, class _Traits, class _Ax>
|
template<class _Elem, class _Traits, class _Ax>
|
||||||
inline LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCSTR pszName, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue)
|
inline LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCSTR pszName, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue)
|
||||||
{
|
{
|
||||||
assert(0); // TODO: Test this code.
|
|
||||||
|
|
||||||
LSTATUS lResult;
|
LSTATUS lResult;
|
||||||
BYTE aStackBuffer[WINSTD_STACK_BUFFER_BYTES];
|
BYTE aStackBuffer[WINSTD_STACK_BUFFER_BYTES];
|
||||||
DWORD dwSize = sizeof(aStackBuffer), dwType;
|
DWORD dwSize = sizeof(aStackBuffer), dwType;
|
||||||
@ -889,10 +1003,11 @@ inline LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCSTR pszName, _Out_
|
|||||||
if (lResult == ERROR_SUCCESS) {
|
if (lResult == ERROR_SUCCESS) {
|
||||||
if (dwType == REG_SZ || dwType == REG_MULTI_SZ) {
|
if (dwType == REG_SZ || dwType == REG_MULTI_SZ) {
|
||||||
// The value is REG_SZ or REG_MULTI_SZ.
|
// The value is REG_SZ or REG_MULTI_SZ.
|
||||||
sValue.assign((_Elem*)aStackBuffer, dwSize / sizeof(_Elem));
|
dwSize /= sizeof(CHAR);
|
||||||
|
sValue.assign((LPCSTR)aStackBuffer, dwSize && ((LPCSTR)aStackBuffer)[dwSize - 1] == 0 ? dwSize - 1 : dwSize);
|
||||||
} else if (dwType == REG_EXPAND_SZ) {
|
} else if (dwType == REG_EXPAND_SZ) {
|
||||||
// The value is REG_EXPAND_SZ. Expand it from stack buffer.
|
// The value is REG_EXPAND_SZ. Expand it from stack buffer.
|
||||||
if (::ExpandEnvironmentStringsW((const _Elem*)aStackBuffer, sValue) == 0)
|
if (::ExpandEnvironmentStringsA((LPCSTR)aStackBuffer, sValue) == 0)
|
||||||
lResult = ::GetLastError();
|
lResult = ::GetLastError();
|
||||||
} else {
|
} else {
|
||||||
// The value is not a string type.
|
// The value is not a string type.
|
||||||
@ -901,16 +1016,17 @@ inline LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCSTR pszName, _Out_
|
|||||||
} else if (lResult == ERROR_MORE_DATA) {
|
} else if (lResult == ERROR_MORE_DATA) {
|
||||||
if (dwType == REG_SZ || dwType == REG_MULTI_SZ) {
|
if (dwType == REG_SZ || dwType == REG_MULTI_SZ) {
|
||||||
// The value is REG_SZ or REG_MULTI_SZ. Read it now.
|
// The value is REG_SZ or REG_MULTI_SZ. Read it now.
|
||||||
auto szBuffer = std::unique_ptr<_Elem[]>(new _Elem[dwSize / sizeof(_Elem)]);
|
auto szBuffer = std::unique_ptr<CHAR[]>(new CHAR[dwSize / sizeof(CHAR)]);
|
||||||
if ((lResult = ::RegQueryValueExA(hReg, pszName, NULL, NULL, (LPBYTE)szBuffer.get(), &dwSize)) == ERROR_SUCCESS)
|
if ((lResult = ::RegQueryValueExA(hReg, pszName, NULL, NULL, (LPBYTE)szBuffer.get(), &dwSize)) == ERROR_SUCCESS) {
|
||||||
sValue.assign(szBuffer.get(), dwSize / sizeof(_Elem));
|
dwSize /= sizeof(CHAR);
|
||||||
else
|
sValue.assign(szBuffer.get(), dwSize && szBuffer[dwSize - 1] == 0 ? dwSize - 1 : dwSize);
|
||||||
|
} else
|
||||||
sValue.clear();
|
sValue.clear();
|
||||||
} else if (dwType == REG_EXPAND_SZ) {
|
} else if (dwType == REG_EXPAND_SZ) {
|
||||||
// The value is REG_EXPAND_SZ. Read it and expand environment variables.
|
// The value is REG_EXPAND_SZ. Read it and expand environment variables.
|
||||||
auto szBuffer = std::unique_ptr<_Elem[]>(new _Elem[dwSize / sizeof(_Elem)]);
|
auto szBuffer = std::unique_ptr<CHAR[]>(new CHAR[dwSize / sizeof(CHAR)]);
|
||||||
if ((lResult = ::RegQueryValueExA(hReg, pszName, NULL, NULL, (LPBYTE)szBuffer.get(), &dwSize)) == ERROR_SUCCESS) {
|
if ((lResult = ::RegQueryValueExA(hReg, pszName, NULL, NULL, (LPBYTE)szBuffer.get(), &dwSize)) == ERROR_SUCCESS) {
|
||||||
if (::ExpandEnvironmentStringsW(szBuffer.get(), sValue) == 0)
|
if (::ExpandEnvironmentStringsA(szBuffer.get(), sValue) == 0)
|
||||||
lResult = ::GetLastError();
|
lResult = ::GetLastError();
|
||||||
} else
|
} else
|
||||||
sValue.clear();
|
sValue.clear();
|
||||||
@ -927,8 +1043,6 @@ inline LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCSTR pszName, _Out_
|
|||||||
template<class _Elem, class _Traits, class _Ax>
|
template<class _Elem, class _Traits, class _Ax>
|
||||||
inline LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCWSTR pszName, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue)
|
inline LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCWSTR pszName, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue)
|
||||||
{
|
{
|
||||||
assert(0); // TODO: Test this code.
|
|
||||||
|
|
||||||
LSTATUS lResult;
|
LSTATUS lResult;
|
||||||
BYTE aStackBuffer[WINSTD_STACK_BUFFER_BYTES];
|
BYTE aStackBuffer[WINSTD_STACK_BUFFER_BYTES];
|
||||||
DWORD dwSize = sizeof(aStackBuffer), dwType;
|
DWORD dwSize = sizeof(aStackBuffer), dwType;
|
||||||
@ -938,10 +1052,11 @@ inline LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCWSTR pszName, _Out_
|
|||||||
if (lResult == ERROR_SUCCESS) {
|
if (lResult == ERROR_SUCCESS) {
|
||||||
if (dwType == REG_SZ || dwType == REG_MULTI_SZ) {
|
if (dwType == REG_SZ || dwType == REG_MULTI_SZ) {
|
||||||
// The value is REG_SZ or REG_MULTI_SZ.
|
// The value is REG_SZ or REG_MULTI_SZ.
|
||||||
sValue.assign((_Elem*)aStackBuffer, dwSize / sizeof(_Elem));
|
dwSize /= sizeof(WCHAR);
|
||||||
|
sValue.assign((LPCWSTR)aStackBuffer, dwSize && ((LPCWSTR)aStackBuffer)[dwSize - 1] == 0 ? dwSize - 1 : dwSize);
|
||||||
} else if (dwType == REG_EXPAND_SZ) {
|
} else if (dwType == REG_EXPAND_SZ) {
|
||||||
// The value is REG_EXPAND_SZ. Expand it from stack buffer.
|
// The value is REG_EXPAND_SZ. Expand it from stack buffer.
|
||||||
if (::ExpandEnvironmentStringsW((const _Elem*)aStackBuffer, sValue) == 0)
|
if (::ExpandEnvironmentStringsW((LPCWSTR)aStackBuffer, sValue) == 0)
|
||||||
lResult = ::GetLastError();
|
lResult = ::GetLastError();
|
||||||
} else {
|
} else {
|
||||||
// The value is not a string type.
|
// The value is not a string type.
|
||||||
@ -950,14 +1065,15 @@ inline LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCWSTR pszName, _Out_
|
|||||||
} else if (lResult == ERROR_MORE_DATA) {
|
} else if (lResult == ERROR_MORE_DATA) {
|
||||||
if (dwType == REG_SZ || dwType == REG_MULTI_SZ) {
|
if (dwType == REG_SZ || dwType == REG_MULTI_SZ) {
|
||||||
// The value is REG_SZ or REG_MULTI_SZ. Read it now.
|
// The value is REG_SZ or REG_MULTI_SZ. Read it now.
|
||||||
auto szBuffer = std::unique_ptr<_Elem[]>(new _Elem[dwSize / sizeof(_Elem)]);
|
auto szBuffer = std::unique_ptr<WCHAR[]>(new WCHAR[dwSize / sizeof(WCHAR)]);
|
||||||
if ((lResult = ::RegQueryValueExW(hReg, pszName, NULL, NULL, (LPBYTE)szBuffer.get(), &dwSize)) == ERROR_SUCCESS)
|
if ((lResult = ::RegQueryValueExW(hReg, pszName, NULL, NULL, (LPBYTE)szBuffer.get(), &dwSize)) == ERROR_SUCCESS) {
|
||||||
sValue.assign(szBuffer.get(), dwSize / sizeof(_Elem));
|
dwSize /= sizeof(WCHAR);
|
||||||
else
|
sValue.assign(szBuffer.get(), dwSize && szBuffer[dwSize - 1] == 0 ? dwSize - 1 : dwSize);
|
||||||
|
} else
|
||||||
sValue.clear();
|
sValue.clear();
|
||||||
} else if (dwType == REG_EXPAND_SZ) {
|
} else if (dwType == REG_EXPAND_SZ) {
|
||||||
// The value is REG_EXPAND_SZ. Read it and expand environment variables.
|
// The value is REG_EXPAND_SZ. Read it and expand environment variables.
|
||||||
auto szBuffer = std::unique_ptr<_Elem[]>(new _Elem[dwSize / sizeof(_Elem)]);
|
auto szBuffer = std::unique_ptr<WCHAR[]>(new WCHAR[dwSize / sizeof(WCHAR)]);
|
||||||
if ((lResult = ::RegQueryValueExW(hReg, pszName, NULL, NULL, (LPBYTE)szBuffer.get(), &dwSize)) == ERROR_SUCCESS) {
|
if ((lResult = ::RegQueryValueExW(hReg, pszName, NULL, NULL, (LPBYTE)szBuffer.get(), &dwSize)) == ERROR_SUCCESS) {
|
||||||
if (::ExpandEnvironmentStringsW(szBuffer.get(), sValue) == 0)
|
if (::ExpandEnvironmentStringsW(szBuffer.get(), sValue) == 0)
|
||||||
lResult = ::GetLastError();
|
lResult = ::GetLastError();
|
||||||
|
17
src/Win.cpp
17
src/Win.cpp
@ -292,3 +292,20 @@ void winstd::vmemory::free_internal()
|
|||||||
{
|
{
|
||||||
VirtualFreeEx(m_proc, m_h, 0, MEM_RELEASE);
|
VirtualFreeEx(m_proc, m_h, 0, MEM_RELEASE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// winstd::reg_key
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
winstd::reg_key::~reg_key()
|
||||||
|
{
|
||||||
|
if (m_h)
|
||||||
|
RegCloseKey(m_h);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void winstd::reg_key::free_internal()
|
||||||
|
{
|
||||||
|
RegCloseKey(m_h);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user