AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Registry: WOW6432NODE

Ein Thema von Rakshasa · begonnen am 16. Feb 2007 · letzter Beitrag vom 17. Feb 2007
Antwort Antwort
Benutzerbild von Rakshasa
Rakshasa

Registriert seit: 1. Nov 2003
182 Beiträge
 
Delphi 2007 Professional
 
#1

Registry: WOW6432NODE

  Alt 16. Feb 2007, 23:16
Problem: Unter einem 64-Bit-Windows (bspw. XP oder Vista) werden Anfragen von 32-Bit und 64-Bit Programmen unterschiedlich beantwortet: MSDN

Beispiel:
Unsere (32-Bit) Anwendung möchte auf den Schlüssel "HKEY_LM\Software\Microsoft\Windows" zugreifen (Schreibzugriff).
Tatsächlich aber wird die Anfrage von TRegistry umgeleitet, auf den Schlüssel "HKEY_LM\Software\WOW6432Node\Microsoft\Window s". D.h., der Wert wird in den Schlüssel "HKEY_LM\Software\WOW6432Node\Microsoft\Window s" geschrieben, statt in "KEY_LM\Software\Microsoft\Windows ".

Lösung:
Die TRegistry muss mit speziellen Zugriffsrechten geöffnet werden, um 32-Bit-Anwendungen expliziten Zugriff auf einen der beiden Schlüssel zu geben (also 32-Bit: "HKEY_LM\Software\WOW6432Node\..." oder 64-Bit: "HKEY_LM\Software\...").
Wichtig: Meine Lösungen gehen davon, dass das Programm über Abwärtskompatibilität verfügen soll, d.h. je nachdem, ob ein 64-Bit oder 32-Bit Windows entdeckt wurde, wird anders verfahren.
Um herauszufinden, ob Windows 64-Bit installiert wurde, kann folgende Funktion (von hier) verwendet werden:

Delphi-Quellcode:
function IsWow64: Boolean;
type
  TIsWow64Process = function( // Type of IsWow64Process API fn
    Handle: Windows.THandle; var Res: Windows.BOOL
  ): Windows.BOOL; stdcall;
var
  IsWow64Result: Windows.BOOL; // Result from IsWow64Process
  IsWow64Process: TIsWow64Process; // IsWow64Process fn reference
begin
  // Try to load required function from kernel32
  IsWow64Process := Windows.GetProcAddress(
    Windows.GetModuleHandle('kernel32'), 'IsWow64Process'
  );
  if Assigned(IsWow64Process) then
  begin
    // Function is implemented: call it
    if not IsWow64Process(
      Windows.GetCurrentProcess, IsWow64Result
    ) then
      raise SysUtils.Exception.Create('IsWow64: bad process handle');
    // Return result of function
    Result := IsWow64Result;
  end
  else
    // Function not implemented: can't be running on Wow64
    Result := False;
end;
So, um jetzt ordentlich zugreifen zu können, müssen zwei neue Typen deklariert werden (MSDN):
Delphi-Quellcode:
 const
 KEY_WOW64_64KEY = $0100;
 KEY_WOW64_32KEY = $0200;
Beispielcode für den LESE-Zugriff (32-Bit-Anwendung) auf einen Unterschlüssel von "HK_LM\Software\...":

Delphi-Quellcode:
var
  s1,s2: String;
