mehrere Registry Werte(deren Daten) lesen+ausgeben



  • ok, danke an swordfish für den code.
    ich glaub, jetzt hab ich ihn auch verstanden, zumindest funktioniert er.

    anstatt reinterpret_cast<char>* kann ich auch die normale explizite typumwandlung (char)* benutzen, das hab ich ausprobiert.

    wo der unterschied zu reinterpret_cast<char*> liegt, weiß ich allerdings immer noch nicht.



  • @*vector*: Ok, 1:0 für dich 😉

    ein reinterpret_cast< type >( var ) sorgt dafür, das der Speicher, auf welchen var Zeigt wie type interpretiert wird. Hätte wir zum Beispiel

    #include <iostream>
    using namespace std;
    
    int main( )
    {
    //  einen
    
        float f = 2.345f;
    
    //  dann könnten wir mit einem
    
        unsigned char *p = reinterpret_cast< unsigned char* >( &f );
    
    //  an das erste Byte von f kommen und so
    
        for( size_t i = 0; i < sizeof( float ); ++i ) {
    
            cout << "0x";
            cout.width( 2 );
            cout.fill( '0' );
            cout << hex << p[ i ] << " ";
        }
    
    //  alle Bytes nacheinander ausgeben.
    

    Der Unterschied zu einem C-Style Cast ist, daß man mit ihm keine consts "wegcasten" kann:

    int main( )
    {
        const char str[ ] = "Hello";
        char *p = reinterpret_cast< char* >( str ); // <- *)
    }
    

    😉 wird zu einem Compilerfehler ähnlich dem Wortlaut "'reinterpret_cast' : 'const char [6]' kann nicht in 'char *' konvertiert werden" führen. Mit einem C-Style Cast ist dies möglich:

    int main( )
    {
        const char str[ ] = "Hello";
        char *p = ( char* ) str;
    
        cout << "Before: \"" << str << "\"" << endl;
    
        p[ 1 ] = 'a'; // wir schreiben munter in konstanten Speicher!
    
        cout << "After: \"" << str << "\"" << endl;
    }
    

    Ausgabe:

    Before: "Hello"
    After: "Hallo"
    

    Mit C++ Casts wäre dazu explizit ein const_cast nötig:

    #include <iostream>
    
    using namespace std;
    
    int main( )
    {
        const char str[ ] = "Hello";
        char *p = const_cast< char* >( str );
    
        cout << "Before: \"" << str << "\"" << endl;
    
        p[ 1 ] = 'a';
    
        cout << "After: \"" << str << "\"" << endl;
    }
    

    Somit kann es mit C++ Casts nicht passieren, das man sich "aus versehen" in's Bein schießt.

    Greetz, Swordfish



  • ok, danke swordfish.
    nachdem ich mir deinen code durchgelesen und (glaube ich) auch verstanden habe, habe ich es nochmal selbst probiert, um zu sehen, ob ich es jetzt selbst hinbekommen würde (dabei habe ich zwar für mich nicht notwendige teile deines codes weggelassen, jedoch habe ich mich, wie du sehen wirst, sehr an deinem orientiert.). anscheinend ist das nicht der fall, denn bei folgendem code kommt mal wieder nicht die richtige ausgabe.
    bitte korrigieren, wenn ich irgendwas falsch sehe (siehe kommentare)!

    code:

    #include  <iostream>
    #include  <string>
    #include  <windows.h>
    
    using namespace std;
    
    #define cls system("cls")
    #define wait  system  ("pause>nul")
    void  color(string  pColor)
    {
      string  cmdstr  = "color "  + pColor;
      system(cmdstr.c_str());
    }
    
    typedef unsigned  long  ulong;
    typedef unsigned  char  uchar;
    
    bool  RegReadValueString(  string &value_data, const HKEY  &hkey,  const char* value)
    {
      ulong val_type;
    
      //  Typ des Wertes prüfen
      RegQueryValueEx(  hkey, //  Schlüssel -ein
                        value,  //  Wert  -ein
                        0,  //  immer NULL  -ein
                        &val_type, //  Typ des Wertes -aus
                        0,  //  Puffer für Daten des Wertes -ein
                        0 //  Größe des Puffers -aus
                     );
    
      if( val_type  !=  REG_SZ  )
        return  false;  //  falls Werte-Typ !=  String
    
      //  Daten lesen
      ulong result;
      ulong size  = 1;  //  Größe des Daten-Puffers
      uchar *data = new uchar[1]; //  Daten-Puffer  ( Platz für 1 Zeichen => \0 )
    
      if( result  = RegQueryValueEx(  hkey, value,  0,  0,  data, &size  ) )
      {
        delete  []  data;
    
        if( result  !=  ERROR_MORE_DATA )
          return  false;  //  Falls Daten = "\0"
    
        try
        {
          data  = new uchar[size];  //  Puffer  auf die richtige Größe bringen
        }
        catch(  bad_alloc )
        {
          return  false;  //  falls Vergrößern des Puffers fehlschlägt
        }
    
        if( RegQueryValueEx(  hkey, value,  0,  0,  data, &size ) )
          return  false;  //  falls weitere Fehler auftreten
      }
      value_data  = (char*) data;  //  Daten in C-String-Parameter schreiben
      delete  []  data; //  Daten-Array leeren
      return  true; //  bei Erfolg
    
    } //  RegDataToStr
    
    int main()
    {
      HKEY  hkey;
      string  status, name, domain, password;
    
      //  Schlüssel öffnen
      if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, //  Host-Key
                        "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
                          //  Unerschlüssel
                        0,  //  immer NULL
                        KEY_READ, //  Zugriffsberechtigungen zum öffnen
                        &hkey //  HKEY-Handle
                      )
        )
      {
        cls;
        color("c");
        cout  <<  "Fehler: HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\"
              <<  "CurrentVersion\\Winlogon konnte nicht geoeffnet werden.\n"
              <<  "beliebige Taste zum Beenden ...\n";
        wait;
        exit(-1);
      }
    
      //  Daten lesen
    
      //  Status lesen
      if( !RegReadValueString(  status, hkey, "AutoAdminLogon" ) )
      {
        cls;
        color("c");
        cout  <<  "Fehler: AutoAdminLogon konnte nicht gelesen werden.\n";
        cout  <<  "name";
        wait;
        exit(-1);
      }
      else
      {
        if( status  ==  "1" )
          status  = "AKTIVIERT";
        else
          status  = "DEAKTIVIERT";
      }
    
      //  Namen lesen
      if( !RegReadValueString( name, hkey, "DefaultUserName" )  )
      {
        cls;
        color("c");
        cout  <<  "Fehler: DefaultUserName konnte nicht gelesen werden.\n";
        wait;
        exit(-1);
      }
    
      //  Domain lesen
      if( !RegReadValueString(  domain, hkey, "DefaultDomain" ) )
      {
        cls;
        color("c");
        cout  <<  "Fehler: DefaultDomain konnte nicht gelesen werden.\n";
        wait;
        exit(-1);
      }
    
      //  Passwort lesen
      if( !RegReadValueString(  password, hkey, "DefaultPassword" ) )
      {
        cls;
        color("c");
        cout  <<  "Fehler: DefaultPassword konnte nicht gelesen werden.\n";
        wait;
        exit(-1);
      }
    
      //  Hauptmenü ausgeben
      hm:
    
      int choice;
    
      cls;
      cout  <<  "\t\tautomatischer Login  ist "  <<  status  <<  endl
            <<  "\t\tBenutzername:            " <<  name  <<  endl
            <<  "\t\tDomain:                  " <<  domain  <<  endl
            <<  "\t\tPasswort:                " <<  password  <<  endl;
      return  0;
    }
    

    ausgabe:

    Fehler: DefaultDomain konnte nicht gelesen werden.
    


  • Ok, hab's mir angesehen. Der Code tut genau das, was er tun soll. Haste gut gemacht *tätschel* 😉

    Julian__ schrieb:

    ausgabe:

    Fehler: DefaultDomain konnte nicht gelesen werden.
    

    Ich nehme mal an, das SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\AutoAdminLogon bei dir (wie auch bei mir) schlichtweg nicht existiert. Du könntest jeden Wert auf Existenz prüfen, bevor du versuchst ihn zu lesen und wenn ein Wert nicht existiert mit dem nächsten weitermachen. Testen kannst du das zB. mit:

    bool reg_value_exists( HKEY reg_key, const string value )
    {
        char value_name[ 256 ];
        unsigned long size = 256;
    
        long result = 0;
    
        if( ( result = RegEnumValue( reg_key, 0, value_name, &size, 0, 0, 0, 0 ) ) )
            return false;
    
        if( value.compare( value_name ) == 0 )
            return true;
    
        for( unsigned long i = 1; true; ++i ) {
    
            size = 256;
    
            if( ( result = RegEnumValue( reg_key, i, value_name, &size, 0, 0, 0, 0 ) ) )
                return false;
    
            if( value.compare( value_name ) == 0 )
                return true;
    
            ++i;
    
        } while( true );
    
        return false;
    }
    

    Achja, noch was zu deinem Code:

    // ...
    
    #define cls system("cls")             // 1)
    #define wait  system  ("pause>nul")   // 2)
    
    void color(string  pColor)            // 3)
    {
      string  cmdstr  = "color "  + pColor;
      system(cmdstr.c_str());
    }
    
    // ...
    
    exit(-1);                             // 4)
    
    // ...
    
    hm:                                   // nicht benutzt
    int choice;                           // ebenfalls
    
    1. wenn du einen Makro als einen Funktionsersatz verwendest, solltest du im á la
    #define cls() system("cls")
    
    // Aufruf:
    
    cls();
    

    Klammern verpassen, damit man nicht in Versuchung kommt, ihn für einen Variablenamen zu halten.

    1. schau dir mal ➡ DOS und Win32-Konsole :: Automatisches Schließen verhindern an.

    2. zum Löschen des Bildschirms und farbiger Ausgabe solltest du die ➡ Improved Console ansehen.

    3. bei exit( int code ) verwendet man als Parameter üblicherweise EXIT_SUCCESS bzw. EXIT_FAILURE. Ein einfaches return( 0 ) tuts in den meisten fällen genauso gut.

    Hoff' ich konnt' helfen.

    Greetz, Swordfish



  • ooh danke!

    naja, mit deiner vermutung lagst du fast richtig.
    ich überleg den ganzen verdammten tag, woran das liegen könnte und eben fällt mir auf, dass der key ja nicht "DefaultDomain", sondern "DefaultDomainName" heißt.
    schön blöd... 🤡

    ja, lacht ruhig, hab ich auch gemacht. 😃 😃 😃 😃 😃

    und danke für die links!

    aber: ich habe den C++BuilderX (borland), der war bei einem anfängerbuch dabei und gefällt mir sehr gur, ist halt nur keine RAD, aber ich schreib ja (noch) nur konsolenprogramme. und der C++BuilderX ist nicht unter den unterstützten compilern bei Improved Console aufgeführt. sollte das trotzdem klappen?



  • Julian__ schrieb:

    [...] der C++BuilderX ist nicht unter den unterstützten compilern bei Improved Console aufgeführt. sollte das trotzdem klappen?

    Entweder probierst du's einfach aus oder du fragst hier: ➡ Improved Console

    Greetz, Swordfish



  • yo hab ich schon gemacht. funktioniert auch alles, bis auf die dropdown-menüs mit den möglichen methoden, aber das lässt sich verkraften.

    ok, nochmal danke swordfish für deine hilfe hier bei meinen (meist durch eigene dummheit entstandenen) problemen.

    euer forum werd ich mir merken, ist, wirklich gut hier, hab schon viel schlechteres erlebt.

    mfg, julian



  • eigentlich wollt ich nur kurz den post editieren, aba dann hab ich gemerkt: das geht nicht!

    yo hab ich schon gemacht. funktioniert auch alles, bis auf die dropdown-menüs mit den möglichen methoden, aber das liegt ja am compiler (an der IDE).

    ok, nochmal danke swordfish für deine hilfe hier bei meinen (meist durch eigene dummheit entstandenen) problemen.

    euer forum werd ich mir merken, ist, wirklich gut hier, hab schon viel schlechteres erlebt.

    mfg, julian



  • Aber bitte, gerne!

    Dieses Forum nicht nur merken, sonder ➡ Klicken 😉

    Greetz, Swordfish



  • <= und? wie steht mir das? 😉
    ich find's irgendwie stylish.


Anmelden zum Antworten