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.

Erstelle ein Benutzerkonto oder melde Dich an, um zu kommentieren

Du musst ein Benutzerkonto haben, um einen Kommentar verfassen zu können

Benutzerkonto erstellen

Neues Benutzerkonto für unsere Community erstellen. Es ist einfach!

Neues Benutzerkonto erstellen

Anmelden

Du hast bereits ein Benutzerkonto? Melde Dich hier an.

Jetzt anmelden

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...