Loading backends/regedit/regedit.cpp +53 −97 Original line number Diff line number Diff line /******************************************************************************* * Copyright (c) 2023, Jan Koester jan.koester@gmx.net * Copyright (c) 2025, Jan Koester jan.koester@gmx.net * All rights reserved. * * (Lizenzblock beibehalten) * 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" #include <iostream> #include <string> #include <vector> #include <sstream> #include <algorithm> // Spezifische Windows API Includes #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <winreg.h> #include "regconf.h" // Angenommen: Dies ist der umbenannte yamlconf.h #include "exception.h" // Angenommen: Ihre eigene Exception-Klasse namespace confplus { // Basis-Schlüssel in der Registry. Wir verwenden HKEY_CURRENT_USER // und einen festen Pfad für die Anwendung. // Basis-Schlüssel in der Registry unter HKEY_CURRENT_USER const char* REGISTRY_BASE_PATH = "SOFTWARE\\ConfPlus\\Config"; // Hilfsfunktion zum Ersetzen aller Vorkommen eines Substrings (für Pfade) std::string replaceAll(std::string str, const std::string& from, const std::string& to) { size_t start_pos = 0; while((start_pos = str.find(from, start_pos)) != std::string::npos) { str.replace(start_pos, from.length(), to); start_pos += to.length(); } return str; } // Die Klasse wird von Yaml zu Registry umbenannt. class Registry : public BackendApi{ public: const char* getName(); const char* getVersion(); const char* getAuthor(); void loadConfig(const char *path,Config *conf); void saveConfig(const char *path,const Config *conf); Registry(); virtual ~Registry(); }; // --- Implementierung der Registry-Klasse --- Registry::Registry(){} Loading @@ -64,21 +64,16 @@ namespace confplus { /** * @brief Speichert die Konfiguration in der Windows Registry. * * Da das Config-System Pfade wie /Abschnitt/Schlüssel verwendet, * verwenden wir diese als Value-Namen unter dem Basis-Schlüssel. * * @param path Der Pfad wird hier ignoriert oder als Subkey des Basis-Pfades verwendet. * @param conf Das Config-Objekt. */ void Registry::saveConfig(const char *path, const Config *conf){ HKEY hKey; DWORD dwDisposition; // Erstellt oder öffnet den Basis-Schlüssel für die Konfiguration LONG lRes = RegCreateKeyExA( HKEY_CURRENT_USER, // Hauptschlüssel REGISTRY_BASE_PATH, // Subkey-Pfad HKEY_CURRENT_USER, REGISTRY_BASE_PATH, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, // KEY_WRITE KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition ); Loading @@ -86,55 +81,18 @@ namespace confplus { throw Exception("Failed to create/open registry key."); } // --- Iteration über alle Schlüssel im Config-Objekt --- // Da die Config-API nicht direkt sichtbar ist, simulieren wir die Iteration // und speichern jeden Wert als REG_SZ (String). // Die Iterationslogik müsste hier implementiert werden, um alle // ConfigData* Objekte im Config-Objekt zu erhalten. // Hier ein konzeptionelles Beispiel: std::vector<Config::ConfigData*> allKeys = conf->getAllKeys(); for (Config::ConfigData* ckey : allKeys) { std::string cname = ckey->getPath(); // Z.B. "/Server/Port" std::string cvalue = conf->getValue(ckey, 0); // Hole den 1. Wert // Entferne den führenden Schrägstrich für den Value-Namen if (cname.length() > 0 && cname[0] == '/') { cname = cname.substr(1); } // Speichere den Wert lRes = RegSetValueExA( hKey, cname.c_str(), // Z.B. "Server/Port" 0, REG_SZ, (const BYTE*)cvalue.c_str(), cvalue.length() + 1 ); if (lRes != ERROR_SUCCESS) { std::cerr << "Failed to set value for: " << cname << std::endl; } } // Da die tatsächliche Struktur des Config-Objekts unbekannt ist, // kann hier nur ein Stub eingefügt werden. // TODO: Hier die Iterationslogik über conf->getAllKeys() und RegSetValueExA // implementieren, um alle Schlüssel/Werte zu speichern. RegCloseKey(hKey); } /** * @brief Lädt die Konfiguration aus der Windows Registry. * * Liest alle Werte unter dem Basis-Schlüssel und speichert sie im Config-Objekt. * * @param path Der Pfad wird hier ignoriert oder als Subkey des Basis-Pfades verwendet. * @param conf Das Config-Objekt. */ void Registry::loadConfig(const char* path, Config* conf) { HKEY hKey; // Öffne den Basis-Schlüssel LONG lRes = RegOpenKeyExA( HKEY_CURRENT_USER, REGISTRY_BASE_PATH, Loading @@ -144,17 +102,12 @@ namespace confplus { ); if (lRes != ERROR_SUCCESS) { // Wenn der Schlüssel nicht existiert, ist das keine Exception, // sondern eine leere Konfiguration. std::cerr << "Registry key not found: " << REGISTRY_BASE_PATH << std::endl; return; } DWORD dwValues; DWORD dwMaxValueNameLen; DWORD dwMaxValueLen; DWORD dwValues, dwMaxValueNameLen, dwMaxValueLen; // Ermittelt die Anzahl der Werte und die maximale Länge lRes = RegQueryInfoKey( hKey, NULL, NULL, NULL, NULL, NULL, NULL, &dwValues, &dwMaxValueNameLen, &dwMaxValueLen, Loading @@ -166,14 +119,13 @@ namespace confplus { throw Exception("Failed to query registry key info."); } // Buffer allozieren (+1 für Nullterminierung) char* valueNameBuffer = new char[dwMaxValueNameLen + 1]; char* dataBuffer = new char[dwMaxValueLen + 1]; // Fügt 1 für das Null-Terminierungszeichen hinzu DWORD dwSizeValueName = dwMaxValueNameLen + 1; DWORD dwSizeData = dwMaxValueLen + 1; DWORD dwSizeValueName, dwSizeData; // --- Iteration über alle Values unter dem Basis-Schlüssel --- // Iteration über alle Values unter dem Basis-Schlüssel for (DWORD i = 0; i < dwValues; ++i) { DWORD dwType = 0; dwSizeValueName = dwMaxValueNameLen + 1; Loading @@ -188,26 +140,21 @@ namespace confplus { if (lRes == ERROR_SUCCESS) { std::string cname = "/"; cname += std::string(valueNameBuffer); // Z.B. "/Server/Port" cname += std::string(valueNameBuffer); // Konstruiert den Pfad: "/Server/Port" std::string cvalue = std::string(dataBuffer); // Unterstützt nur REG_SZ (String) und REG_DWORD (Zahl) if (dwType == REG_SZ) { Config::ConfigData* ckey = conf->setKey(cname); conf->setValue(ckey, 0, cvalue); std::cout << "Loading key: " << cname << " Value: " << cvalue << std::endl; } else if (dwType == REG_DWORD) { // Konvertiere DWORD zu String std::stringstream ss; ss << *((DWORD*)dataBuffer); Config::ConfigData* ckey = conf->setKey(cname); conf->setValue(ckey, 0, ss.str()); std::cout << "Loading key: " << cname << " Value: " << ss.str() << " (DWORD)" << std::endl; } } else if (lRes == ERROR_NO_MORE_ITEMS) { break; } else { // Fehler beim Lesen des Wertes std::cerr << "Error reading registry value at index " << i << std::endl; } } Loading @@ -217,3 +164,12 @@ namespace confplus { RegCloseKey(hKey); } } // --- Implementierung der Export-Funktionen --- EXPORT confplus::BackendApi* create() { return new confplus::Registry(); } EXPORT void destroy(confplus::BackendApi* p) { delete p; } No newline at end of file backends/regedit/regedit.h +57 −0 Original line number Diff line number Diff line /******************************************************************************* * 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. *******************************************************************************/ #pragma once #include "conf.h" #include "backend.h" namespace confplus { class Config; // Forward-Deklaration /** * @brief Registry-Backend zur Verwaltung der Konfiguration in der Windows Registry. */ class Registry : public BackendApi{ public: // Metadaten-Funktionen const char* getName() override; const char* getVersion() override; const char* getAuthor() override; // Backend-Schnittstellen-Funktionen void loadConfig(const char *path, Config *conf) override; void saveConfig(const char *path, const Config *conf) override; Registry(); virtual ~Registry(); }; } // Export-Funktionen für das dynamische Laden der Bibliothek EXPORT confplus::BackendApi* create(); EXPORT void destroy(confplus::BackendApi* p); No newline at end of file Loading
backends/regedit/regedit.cpp +53 −97 Original line number Diff line number Diff line /******************************************************************************* * Copyright (c) 2023, Jan Koester jan.koester@gmx.net * Copyright (c) 2025, Jan Koester jan.koester@gmx.net * All rights reserved. * * (Lizenzblock beibehalten) * 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" #include <iostream> #include <string> #include <vector> #include <sstream> #include <algorithm> // Spezifische Windows API Includes #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <winreg.h> #include "regconf.h" // Angenommen: Dies ist der umbenannte yamlconf.h #include "exception.h" // Angenommen: Ihre eigene Exception-Klasse namespace confplus { // Basis-Schlüssel in der Registry. Wir verwenden HKEY_CURRENT_USER // und einen festen Pfad für die Anwendung. // Basis-Schlüssel in der Registry unter HKEY_CURRENT_USER const char* REGISTRY_BASE_PATH = "SOFTWARE\\ConfPlus\\Config"; // Hilfsfunktion zum Ersetzen aller Vorkommen eines Substrings (für Pfade) std::string replaceAll(std::string str, const std::string& from, const std::string& to) { size_t start_pos = 0; while((start_pos = str.find(from, start_pos)) != std::string::npos) { str.replace(start_pos, from.length(), to); start_pos += to.length(); } return str; } // Die Klasse wird von Yaml zu Registry umbenannt. class Registry : public BackendApi{ public: const char* getName(); const char* getVersion(); const char* getAuthor(); void loadConfig(const char *path,Config *conf); void saveConfig(const char *path,const Config *conf); Registry(); virtual ~Registry(); }; // --- Implementierung der Registry-Klasse --- Registry::Registry(){} Loading @@ -64,21 +64,16 @@ namespace confplus { /** * @brief Speichert die Konfiguration in der Windows Registry. * * Da das Config-System Pfade wie /Abschnitt/Schlüssel verwendet, * verwenden wir diese als Value-Namen unter dem Basis-Schlüssel. * * @param path Der Pfad wird hier ignoriert oder als Subkey des Basis-Pfades verwendet. * @param conf Das Config-Objekt. */ void Registry::saveConfig(const char *path, const Config *conf){ HKEY hKey; DWORD dwDisposition; // Erstellt oder öffnet den Basis-Schlüssel für die Konfiguration LONG lRes = RegCreateKeyExA( HKEY_CURRENT_USER, // Hauptschlüssel REGISTRY_BASE_PATH, // Subkey-Pfad HKEY_CURRENT_USER, REGISTRY_BASE_PATH, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, // KEY_WRITE KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition ); Loading @@ -86,55 +81,18 @@ namespace confplus { throw Exception("Failed to create/open registry key."); } // --- Iteration über alle Schlüssel im Config-Objekt --- // Da die Config-API nicht direkt sichtbar ist, simulieren wir die Iteration // und speichern jeden Wert als REG_SZ (String). // Die Iterationslogik müsste hier implementiert werden, um alle // ConfigData* Objekte im Config-Objekt zu erhalten. // Hier ein konzeptionelles Beispiel: std::vector<Config::ConfigData*> allKeys = conf->getAllKeys(); for (Config::ConfigData* ckey : allKeys) { std::string cname = ckey->getPath(); // Z.B. "/Server/Port" std::string cvalue = conf->getValue(ckey, 0); // Hole den 1. Wert // Entferne den führenden Schrägstrich für den Value-Namen if (cname.length() > 0 && cname[0] == '/') { cname = cname.substr(1); } // Speichere den Wert lRes = RegSetValueExA( hKey, cname.c_str(), // Z.B. "Server/Port" 0, REG_SZ, (const BYTE*)cvalue.c_str(), cvalue.length() + 1 ); if (lRes != ERROR_SUCCESS) { std::cerr << "Failed to set value for: " << cname << std::endl; } } // Da die tatsächliche Struktur des Config-Objekts unbekannt ist, // kann hier nur ein Stub eingefügt werden. // TODO: Hier die Iterationslogik über conf->getAllKeys() und RegSetValueExA // implementieren, um alle Schlüssel/Werte zu speichern. RegCloseKey(hKey); } /** * @brief Lädt die Konfiguration aus der Windows Registry. * * Liest alle Werte unter dem Basis-Schlüssel und speichert sie im Config-Objekt. * * @param path Der Pfad wird hier ignoriert oder als Subkey des Basis-Pfades verwendet. * @param conf Das Config-Objekt. */ void Registry::loadConfig(const char* path, Config* conf) { HKEY hKey; // Öffne den Basis-Schlüssel LONG lRes = RegOpenKeyExA( HKEY_CURRENT_USER, REGISTRY_BASE_PATH, Loading @@ -144,17 +102,12 @@ namespace confplus { ); if (lRes != ERROR_SUCCESS) { // Wenn der Schlüssel nicht existiert, ist das keine Exception, // sondern eine leere Konfiguration. std::cerr << "Registry key not found: " << REGISTRY_BASE_PATH << std::endl; return; } DWORD dwValues; DWORD dwMaxValueNameLen; DWORD dwMaxValueLen; DWORD dwValues, dwMaxValueNameLen, dwMaxValueLen; // Ermittelt die Anzahl der Werte und die maximale Länge lRes = RegQueryInfoKey( hKey, NULL, NULL, NULL, NULL, NULL, NULL, &dwValues, &dwMaxValueNameLen, &dwMaxValueLen, Loading @@ -166,14 +119,13 @@ namespace confplus { throw Exception("Failed to query registry key info."); } // Buffer allozieren (+1 für Nullterminierung) char* valueNameBuffer = new char[dwMaxValueNameLen + 1]; char* dataBuffer = new char[dwMaxValueLen + 1]; // Fügt 1 für das Null-Terminierungszeichen hinzu DWORD dwSizeValueName = dwMaxValueNameLen + 1; DWORD dwSizeData = dwMaxValueLen + 1; DWORD dwSizeValueName, dwSizeData; // --- Iteration über alle Values unter dem Basis-Schlüssel --- // Iteration über alle Values unter dem Basis-Schlüssel for (DWORD i = 0; i < dwValues; ++i) { DWORD dwType = 0; dwSizeValueName = dwMaxValueNameLen + 1; Loading @@ -188,26 +140,21 @@ namespace confplus { if (lRes == ERROR_SUCCESS) { std::string cname = "/"; cname += std::string(valueNameBuffer); // Z.B. "/Server/Port" cname += std::string(valueNameBuffer); // Konstruiert den Pfad: "/Server/Port" std::string cvalue = std::string(dataBuffer); // Unterstützt nur REG_SZ (String) und REG_DWORD (Zahl) if (dwType == REG_SZ) { Config::ConfigData* ckey = conf->setKey(cname); conf->setValue(ckey, 0, cvalue); std::cout << "Loading key: " << cname << " Value: " << cvalue << std::endl; } else if (dwType == REG_DWORD) { // Konvertiere DWORD zu String std::stringstream ss; ss << *((DWORD*)dataBuffer); Config::ConfigData* ckey = conf->setKey(cname); conf->setValue(ckey, 0, ss.str()); std::cout << "Loading key: " << cname << " Value: " << ss.str() << " (DWORD)" << std::endl; } } else if (lRes == ERROR_NO_MORE_ITEMS) { break; } else { // Fehler beim Lesen des Wertes std::cerr << "Error reading registry value at index " << i << std::endl; } } Loading @@ -217,3 +164,12 @@ namespace confplus { RegCloseKey(hKey); } } // --- Implementierung der Export-Funktionen --- EXPORT confplus::BackendApi* create() { return new confplus::Registry(); } EXPORT void destroy(confplus::BackendApi* p) { delete p; } No newline at end of file
backends/regedit/regedit.h +57 −0 Original line number Diff line number Diff line /******************************************************************************* * 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. *******************************************************************************/ #pragma once #include "conf.h" #include "backend.h" namespace confplus { class Config; // Forward-Deklaration /** * @brief Registry-Backend zur Verwaltung der Konfiguration in der Windows Registry. */ class Registry : public BackendApi{ public: // Metadaten-Funktionen const char* getName() override; const char* getVersion() override; const char* getAuthor() override; // Backend-Schnittstellen-Funktionen void loadConfig(const char *path, Config *conf) override; void saveConfig(const char *path, const Config *conf) override; Registry(); virtual ~Registry(); }; } // Export-Funktionen für das dynamische Laden der Bibliothek EXPORT confplus::BackendApi* create(); EXPORT void destroy(confplus::BackendApi* p); No newline at end of file