Registryeintrag mit zwei Werten lesen
-
Hi
Ich bin dabei Registry Einträge auszulesen. Funktioniert bei REG_SZ und REG_MULTI_SZ werten.
Hab dabei aber das Problem das ich ein DNS-Eintrag lese in dem 2 Ip-Adressen gespeichert sind. Und ich bekomme dann immer beide IPs aneinander gehängt zurück, und jetzt weiß ich nicht wie ich die zwei am besten beim einlesen trennen kann.Registryeintrag mit den IPs 123.123.123.123 und 2.2.2.2:
"DNS"=hex(7):\ 31,32,33,2e,31,32,33,2e,31,32,33,2e,31,32,33,00,32,2e,32,2e,32,2e,32,00,00Die Zwei Ip Adressen sind durch 00(\0) getrennt.
Funktionsaufruf:
char * DNS_Reg = RegistryLesen(HKEY_LOCAL_MACHINE, REG_MULTI_SZ, L"Comm\\DM90001\\Parms\\TcpIp", L"DNS");Funktion:
char * RegistryLesen(HKEY MainKey, DWORD Reg_Type, LPCWSTR Subkey, LPCWSTR Value) { HKEY m_hkey = MainKey; LPCWSTR lpstrKey = Subkey; LPCWSTR lpstrKeyValue = Value; DWORD dwType = Reg_Type; DWORD dwSize = MAX_PATH; char value[MAX_PATH]; RegOpenKeyEx(m_hkey,lpstrKey,0,KEY_READ, &m_hkey) ; int i=0; int iLastError=0; char DaValue[MAX_PATH]=""; char * DaValuePart; do { LPTSTR cValueName; DWORD dwValueName = 256; DWORD ValueType = 0; BYTE cValueData[256] = "\0"; DWORD dwValueData = 256; iLastError = RegEnumValue(m_hkey,i,cValueName,&dwValueName,0,&ValueType,cValueData,&dwValueData); if(ValueType == REG_SZ) printf("CVALUE: %s\r\n",cValueName); ++i; }while(iLastError!=ERROR_NO_MORE_ITEMS); if (RegQueryValueEx(m_hkey, lpstrKeyValue, 0, &dwType,(LPBYTE)value,&dwSize)== ERROR_SUCCESS) { for(int s=0; s<(int)dwSize;s=s+1) { DaValuePart = ("%s",value+s); // AN DIESER STELLE MÜSSTE MAN IRGENDWIE TEILEN? // if (DaValuePart == "\0") // printf("Hier Teilen") // geht nicht! } } RegCloseKey(m_hkey); return DaValue; }Wenn ich mir jetzt mein Rückgabewert ausgeben lasse, sieht der so aus:
123.123.123.1232.2.2.2
Hat mir jemand ein paar Tricks und Kniffe auf Lager die ich versuchen könnte?Ein zweites Problemchen hab ich, wenn ich versuche ein REG_DWORD auszulesen, sowie:
"EnableDHCP"=dword:00000000Dann bekomme ich ein unlesbares Zeichen angezeigt!?
Gruß
ThomasPS: Wer wissen möchte wie diese IPs in die Registry geschrieben werden:
http://www.c-plusplus.net/forum/viewtopic-var-t-is-189540-and-highlight-is-.html
-
Das System kann das \0 nicht darstellen, deswegen wird es bei der Ausgabe auch übersprungen - aber das bedeutet nicht, daß du es nicht gesondert betrachten könntest:
for(int s=0; s<(int)dwSize;s=s+1)
{
if(value[s]=='\0')
printf("-Ende\n")
else
printf("%c",value[s];
}[cpp](PS: Außerdem kannst du mit strlen() feststellen, wie lang der erste Eintrag ist - an Position len+1 beginnt dann der zweite Eintrag)
-
So ich habs gepackt

Danke vielmalschar * RegistryLesen(HKEY MainKey, DWORD Reg_Type, LPCWSTR Subkey, LPCWSTR Value) { HKEY m_hkey = MainKey; LPCWSTR lpstrKey = Subkey; LPCWSTR lpstrKeyValue = Value; DWORD dwType = Reg_Type; DWORD dwSize = MAX_PATH; char value[MAX_PATH]; RegOpenKeyEx(m_hkey,lpstrKey,0,KEY_READ, &m_hkey) ; int i=0; int iLastError=0; char DaValue[MAX_PATH]=""; char DaValue2[MAX_PATH]=""; char * DaValuePart; int NullCounter=0; int EntryCounter=0; do { LPTSTR cValueName; DWORD dwValueName = 256; DWORD ValueType = 0; BYTE cValueData[256] = "\0"; DWORD dwValueData = 256; iLastError = RegEnumValue(m_hkey,i,cValueName,&dwValueName,0,&ValueType,cValueData,&dwValueData); if(ValueType == REG_SZ) printf("CVALUE: %s\r\n",cValueName); ++i; }while(iLastError!=ERROR_NO_MORE_ITEMS); if (RegQueryValueEx(m_hkey, lpstrKeyValue, 0, &dwType,(LPBYTE)value,&dwSize)== ERROR_SUCCESS) { for(int s=0; s<(int)dwSize; s=s+2) { if (value[s]=='\0') { NullCounter++; DaValuePart = ""; } else { DaValuePart = ("%s",value+s); NullCounter=0; } if (EntryCounter==0) // In Wert1 schreiben { strcat(DaValue, DaValuePart); } else if (EntryCounter==1) // In Wert2 schreiben { strcat(DaValue2, DaValuePart); } if (NullCounter==1) { printf("HIER TEILEN!"); NullCounter=0; EntryCounter++; } } } RegCloseKey(m_hkey); if (strlen(DaValue2)<7) // DaValue2 ist zu kurz um eine IP zu beinhalten return DaValue; else if (strlen(DaValue2)>=7) { strcat(DaValue, "-"); strcat(DaValue, DaValue2); return DaValue; } }
-
Da fehlen aber noch einige Grundlagen, bevor der Programmtext halbwegs lesbar ist.
(btw, solche Ausdrücke wie "DaValuePart = ("%s",value+s);" sind unsinnig - das ist identisch zu "DaVAluePart = value+s;")
-
CStoll schrieb:
Da fehlen aber noch einige Grundlagen, bevor der Programmtext halbwegs lesbar ist.
Ja ich weiß, aber ich hab momentan keine Zeit um die vor Jahren "eigentlich" schonmal erlernten Grundlagen aufzufrischen! Geht bei mir gerade nur durch learning-by-doing...
Und solange ich in der Lage bin meinen Code zu verstehen, passt das erst mal...CStoll schrieb:
(btw, solche Ausdrücke wie "DaValuePart = ("%s",value+s);" sind unsinnig - das ist identisch zu "DaVAluePart = value+s;")
Guat da haste natürlich auch wieder mal recht.
-
Moin
es hat sich noch ein kleines Problem aufgetan, und mit meinen mangelnden Grundlagen hab ichs noch nicht hinbekommen.
Und zwar bekomme ich eine Warnung:
warning C4172: returning address of local variable or temporaryJetzt weiß ich nicht wie ich die Funktion umschreiben muss, damit er mir einfach ein char zurück gibt. Kann man mir noch helfen?

Wenn ich anfange die Funktion als "char Registrylesen(...)" zu schreiben, dann zieht das einen riesigen Rattenschwanz nachsich. Gibt es vielleicht eine einfachere Lösung als die ganze Funktion umzuschreiben?
Gruß
-
Wie gesagt, da fehlen Grundlagen - char ist nur ein einzelnes Zeichen (also zu klein für den kompletten Registry-Eintrag) und dein
char DaValue[MAX_PATH];ist eine lokale Variable, die am Funktionsende wieder zerstört wird (das ist es, was die Warnung dir sagen will - du gibst einen Zeiger auf etwas zurück, was nicht (mehr) existiert).Eine einfache Lösung für das Problem wäre es, den zurückzugebenden Speicher per new[] anzufordern (aber dann muß das Hauptprogramm ihn aufräumen) oder als Parameter an die Funktion zu übergeben. Noch eleganter ist es natürlich, mit CString oder std::string zu arbeiten.
-
jaja die grundlagen...
Also mit CString oder std::string hatte ich bis jetzt noch nix mit zu tun.
Aber die Möglichkeit einen Parameter mit der Funktion zu übergeben hört sich interessant an.Ich nehm mal an das meine Funktion dann keinen Rückgabewert mehr gibt. Ich aber beim Funktionsaufruf noch eine Variable mitgebe, die ich dann in der Funktion fülle.
Etwa in diese Richtung:void RegistryLesen(char * Rückgabewert, HKEY MainKey, DWORD Reg_Type, LPCWSTR Subkey, LPCWSTR Value)Liegt ich da soweit richtig? Werds gleich mal testen...
-
mrkorn schrieb:
jaja die grundlagen...
Also mit CString oder std::string hatte ich bis jetzt noch nix mit zu tun.
Aber die Möglichkeit einen Parameter mit der Funktion zu übergeben hört sich interessant an.Die Lösung dazu ist eigentlich ganz einfach - du änderst den Rückgabetyp der Funktion auf CString und lässt den Rest so, wie er ist (im nächsten Schritt wäre es vielleicht hilfreich, die ganzen <cstring>-Funktionen durch Operator-Aufrufe zu ersetzen).
Ich nehm mal an das meine Funktion dann keinen Rückgabewert mehr gibt. Ich aber beim Funktionsaufruf noch eine Variable mitgebe, die ich dann in der Funktion fülle.
Etwa in diese Richtung:void RegistryLesen(char * Rückgabewert, HKEY MainKey, DWORD Reg_Type, LPCWSTR Subkey, LPCWSTR Value)Liegt ich da soweit richtig? Werds gleich mal testen...
Ja, das sieht gut aus (eventuell sollte das Hauptprogramm auch noch dazusagen, wieviel Platz hinter "Rückgabewert" tatsächlich zur Verfügung steht). Allerdings mußt du nicht unbedingt void zurückgeben, sondern kannst die Rückgabe auch für Fehler- und Statuswerte oder z.B. die Länge des verfügbaren Strings nutzen.
-
Also ich hab da mal ein kleines Beispiel für CSrings aus dem Internet versucht:
CString gray("Gray");
CString cat("Cat");
CString graycat = gray + cat;Bringt mir einige Fehler:
error C2065: 'CString' : undeclared identifier
error C2146: syntax error : missing ';' before identifier 'gray'
error C2065: 'gray' : undeclared identifier
error C2146: syntax error : missing ';' before identifier 'cat'
error C2065: 'cat' : undeclared identifier
error C2146: syntax error : missing ';' before identifier 'graycat'
error C2065: 'graycat' : undeclared identifierMuss ich dafür noch eine bestimmte Headerdatei includen? (hab auf einigen Seiten geschaut, und keiner gibt ne Headerdatei an)
--------------------------------------------------
Wenn ich die Funktion so wie sie beim letzten post war aufrufe, dann muss ich als ersten Parameter auch wieder eine andere Variable übergeben? Habs so mal versucht:
char * DNSback; RegistryLesen(DNSback, HKEY_LOCAL_MACHINE, REG_MULTI_SZ, L"Comm\\DM90001\\Parms\\TcpIp", L"DNS"); printf("UEBERGEBEN DNS: %s\r\n",DNSback);Kompiliert ohne Fehler, aber in meiner Ausgabe mit printf erscheint keinerlei Inhalt!?
-
mrkorn schrieb:
Also ich hab da mal ein kleines Beispiel für CSrings aus dem Internet versucht:
CString gray("Gray");
CString cat("Cat");
CString graycat = gray + cat;Bringt mir einige Fehler:
error C2065: 'CString' : undeclared identifier
error C2146: syntax error : missing ';' before identifier 'gray'
error C2065: 'gray' : undeclared identifier
error C2146: syntax error : missing ';' before identifier 'cat'
error C2065: 'cat' : undeclared identifier
error C2146: syntax error : missing ';' before identifier 'graycat'
error C2065: 'graycat' : undeclared identifierMuss ich dafür noch eine bestimmte Headerdatei includen? (hab auf einigen Seiten geschaut, und keiner gibt ne Headerdatei an)
Ja, da brauchst du den Header <afx.h> (siehe MSDN) - für std::string dann natürlich <string>.
Wenn ich die Funktion so wie sie beim letzten post war aufrufe, dann muss ich als ersten Parameter auch wieder eine andere Variable übergeben? Habs so mal versucht:
char * DNSback; RegistryLesen(DNSback, HKEY_LOCAL_MACHINE, REG_MULTI_SZ, L"Comm\\DM90001\\Parms\\TcpIp", L"DNS"); printf("UEBERGEBEN DNS: %s\r\n",DNSback);Kompiliert ohne Fehler, aber in meiner Ausgabe mit printf erscheint keinerlei Inhalt!?
Daß du überhaupt bis zum printf() kommst, ist ja erstaunlich - das Hauptprogramm muß natürlich auch genug Speicher bereitstellen, wo die Daten reingepackt werden können (entweder als char-Array oder über malloc()/new[]), sonst schreibst du irgendwo in den Speicher.
-
Nachdem ich <afx.h> und <string> eingebaut habe, bekomme ich diese Fehler:
c:\programme\windows ce tools\wce500\standardsdk_500\mfc\include\wcealt.h(245) : error C2084: function 'void *__cdecl operator new(unsigned int,void *)' already has a body
c:\programme\windows ce tools\wce500\standardsdk_500\mfc\include\wcealt.h(251) : error C2084: function 'void __cdecl operator delete(void *,void *)' already has a body
-
Das ist seltsam - was für Header verwendest du denn sonst noch?
-
Das sind alle:
#include <windows.h>
#include <stdio.h>
#include <winioctl.h>
#include <stdlib.h>
#include "httpext.h"
#include "creg.hxx"
#include <string>
#include <afx.h>