begin

  // Auf Schlüssel "HKEY_LM\Software\WOW6432Node\Microsoft\Windows" zugreifen (umgeleitet!)
  with TRegistry.Create do
  begin
    try
      RootKey := HKEY_LOCAL_MACHINE;
      if OpenKey('\Software\Microsoft\Windows', false) then
      begin
        s1 := ReadString('');
        CloseKey;
      end;
    finally
      free;
    end;
  end;

  // Und jetzt auf den Schlüssel "HKEY_LM\Software\Microsoft\Windows" zugreifen
  with TRegistry.Create(KEY_ALL_ACCESS OR KEY_WOW64_64KEY) do
  begin
    try
      RootKey := HKEY_LOCAL_MACHINE;
      if OpenKey('\Software\Microsoft\Windows', false) then
      begin
        s2 := ReadString('');
        CloseKey;
      end;
    finally
      free;
    end;
  end;

  Showmessage(s1 + #13 + s2);
end;
Der Schreibzugriff ist jetzt ein wenig aufwendiger, ich habe mir dazu eine kleine Function gebaut, die immer - je nach Bedarf - in den einen oder anderen Schlüssel schreibt. Läuft die Anwendung auf einem 32-Bit-Windows, wird der Standard-AccessMode zurückgegeben.
Dabei wird wird an die Function der zu schreibende Schlüsselname gegeben, also bspw. "HKEY_LM\Software\WOW6432Node\Microsoft\Window s" oder "HKEY_LM\Software\Microsoft\Windows". Der Witz ist jetzt, dass durch die Function tatsächlich auch in den angegebenen Schlüssel geschrieben wird, es erfolgt keine "Umleitung".

Achtung: Beispiel verwendet Smartpos() der Unit FastStrings, da SmartPos() nicht case-sensitive ist. Das Beispiel kann natürlich auch mit Pos() benutzt werden.

Delphi-Quellcode:
function GetRegAccessMode(sOrtID: String): Cardinal;
begin
  // Bei 32-Bit-Windows kein spezieller Accessmode erforderlich
  if not Is64BitWindows then begin
    Result := KEY_ALL_ACCESS;
    exit;
  end;

  if SmartPos('Wow6432Node', sOrtID, false) > 0 then // 32-Bit-Wert schreiben?
    result := (KEY_ALL_ACCESS OR KEY_WOW64_32KEY)
  else
    result := (KEY_ALL_ACCESS OR KEY_WOW64_64KEY);

  // Alternativ: Mit pos() -> case-sensitive!
  {
  if Pos('Wow6432Node', sOrtID) > 0 then // 32-Bit-Wert schreiben?
    result := (KEY_ALL_ACCESS OR KEY_WOW64_32KEY)
  else
    result := (KEY_ALL_ACCESS OR KEY_WOW64_64KEY);
  }

end;
Eingebaut wird dass dann in den .Create-Aufruf von TRegistry:

Delphi-Quellcode:
var
  AccessMode: Cardinal;
  sKey: String;
begin
  sKey := '\Software\Microsoft\Windows';
  AccessMode := GetRegAccessMode(sKey);

  with TRegistry.Create(AccessMode) do
  begin
    try
      {.........}
    finally
      free;
    end;
 end;
Fertig!!

[edit=CalganX]Code-Style und Ressourcenschutz. Mfg, CalganX[/edit]
  Mit Zitat antworten Zitat
Benutzerbild von Rakshasa
Rakshasa

Registriert seit: 1. Nov 2003
182 Beiträge
 
Delphi 2007 Professional
 
#2

Re: Registry: WOW6432NODE

  Alt 17. Feb 2007, 10:49
Zitat von Luckie:
Dann könnte ich den Code eventuell für meinen Usermanager gebrauchen. Muss ich mal gucken.
Also unter Windows 64 braucht diesen (oder ähnlichen) Code jede Anwendung, die auf einen der Schlüssel

HKEY_LOCAL_MACHINE\Software
HKEY_USERS\*\Software\Classes
HKEY_USERS\*_Classes

zugreifen will. Link

Es gibt allerdings auch Schlüssel, die für alle Anwendungen (32 oder 64 Bit) gleich sind: MSDN

Zitat:
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\HCP
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography \Calais\Current
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography \Calais\Readers
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography \Services
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\CTF\SystemSh ared
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\CTF\TIP
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DFS
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Driver Signing
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\EnterpriseCe rtificates
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSMQ
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Non-Driver Signing
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\RAS
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Software\Mic rosoft\Shared Tools\MSInfo
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SystemCertif icates
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\TermServLice nsing
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Transaction Server
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontDpi
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontMapper
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontSubstitutes
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Ports
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Curr entVersion\Control Panel\Cursors\Schemes
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Curr entVersion\Group Policy
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Curr entVersion\Policies
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Curr entVersion\Setup
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Curr entVersion\Setup\OC Manager
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Curr entVersion\Telephony\Locations
HKEY_LOCAL_MACHINE\SOFTWARE\Policies
Eine andere Möglichkeit scheint die Verwendung von "RegDisableReflectionKey" und "RegEnableReflectionKey" zu sein (MSDN). Wie genau das funktionieren soll, weiß ich allerdings auch noch nicht.


Auf jeden Fall wird das Schreiben von Anwendungen ziemlich ätzend auf dieser Ebene, da ständig die 64-Bit Varianten der Schlüssel ebenfalls abgefragt werden müssen.
  Mit Zitat antworten Zitat
Antwort Antwort

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:32 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz