Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Binääridatan printtaaminen ja muokkaus

zeropointx [15.07.2014 17:18:57]

#

Hei olen tässä koittanut lukea & kirjoitaa rekisteristä binäärinä. Olen onnistunut saamaan rekisterin auki esimerkillä:

HKEY hKey;
   LPCTSTR sk = TEXT("SOFTWARE\\Some game\\Epic\\");

   LONG openRes = RegOpenKeyEx(HKEY_CURRENT_USER, sk, 0, KEY_ALL_ACCESS , &hKey);

Onnistuin myös lukemaan rekisteristä stringin, mutta en tiedä miten sen saa näkymään binäärimuodossa: Tältä sen pitäisi näyttää
(tai no näyttäisi olevan hexamuodossa, mutta kuitenkin).
Tai paremmin miten saan luettua sen binäärinä ja muokattua sitä. Löysin netistä esim. koodin

LPCTSTR szValueName;
DWORD dwReturn[1000];
 DWORD dwBufSize = sizeof(dwReturn);
 DWORD error = RegQueryValueEx(hKey,szValueName,0,0, (LPBYTE)dwReturn, &dwBufSize);

Mutta en tiedä miten tuon voi printata/muokkailla samanlaisessa muodossa kuin tuossa ylemmässä kuvassa tai että toimiiko se edes.

EDIT: Eli ei tosiaan taida se rekisteristä lukeminen olla ongelma, vaan se että kun saan LPBYTE:n hankittua esimerkiki tällä tavalla, miten voin lukea sen samanlaisessa muodossa, kuin tämä? Eli LPBYTE:n arvot pitäisi jotenkin muuttaa hexa muotoon.

Metabolix [16.07.2014 18:18:12]

#

Onko ongelmana nyt rekisterin lukeminen, johon sinulla näyttää jo olevan koodi (tosin szValueName tarvitsee jonkin arvon ja DWORD kannattaa vaihtaa BYTEksi), vai tavutaulukon muokkaaminen, joka ei liity rekisteriin mitenkään, vai datan tallentaminen, joka tapahtuu aivan kuten lukeminen mutta funktiolla RegSetValueEx?

zeropointx [17.07.2014 09:01:13]

#

Metabolix kirjoitti:

Onko ongelmana nyt rekisterin lukeminen, johon sinulla näyttää jo olevan koodi (tosin szValueName tarvitsee jonkin arvon ja DWORD kannattaa vaihtaa BYTEksi), vai tavutaulukon muokkaaminen, joka ei liity rekisteriin mitenkään, vai datan tallentaminen, joka tapahtuu aivan kuten lukeminen mutta funktiolla RegSetValueEx?

Joo ehkä vähän sekavasti tuli kirjoitettua. Tuolla szValueName:lla oli kyllä alunperin oikea arvo, mutta kun leikkasin sen koko koodista se jäi tyhjäksi (unohdin sen laittaa tänne pahoittelen).
Jos siis muutan tuon bufferin LPBYTE:ksi, niin miten saan printattua sen arvot hexamuodossa kuten ylemmässä kuvassa? Ja tarkoitin tavutaulukon muokkaamista, joka ei tosiaan liity alkuperäiseen aiheeseen. (muutin otsikon ja postia paremmin kuvaavaksi, kun en itsekkään tajunnut aikaisemmin ongelmaa).

zeropointx [17.07.2014 16:24:41]

#

Ratkaisin nyt ongelman.

   DWORD dwSize     = 0;
   DWORD dwDataType = 0;
   LPBYTE lpValue   = NULL;
      LPCTSTR const lpValueName = _T("somename");
   ::RegQueryValueEx(hKey,
                     lpValueName,
                     0,
                     &dwDataType,
                     lpValue,  // NULL
                     &dwSize); // will contain the data size

   // Alloc the buffer
   lpValue = (LPBYTE)malloc(dwSize);

   // Call twice RegQueryValueEx to get the value
  ::RegQueryValueEx(hKey,
                            lpValueName,
                            0,
                            &dwDataType,
                            lpValue,
                            &dwSize);
   ::RegCloseKey(hKey);
   for(int j = 0; j < dwSize; j++)
   {
	   printf("%d\n",lpValue[j]);
   }

Toimii kuten ajattelin. En tajunnut, että tuo LPBYTE toimii tuolla tavalla ja unohdin myöskin muuntaa arvot hexadesimaaliksi, jolloin vaikka todennäköisesti sain aikaisemminkin oikeita arvoja ne näyttivät vääriltä. Kiitoksia Metabolixelle vastauksesta, selvensi omaa ajattelua!

Metabolix [21.07.2014 20:08:11]

#

zeropointx kirjoitti:

printf("%d\n",lpValue[j]);

Heksadesimaaleja voi tulostaa merkinnällä %x, ja yhden tavun eli kaksi heksamerkkiä voi tulostaa selvimmin merkinnällä %02x. Johonkin graafiseen komponenttiin siirtämisessä tietenkin sprintf auttaa. Muunnoksen tekstiksi voi tehdä myös itse, jolloin tietenkin yhteen tavuun tarvitaan kaksi kutsua, jotta saadaan ensimmäinen (ylempi, high) ja toinen (alempi, low) merkki:

char hex_char(int b) {
	if (b >> 4 != 0)
		throw std::logic_error("Bad value!");
	return "0123456789abcdef"[b];
}
char hex_value(char c) {
	if ('0' <= c && c <= '9')
		return c - '0';
	if ('a' <= c && c <= 'f')
		return c - 'a' + 10;
	if ('A' <= c && c <= 'F')
		return c - 'A' + 10;
	throw std::logic_error("Bad hex character!");
}
char get_low_nibble(char byte) {
	return hex_char(byte & 0x0f);
}
char get_high_nibble(char byte) {
	return hex_char((byte >> 4) & 0x0f);
}
char set_low_nibble(char byte, char low) {
	return (byte & 0xf0) | hex_value(low);
}
char set_high_nibble(char byte, char high) {
	return (byte & 0x0f) | (hex_value(high) << 4);
}
// ...
char c = 0x46;
printf("%c%c\n", get_high_nibble(c), get_low_nibble(c));
c = set_high_nibble(c, 'a');
printf("%c%c\n", get_high_nibble(c), get_low_nibble(c));

vesikuusi [22.07.2014 13:02:23]

#

Metabolix kirjoitti:

throw std::logic_error

Heittäisin std::invalid_argument.

Carry on.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta