-
Notifications
You must be signed in to change notification settings - Fork 97
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #40 from GiovanniDicanio/support-empty-strings-in-…
…double-null-terminated-strings Added support for empty strings inside double-null-terminated strings
- Loading branch information
Showing
2 changed files
with
227 additions
and
144 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,114 +1,114 @@ | ||
# WinReg v4.0.0 | ||
## High-level C++ Wrapper Around the Low-level Windows Registry C-interface API | ||
|
||
by Giovanni Dicanio | ||
|
||
The Windows Registry C-interface API is _very low-level_ and _hard_ to use. | ||
|
||
I developed some **C++ wrappers** around this low-level Win32 API, to raise the semantic level, using C++ classes like `std::wstring`, `std::vector`, etc. instead of raw C-style buffers and low-level mechanisms. | ||
|
||
For example, the `REG_MULTI_SZ` registry type associated to double-NUL-terminated C-style strings is handled using a much easier higher-level `vector<wstring>`. My C++ code does the _translation_ between high-level C++ STL-based stuff and the low-level Win32 C-interface API. | ||
|
||
Moreover, Win32 error codes are translated to C++ exceptions. | ||
|
||
The Win32 registry value types are mapped to C++ higher-level types according the following table: | ||
|
||
| Win32 Registry Type | C++ Type | | ||
| -------------------- |:----------------------------:| | ||
| `REG_DWORD` | `DWORD` | | ||
| `REG_QWORD` | `ULONGLONG` | | ||
| `REG_SZ` | `std::wstring` | | ||
| `REG_EXPAND_SZ` | `std::wstring` | | ||
| `REG_MULTI_SZ` | `std::vector<std::wstring>` | | ||
| `REG_BINARY` | `std::vector<BYTE>` | | ||
|
||
|
||
This code is currently developed using **Visual Studio 2019**. I have no longer tested the code with previous compilers. The code compiles cleanly at `/W4` in both 32-bit and 64-bit builds. | ||
|
||
This is a **header-only** library, implemented in the **[`WinReg.hpp`](WinReg/WinReg.hpp)** header file. | ||
|
||
`WinRegTest.cpp` contains some demo/test code for the library: check it out for some sample usage. | ||
|
||
The library exposes three main classes: | ||
|
||
* `RegKey`: a tiny efficient wrapper around raw Win32 `HKEY` handles | ||
* `RegException`: an exception class to signal error conditions | ||
* `RegResult`: a tiny wrapper around Windows Registry API `LONG` error codes, returned by some `Try` methods (like `RegKey::TryOpen`) | ||
|
||
There are many member functions inside the `RegKey` class, that wrap many parts of the native C-interface Windows Registry API, in a convenient C++ way. | ||
|
||
For example, you can simply open a registry key and get registry values with C++ code like this: | ||
|
||
```c++ | ||
RegKey key{ HKEY_CURRENT_USER, L"SOFTWARE\\SomeKey" }; | ||
|
||
DWORD dw = key.GetDwordValue (L"SomeDwordValue"); | ||
wstring s = key.GetStringValue(L"SomeStringValue"); | ||
``` | ||
You can also open a registry key using a two-step construction process: | ||
```c++ | ||
RegKey key{}; | ||
key.Open(HKEY_CURRENT_USER, L"SOFTWARE\\SomeKey"); | ||
``` | ||
|
||
The above code will throw an exception on error. If you prefer to check return codes, you can do that as well: | ||
|
||
```c++ | ||
RegKey key; | ||
RegResult result = key.TryOpen(HKEY_CURRENT_USER, L"SOFTWARE\\SomeKey"); | ||
if (! result) | ||
{ | ||
// | ||
# WinReg v4.1.0 | ||
## High-level C++ Wrapper Around the Low-level Windows Registry C-interface API | ||
|
||
by Giovanni Dicanio | ||
|
||
The Windows Registry C-interface API is _very low-level_ and _hard_ to use. | ||
|
||
I developed some **C++ wrappers** around this low-level Win32 API, to raise the semantic level, using C++ classes like `std::wstring`, `std::vector`, etc. instead of raw C-style buffers and low-level mechanisms. | ||
|
||
For example, the `REG_MULTI_SZ` registry type associated to double-NUL-terminated C-style strings is handled using a much easier higher-level `vector<wstring>`. My C++ code does the _translation_ between high-level C++ STL-based stuff and the low-level Win32 C-interface API. | ||
|
||
Moreover, Win32 error codes are translated to C++ exceptions. | ||
|
||
The Win32 registry value types are mapped to C++ higher-level types according the following table: | ||
|
||
| Win32 Registry Type | C++ Type | | ||
| -------------------- |:----------------------------:| | ||
| `REG_DWORD` | `DWORD` | | ||
| `REG_QWORD` | `ULONGLONG` | | ||
| `REG_SZ` | `std::wstring` | | ||
| `REG_EXPAND_SZ` | `std::wstring` | | ||
| `REG_MULTI_SZ` | `std::vector<std::wstring>` | | ||
| `REG_BINARY` | `std::vector<BYTE>` | | ||
|
||
|
||
This code is currently developed using **Visual Studio 2019**. I have no longer tested the code with previous compilers. The code compiles cleanly at `/W4` in both 32-bit and 64-bit builds. | ||
|
||
This is a **header-only** library, implemented in the **[`WinReg.hpp`](WinReg/WinReg.hpp)** header file. | ||
|
||
`WinRegTest.cpp` contains some demo/test code for the library: check it out for some sample usage. | ||
|
||
The library exposes three main classes: | ||
|
||
* `RegKey`: a tiny efficient wrapper around raw Win32 `HKEY` handles | ||
* `RegException`: an exception class to signal error conditions | ||
* `RegResult`: a tiny wrapper around Windows Registry API `LONG` error codes, returned by some `Try` methods (like `RegKey::TryOpen`) | ||
|
||
There are many member functions inside the `RegKey` class, that wrap many parts of the native C-interface Windows Registry API, in a convenient C++ way. | ||
|
||
For example, you can simply open a registry key and get registry values with C++ code like this: | ||
|
||
```c++ | ||
RegKey key{ HKEY_CURRENT_USER, L"SOFTWARE\\SomeKey" }; | ||
|
||
DWORD dw = key.GetDwordValue (L"SomeDwordValue"); | ||
wstring s = key.GetStringValue(L"SomeStringValue"); | ||
``` | ||
You can also open a registry key using a two-step construction process: | ||
```c++ | ||
RegKey key{}; | ||
key.Open(HKEY_CURRENT_USER, L"SOFTWARE\\SomeKey"); | ||
``` | ||
|
||
The above code will throw an exception on error. If you prefer to check return codes, you can do that as well: | ||
|
||
```c++ | ||
RegKey key; | ||
RegResult result = key.TryOpen(HKEY_CURRENT_USER, L"SOFTWARE\\SomeKey"); | ||
if (! result) | ||
{ | ||
// | ||
// Open failed. | ||
// | ||
// You can invoke the RegResult::Code and RegResult::ErrorMessage methods | ||
// for further details. | ||
// | ||
... | ||
} | ||
``` | ||
|
||
You can also enumerate all the values under a given key with simple C++ code like this: | ||
|
||
```c++ | ||
auto values = key.EnumValues(); | ||
|
||
for (const auto & v : values) | ||
{ | ||
// | ||
// Process current value: | ||
// | ||
// - v.first (wstring) is the value name | ||
// - v.second (DWORD) is the value type | ||
// | ||
... | ||
} | ||
``` | ||
|
||
In addition, you can also use the `RegKey::TryGet...Value` methods, that return `std::optional` instead of throwing on errors: | ||
|
||
```c++ | ||
// RegKey::TryGetDwordValue() returns a std::optional<DWORD>; | ||
// the returned std::optional contains no value on error. | ||
|
||
if (auto dw = key.TryGetDwordValue(L"SomeDwordValue")) | ||
{ | ||
// All right: Process the returned value ... | ||
} | ||
else | ||
{ | ||
// The method has failed: The returned std::optional contains no value. | ||
} | ||
``` | ||
|
||
|
||
You can take a look at the test code in `WinRegTest.cpp` for some sample usage. | ||
|
||
The library stuff lives under the `winreg` namespace. | ||
|
||
See the [**`WinReg.hpp`**](WinReg/WinReg.hpp) header for more details and **documentation**. | ||
|
||
Thanks to everyone who contributed to this project with some additional features and constructive comments and suggestions. | ||
|
||
} | ||
``` | ||
|
||
You can also enumerate all the values under a given key with simple C++ code like this: | ||
|
||
```c++ | ||
auto values = key.EnumValues(); | ||
|
||
for (const auto & v : values) | ||
{ | ||
// | ||
// Process current value: | ||
// | ||
// - v.first (wstring) is the value name | ||
// - v.second (DWORD) is the value type | ||
// | ||
... | ||
} | ||
``` | ||
|
||
In addition, you can also use the `RegKey::TryGet...Value` methods, that return `std::optional` instead of throwing on errors: | ||
|
||
```c++ | ||
// RegKey::TryGetDwordValue() returns a std::optional<DWORD>; | ||
// the returned std::optional contains no value on error. | ||
|
||
if (auto dw = key.TryGetDwordValue(L"SomeDwordValue")) | ||
{ | ||
// All right: Process the returned value ... | ||
} | ||
else | ||
{ | ||
// The method has failed: The returned std::optional contains no value. | ||
} | ||
``` | ||
|
||
|
||
You can take a look at the test code in `WinRegTest.cpp` for some sample usage. | ||
|
||
The library stuff lives under the `winreg` namespace. | ||
|
||
See the [**`WinReg.hpp`**](WinReg/WinReg.hpp) header for more details and **documentation**. | ||
|
||
Thanks to everyone who contributed to this project with some additional features and constructive comments and suggestions. | ||
|
Oops, something went wrong.