Loading backends/regedit/regedit.cpp +226 −66 Original line number Diff line number Diff line Loading @@ -39,8 +39,154 @@ #include <winreg.h> /******************************************************************************* * Copyright (c) 2025, Jan Koester jan.koester@gmx.net * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * Neither the name of the <organization> nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ #include "regedit.h" #include "exception.h" // Angenommen: Hier ist ConfException definiert #include <iostream> #include <string> #include <sstream> #include <stdexcept> #include <algorithm> // Spezifische Windows API Includes #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <winreg.h> namespace confplus { // --- Implementierung der Registry-Klasse --- /** * @brief Rekursive Funktion zum Laden von Werten und Subkeys aus der Registry. * @param conf Das Config-Objekt, das gefüllt wird. * @param hKey Das Handle des aktuell geöffneten Registry-Schlüssels. * @param currentConfigPath Der aktuelle Pfad im Config-Objekt (z.B. "/HTTP"). */ void loadKeyRecursiveA(Config* conf, HKEY hKey, const std::string& currentConfigPath) { DWORD dwValues, dwSubKeys, dwMaxValueNameLen, dwMaxValueLen, dwMaxSubKeyLen; // 1. Hole Infos über den aktuellen Schlüssel LONG lRes = RegQueryInfoKeyA( hKey, NULL, NULL, NULL, &dwSubKeys, &dwMaxSubKeyLen, NULL, &dwValues, &dwMaxValueNameLen, &dwMaxValueLen, NULL, NULL ); if (lRes != ERROR_SUCCESS) { // Fehler beim Abfragen ist nicht kritisch, einfach zurückkehren return; } // --- 2. Werte (Values) laden (z.B. PORT unter /HTTP) --- if (dwValues > 0) { // Puffer allozieren (+1 für Nullterminierung) char* valueNameBuffer = new char[dwMaxValueNameLen + 1]; char* dataBuffer = new char[dwMaxValueLen + 1]; DWORD dwSizeValueName, dwSizeData, dwType; for (DWORD i = 0; i < dwValues; ++i) { dwType = 0; dwSizeValueName = dwMaxValueNameLen + 1; dwSizeData = dwMaxValueLen + 1; lRes = RegEnumValueA( hKey, i, valueNameBuffer, &dwSizeValueName, NULL, &dwType, (LPBYTE)dataBuffer, &dwSizeData ); if (lRes == ERROR_SUCCESS) { // Konstruiere den vollen Konfigurationspfad: /AktuellerPfad/ValueName std::string cname = currentConfigPath + "/" + std::string(valueNameBuffer); std::string cvalue; if (dwType == REG_SZ) { cvalue = std::string(dataBuffer); } else if (dwType == REG_DWORD) { std::stringstream ss; // Daten sind little-endian in dataBuffer ss << *((DWORD*)dataBuffer); cvalue = ss.str(); } else { continue; // Andere Typen ignorieren } // Füge den Wert in das Config-Objekt ein Config::ConfigData* ckey = conf->setKey(cname); conf->setValue(ckey, 0, cvalue); } } delete[] valueNameBuffer; delete[] dataBuffer; } // --- 3. Subkeys (Unterschlüssel) rekursiv laden (z.B. HTTP unter /BLOGI) --- if (dwSubKeys > 0) { char* subKeyNameBuffer = new char[dwMaxSubKeyLen + 1]; HKEY hSubKey; for (DWORD i = 0; i < dwSubKeys; ++i) { DWORD dwSizeSubKeyName = dwMaxSubKeyLen + 1; lRes = RegEnumKeyExA( hKey, i, subKeyNameBuffer, &dwSizeSubKeyName, NULL, NULL, NULL, NULL ); if (lRes == ERROR_SUCCESS) { // Öffne den Subkey lRes = RegOpenKeyExA( hKey, subKeyNameBuffer, 0, KEY_READ, &hSubKey ); if (lRes == ERROR_SUCCESS) { // Erzeuge den neuen Konfigurationspfad std::string nextConfigPath = currentConfigPath + "/" + std::string(subKeyNameBuffer); // Rekursiver Aufruf loadKeyRecursiveA(conf, hSubKey, nextConfigPath); RegCloseKey(hSubKey); } } } delete[] subKeyNameBuffer; } } // ------------------------------------------------------------------------- // --- Implementierung der Registry-Klasse --------------------------------- // ------------------------------------------------------------------------- Registry::Registry(){} Loading @@ -58,30 +204,96 @@ namespace confplus { return "Jan Koester"; } // Hilfsfunktion zum Aufteilen des Pfades in Schlüssel und Wertnamen /** * @brief Splittet den Config-Pfad (/Abschnitt/Key) in den Registry Subkey-Pfad (Abschnitt\Key) * und den letzten Teil als Value-Namen. * @param configPath Der Pfad aus dem Config-Objekt (z.B. "/HTTP/PORT" oder "/DOMAIN/NAME"). * @param registryKeyPath [out] Der Pfad für RegCreateKeyEx relativ zum Hauptschlüssel (z.B. "HTTP" oder "DOMAIN"). * @param valueName [out] Der Name für RegSetValueExA (z.B. "PORT" oder "NAME"). */ void splitConfigPath(const std::string& configPath, std::string& registryKeyPath, std::string& valueName) { // Entferne den führenden '/' std::string path = configPath.length() > 0 && configPath[0] == '/' ? configPath.substr(1) : configPath; // Finde den letzten '/' size_t last_slash = path.rfind('/'); if (last_slash == std::string::npos) { // Fall 1: Pfad ist nur der Wertname (z.B. "TEMPLATE") registryKeyPath = ""; valueName = path; } else { // Fall 2: Pfad enthält Subkeys (z.B. "HTTP/PORT") // Registry Key Path ist alles vor dem letzten Slash registryKeyPath = path.substr(0, last_slash); // Value Name ist alles nach dem letzten Slash valueName = path.substr(last_slash + 1); // Ersetze '/' durch '\' für die Registry-API std::replace(registryKeyPath.begin(), registryKeyPath.end(), '/', '\\'); } } /** * @brief Speichert die Konfiguration in der Windows Registry. */ void Registry::saveConfig(const char *path, const Config *conf){ HKEY hKey; // Öffne/Erstelle den Hauptschlüssel (z.B. "SOFTWARE\Blogi") HKEY hRootKey; DWORD dwDisposition; // Der 'path' ist der Basispfad (z.B. "SOFTWARE\Blogi") LONG lRes = RegCreateKeyExA( HKEY_CURRENT_USER, path, REGISTRY_ROOT_KEY, path, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition KEY_ALL_ACCESS, NULL, &hRootKey, &dwDisposition ); if (lRes != ERROR_SUCCESS) { ConfException e; throw e[ConfException::Error]<< "Failed to create/open registry key."; throw e[ConfException::Error] << "Failed to create/open root registry key: " << path; } // TODO: Hier die Iterationslogik über conf->getAllKeys() und RegSetValueExA // implementieren, um alle Schlüssel/Werte zu speichern. // --- TODO: Hier die Iterationslogik über conf->getAllKeys() implementieren --- /* for (const auto& key : conf->getAllKeys()) { std::string configPath = key->getPath(); // z.B. "/HTTP/PORT" std::string cvalue = conf->getValue(key, 0); // Hole den String-Wert RegCloseKey(hKey); std::string subKeyPath; std::string valueName; splitConfigPath(configPath, subKeyPath, valueName); // Temporäres Handle für den Subkey (z.B. "HTTP") HKEY hSubKey; // Erstellt/Öffnet den Subkey relativ zum Root-Key lRes = RegCreateKeyExA(hRootKey, subKeyPath.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hSubKey, NULL); if (lRes == ERROR_SUCCESS) { // Konvertiere den Wert (Hier ist eine einfache String-Speicherung) // Die Unterscheidung zwischen REG_SZ und REG_DWORD müsste basierend auf dem // tatsächlichen Typ des Werts im Config-Objekt erfolgen. // Beispiel: Speichere alles als String (REG_SZ) lRes = RegSetValueExA(hSubKey, valueName.c_str(), 0, REG_SZ, (const BYTE*)cvalue.c_str(), cvalue.length() + 1); RegCloseKey(hSubKey); } else { std::cerr << "Failed to create subkey: " << subKeyPath << std::endl; } } */ // --- ENDE TODO --- RegCloseKey(hRootKey); } /** Loading @@ -90,8 +302,9 @@ namespace confplus { void Registry::loadConfig(const char* path, Config* conf) { HKEY hKey; // Öffne den Hauptschlüssel (z.B. "SOFTWARE\Blogi") LONG lRes = RegOpenKeyExA( HKEY_CURRENT_USER, REGISTRY_ROOT_KEY, // Angenommen HKEY_CURRENT_USER oder HKEY_LOCAL_MACHINE path, 0, KEY_READ, Loading @@ -103,62 +316,9 @@ namespace confplus { return; } DWORD dwValues, dwMaxValueNameLen, dwMaxValueLen; lRes = RegQueryInfoKey( hKey, NULL, NULL, NULL, NULL, NULL, NULL, &dwValues, &dwMaxValueNameLen, &dwMaxValueLen, NULL, NULL ); // Starte die rekursive Ladefunktion. Startpfad im Config-Objekt ist "" (wird zu /) loadKeyRecursiveA(conf, hKey, ""); if (lRes != ERROR_SUCCESS) { RegCloseKey(hKey); ConfException e; throw e[ConfException::Error] << "Failed to query registry key info.";; } // Buffer allozieren (+1 für Nullterminierung) char* valueNameBuffer = new char[dwMaxValueNameLen + 1]; char* dataBuffer = new char[dwMaxValueLen + 1]; DWORD dwSizeValueName, dwSizeData; // Iteration über alle Values unter dem Basis-Schlüssel for (DWORD i = 0; i < dwValues; ++i) { DWORD dwType = 0; dwSizeValueName = dwMaxValueNameLen + 1; dwSizeData = dwMaxValueLen + 1; lRes = RegEnumValueA( hKey, i, valueNameBuffer, &dwSizeValueName, NULL, &dwType, (LPBYTE)dataBuffer, &dwSizeData ); if (lRes == ERROR_SUCCESS) { std::string cname = "/"; cname += std::string(valueNameBuffer); // Konstruiert den Pfad: "/Server/Port" std::string cvalue = std::string(dataBuffer); if (dwType == REG_SZ) { Config::ConfigData* ckey = conf->setKey(cname); conf->setValue(ckey, 0, cvalue); } else if (dwType == REG_DWORD) { std::stringstream ss; ss << *((DWORD*)dataBuffer); Config::ConfigData* ckey = conf->setKey(cname); conf->setValue(ckey, 0, ss.str()); } } else if (lRes == ERROR_NO_MORE_ITEMS) { break; } else { std::cerr << "Error reading registry value at index " << i << std::endl; } } delete[] valueNameBuffer; delete[] dataBuffer; RegCloseKey(hKey); } } Loading Loading
backends/regedit/regedit.cpp +226 −66 Original line number Diff line number Diff line Loading @@ -39,8 +39,154 @@ #include <winreg.h> /******************************************************************************* * Copyright (c) 2025, Jan Koester jan.koester@gmx.net * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * Neither the name of the <organization> nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ #include "regedit.h" #include "exception.h" // Angenommen: Hier ist ConfException definiert #include <iostream> #include <string> #include <sstream> #include <stdexcept> #include <algorithm> // Spezifische Windows API Includes #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <winreg.h> namespace confplus { // --- Implementierung der Registry-Klasse --- /** * @brief Rekursive Funktion zum Laden von Werten und Subkeys aus der Registry. * @param conf Das Config-Objekt, das gefüllt wird. * @param hKey Das Handle des aktuell geöffneten Registry-Schlüssels. * @param currentConfigPath Der aktuelle Pfad im Config-Objekt (z.B. "/HTTP"). */ void loadKeyRecursiveA(Config* conf, HKEY hKey, const std::string& currentConfigPath) { DWORD dwValues, dwSubKeys, dwMaxValueNameLen, dwMaxValueLen, dwMaxSubKeyLen; // 1. Hole Infos über den aktuellen Schlüssel LONG lRes = RegQueryInfoKeyA( hKey, NULL, NULL, NULL, &dwSubKeys, &dwMaxSubKeyLen, NULL, &dwValues, &dwMaxValueNameLen, &dwMaxValueLen, NULL, NULL ); if (lRes != ERROR_SUCCESS) { // Fehler beim Abfragen ist nicht kritisch, einfach zurückkehren return; } // --- 2. Werte (Values) laden (z.B. PORT unter /HTTP) --- if (dwValues > 0) { // Puffer allozieren (+1 für Nullterminierung) char* valueNameBuffer = new char[dwMaxValueNameLen + 1]; char* dataBuffer = new char[dwMaxValueLen + 1]; DWORD dwSizeValueName, dwSizeData, dwType; for (DWORD i = 0; i < dwValues; ++i) { dwType = 0; dwSizeValueName = dwMaxValueNameLen + 1; dwSizeData = dwMaxValueLen + 1; lRes = RegEnumValueA( hKey, i, valueNameBuffer, &dwSizeValueName, NULL, &dwType, (LPBYTE)dataBuffer, &dwSizeData ); if (lRes == ERROR_SUCCESS) { // Konstruiere den vollen Konfigurationspfad: /AktuellerPfad/ValueName std::string cname = currentConfigPath + "/" + std::string(valueNameBuffer); std::string cvalue; if (dwType == REG_SZ) { cvalue = std::string(dataBuffer); } else if (dwType == REG_DWORD) { std::stringstream ss; // Daten sind little-endian in dataBuffer ss << *((DWORD*)dataBuffer); cvalue = ss.str(); } else { continue; // Andere Typen ignorieren } // Füge den Wert in das Config-Objekt ein Config::ConfigData* ckey = conf->setKey(cname); conf->setValue(ckey, 0, cvalue); } } delete[] valueNameBuffer; delete[] dataBuffer; } // --- 3. Subkeys (Unterschlüssel) rekursiv laden (z.B. HTTP unter /BLOGI) --- if (dwSubKeys > 0) { char* subKeyNameBuffer = new char[dwMaxSubKeyLen + 1]; HKEY hSubKey; for (DWORD i = 0; i < dwSubKeys; ++i) { DWORD dwSizeSubKeyName = dwMaxSubKeyLen + 1; lRes = RegEnumKeyExA( hKey, i, subKeyNameBuffer, &dwSizeSubKeyName, NULL, NULL, NULL, NULL ); if (lRes == ERROR_SUCCESS) { // Öffne den Subkey lRes = RegOpenKeyExA( hKey, subKeyNameBuffer, 0, KEY_READ, &hSubKey ); if (lRes == ERROR_SUCCESS) { // Erzeuge den neuen Konfigurationspfad std::string nextConfigPath = currentConfigPath + "/" + std::string(subKeyNameBuffer); // Rekursiver Aufruf loadKeyRecursiveA(conf, hSubKey, nextConfigPath); RegCloseKey(hSubKey); } } } delete[] subKeyNameBuffer; } } // ------------------------------------------------------------------------- // --- Implementierung der Registry-Klasse --------------------------------- // ------------------------------------------------------------------------- Registry::Registry(){} Loading @@ -58,30 +204,96 @@ namespace confplus { return "Jan Koester"; } // Hilfsfunktion zum Aufteilen des Pfades in Schlüssel und Wertnamen /** * @brief Splittet den Config-Pfad (/Abschnitt/Key) in den Registry Subkey-Pfad (Abschnitt\Key) * und den letzten Teil als Value-Namen. * @param configPath Der Pfad aus dem Config-Objekt (z.B. "/HTTP/PORT" oder "/DOMAIN/NAME"). * @param registryKeyPath [out] Der Pfad für RegCreateKeyEx relativ zum Hauptschlüssel (z.B. "HTTP" oder "DOMAIN"). * @param valueName [out] Der Name für RegSetValueExA (z.B. "PORT" oder "NAME"). */ void splitConfigPath(const std::string& configPath, std::string& registryKeyPath, std::string& valueName) { // Entferne den führenden '/' std::string path = configPath.length() > 0 && configPath[0] == '/' ? configPath.substr(1) : configPath; // Finde den letzten '/' size_t last_slash = path.rfind('/'); if (last_slash == std::string::npos) { // Fall 1: Pfad ist nur der Wertname (z.B. "TEMPLATE") registryKeyPath = ""; valueName = path; } else { // Fall 2: Pfad enthält Subkeys (z.B. "HTTP/PORT") // Registry Key Path ist alles vor dem letzten Slash registryKeyPath = path.substr(0, last_slash); // Value Name ist alles nach dem letzten Slash valueName = path.substr(last_slash + 1); // Ersetze '/' durch '\' für die Registry-API std::replace(registryKeyPath.begin(), registryKeyPath.end(), '/', '\\'); } } /** * @brief Speichert die Konfiguration in der Windows Registry. */ void Registry::saveConfig(const char *path, const Config *conf){ HKEY hKey; // Öffne/Erstelle den Hauptschlüssel (z.B. "SOFTWARE\Blogi") HKEY hRootKey; DWORD dwDisposition; // Der 'path' ist der Basispfad (z.B. "SOFTWARE\Blogi") LONG lRes = RegCreateKeyExA( HKEY_CURRENT_USER, path, REGISTRY_ROOT_KEY, path, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition KEY_ALL_ACCESS, NULL, &hRootKey, &dwDisposition ); if (lRes != ERROR_SUCCESS) { ConfException e; throw e[ConfException::Error]<< "Failed to create/open registry key."; throw e[ConfException::Error] << "Failed to create/open root registry key: " << path; } // TODO: Hier die Iterationslogik über conf->getAllKeys() und RegSetValueExA // implementieren, um alle Schlüssel/Werte zu speichern. // --- TODO: Hier die Iterationslogik über conf->getAllKeys() implementieren --- /* for (const auto& key : conf->getAllKeys()) { std::string configPath = key->getPath(); // z.B. "/HTTP/PORT" std::string cvalue = conf->getValue(key, 0); // Hole den String-Wert RegCloseKey(hKey); std::string subKeyPath; std::string valueName; splitConfigPath(configPath, subKeyPath, valueName); // Temporäres Handle für den Subkey (z.B. "HTTP") HKEY hSubKey; // Erstellt/Öffnet den Subkey relativ zum Root-Key lRes = RegCreateKeyExA(hRootKey, subKeyPath.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hSubKey, NULL); if (lRes == ERROR_SUCCESS) { // Konvertiere den Wert (Hier ist eine einfache String-Speicherung) // Die Unterscheidung zwischen REG_SZ und REG_DWORD müsste basierend auf dem // tatsächlichen Typ des Werts im Config-Objekt erfolgen. // Beispiel: Speichere alles als String (REG_SZ) lRes = RegSetValueExA(hSubKey, valueName.c_str(), 0, REG_SZ, (const BYTE*)cvalue.c_str(), cvalue.length() + 1); RegCloseKey(hSubKey); } else { std::cerr << "Failed to create subkey: " << subKeyPath << std::endl; } } */ // --- ENDE TODO --- RegCloseKey(hRootKey); } /** Loading @@ -90,8 +302,9 @@ namespace confplus { void Registry::loadConfig(const char* path, Config* conf) { HKEY hKey; // Öffne den Hauptschlüssel (z.B. "SOFTWARE\Blogi") LONG lRes = RegOpenKeyExA( HKEY_CURRENT_USER, REGISTRY_ROOT_KEY, // Angenommen HKEY_CURRENT_USER oder HKEY_LOCAL_MACHINE path, 0, KEY_READ, Loading @@ -103,62 +316,9 @@ namespace confplus { return; } DWORD dwValues, dwMaxValueNameLen, dwMaxValueLen; lRes = RegQueryInfoKey( hKey, NULL, NULL, NULL, NULL, NULL, NULL, &dwValues, &dwMaxValueNameLen, &dwMaxValueLen, NULL, NULL ); // Starte die rekursive Ladefunktion. Startpfad im Config-Objekt ist "" (wird zu /) loadKeyRecursiveA(conf, hKey, ""); if (lRes != ERROR_SUCCESS) { RegCloseKey(hKey); ConfException e; throw e[ConfException::Error] << "Failed to query registry key info.";; } // Buffer allozieren (+1 für Nullterminierung) char* valueNameBuffer = new char[dwMaxValueNameLen + 1]; char* dataBuffer = new char[dwMaxValueLen + 1]; DWORD dwSizeValueName, dwSizeData; // Iteration über alle Values unter dem Basis-Schlüssel for (DWORD i = 0; i < dwValues; ++i) { DWORD dwType = 0; dwSizeValueName = dwMaxValueNameLen + 1; dwSizeData = dwMaxValueLen + 1; lRes = RegEnumValueA( hKey, i, valueNameBuffer, &dwSizeValueName, NULL, &dwType, (LPBYTE)dataBuffer, &dwSizeData ); if (lRes == ERROR_SUCCESS) { std::string cname = "/"; cname += std::string(valueNameBuffer); // Konstruiert den Pfad: "/Server/Port" std::string cvalue = std::string(dataBuffer); if (dwType == REG_SZ) { Config::ConfigData* ckey = conf->setKey(cname); conf->setValue(ckey, 0, cvalue); } else if (dwType == REG_DWORD) { std::stringstream ss; ss << *((DWORD*)dataBuffer); Config::ConfigData* ckey = conf->setKey(cname); conf->setValue(ckey, 0, ss.str()); } } else if (lRes == ERROR_NO_MORE_ITEMS) { break; } else { std::cerr << "Error reading registry value at index " << i << std::endl; } } delete[] valueNameBuffer; delete[] dataBuffer; RegCloseKey(hKey); } } Loading