Zum Inhalt springen

Empfohlene Beiträge

Geschrieben

Hallo,

ich möchte für ein Programm Daten aus der Windowsregistry laden. Dazu habe ich einen Singleton mit folgendem Konstruktor implementiert:


CSettings::CSettings()

{

	auto HRESULT a_hr;

	auto HKEY a_sHkey;

	auto HKEY a_sKey	= HKEY_LOCAL_MACHINE;

	a_hr =	RegOpenKeyEx(a_sKey, (LPCTSTR) this -> m_seMembers.a_lpRegKey, 0, KEY_ALL_ACCESS, &a_sHkey);

	_ASSERT(SUCCEEDED(a_hr));

	if (SUCCEEDED(a_hr))

	{

		{

			auto CString a_lpBuffer = _T("");

			auto DWORD a_dwValueType = 0;

			auto DWORD a_dwValueLen = 0;

			RegQueryValueEx(a_sHkey, BZR_REG_PDATA_PATH, NULL, &a_dwValueType, 

							(LPBYTE) a_lpBuffer.GetBuffer(a_lpBuffer.GetLength()), &a_dwValueLen);

			if (_T("") == a_lpBuffer)

			{

				GetCurrentDirectory(_MAX_PATH, (LPSTR) a_lpBuffer.GetBuffer(a_lpBuffer.GetLength()));

				a_lpBuffer += _T("\\AV100b.doc");

				a_hr =	RegSetValueEx(a_sHkey, BZR_REG_PDATA_PATH, 0, REG_SZ, (LPBYTE) (LPCTSTR) a_lpBuffer, 

										a_lpBuffer.GetLength());

				_ASSERT(SUCCEEDED(a_hr));

				a_hr = RegFlushKey(a_sHkey);

				_ASSERT(SUCCEEDED(a_hr));

			}

		}

		RegCloseKey(a_sHkey);

	}

}

Daran gibt es jetzt allerdings 2 Probleme:

1. a_lpBuffer ist nach dem Aufruf von RegQueryValueEx immer leer (egal ob ein Wert vorhanden ist oder nicht).

2. Bei GetCurrentDirectory wird zwar der richtige Wert in a_lpBuffer geschrieben, aber nach dem folgenden Verkettungsoperator besitzt a_lpBuffer einen Wert von "\AV100b.doc". Sollte += nicht eigentlich eine Art append sein ?

Geschrieben
1. a_lpBuffer ist nach dem Aufruf von RegQueryValueEx immer leer (egal ob ein Wert vorhanden ist oder nicht).
Das liegt daran, dass du als Puffergröße (a_dwValueLen) 0 übergibst.

2. Bei GetCurrentDirectory wird zwar der richtige Wert in a_lpBuffer geschrieben, aber nach dem folgenden Verkettungsoperator besitzt a_lpBuffer einen Wert von "\AV100b.doc".
Das liegt daran, dass du GetBuffer ohne ReleaseBuffer benutzt.

Du musst übrigens bei GetBuffer schon so viel Platz fordern, dass die Werte auch reinpassen. GetLength wird dir wohl, so wie der Code jetzt aussieht, 0 liefern, da passt nicht viel rein ;)

Geschrieben

m'kay, jetzt geht das erstmal:


CSettings::CSettings()

{

	auto HRESULT a_hr;

	auto HKEY a_sHkey;

	auto HKEY a_sKey	= HKEY_LOCAL_MACHINE;

	a_hr =	RegOpenKeyEx(a_sKey, (LPCTSTR) this -> m_seMembers.a_lpRegKey, 0, KEY_ALL_ACCESS, &a_sHkey);

	_ASSERT(SUCCEEDED(a_hr));

	if (SUCCEEDED(a_hr))

	{

		{

			auto HRESULT a_hr;

			auto CString a_lpBuffer = _T("");

			auto DWORD a_dwValueType = 0;

			auto DWORD a_dwValueLen = _MAX_PATH;

			RegQueryValueEx(p_sHkey, BZR_REG_WORD_SRC_PATH, NULL, &a_dwValueType, 

					(LPBYTE) a_lpBuffer.GetBuffer(_MAX_PATH), &a_dwValueLen);

			a_lpBuffer.ReleaseBuffer();

			if (_T("") == a_lpBuffer)

			{

				GetCurrentDirectory(_MAX_PATH, (LPSTR) a_lpBuffer.GetBuffer(_MAX_PATH));

				a_lpBuffer.ReleaseBuffer();

				a_lpBuffer += _T("\\AV100b.doc");

				a_hr =	RegSetValueEx(p_sHkey, BZR_REG_WORD_SRC_PATH, 0, REG_SZ, (LPBYTE) (LPCTSTR) a_lpBuffer, 

								a_lpBuffer.GetLength());

				_ASSERT(SUCCEEDED(a_hr));

				a_hr = RegFlushKey(p_sHkey);

				_ASSERT(SUCCEEDED(a_hr));

			}

			this -> m_seMembers.m_lpeWordSource = a_lpBuffer;

		}

		RegCloseKey(a_sHkey);

	}

}

Danke. :)

Geschrieben

Da ist noch ein möglicher Bug drin: Du kannst dich nicht darauf verlassen, dass ein String, den du mit RegQueryValueEx ausliest, nullterminiert ist. Du musst also bei ReleaseBuffer explizit die Länge angeben. Aber die sollte nach dem Aufruf in a_dwValueLen stehen.

Und wenn du das irgendwann mal mit UNICODE kompilieren willst, müssen da noch ein paar Umrechnungen rein.

Geschrieben
Da ist noch ein möglicher Bug drin: Du kannst dich nicht darauf verlassen, dass ein String, den du mit RegQueryValueEx ausliest, nullterminiert ist. Du musst also bei ReleaseBuffer explizit die Länge angeben. Aber die sollte nach dem Aufruf in a_dwValueLen stehen.

Und wenn du das irgendwann mal mit UNICODE kompilieren willst, müssen da noch ein paar Umrechnungen rein.

Das hatte ich vorhin schon probiert - da bekomm ich allerdings immer einen Assert

strcore.cpp

Line 512

btw:

Wieso eigentlich Umrechnung bei UNICODE ?

Dachte da wird statt RegQueryValueExA einfach RegQueryValueExW benutzt.

Geschrieben
Das hatte ich vorhin schon probiert - da bekomm ich allerdings immer einen Assert

strcore.cpp

Line 512

Da ich nicht weiß, welche Version von Visual C++ du verwendest, und ich auch nicht alle hier habe, müsstest du schon sagen, was da mit Assert geprüft wird.

Wieso eigentlich Umrechnung bei UNICODE ?

Dachte da wird statt RegQueryValueExA einfach RegQueryValueExW benutzt.

Ja, aber RegQueryValueEx rechnet in Byte, und GetBuffer/ReleaseBuffer rechnet in Zeichen. Und bei UNICODE ist das nicht mehr gleich.

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...