1

I heared that Windows creates a unique key for a PC which is called "MachineID". I found two locations in my registry. Only the location "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography" should be correct. I try to read the value by this function:

    Function GetMaschineID:string;
var
Reg : TRegistry;

//HKEY_CURRENT_USER\Software\Microsoft\MSNMessenger    =   {dd239a44-fa0d-43ff-a51c-5561d3e39de3}
//HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography   =   a06b0ee0-b639-4f55-9972-146776bcd5e4
begin
Reg := TRegistry.Create(KEY_READ);
try
Reg.Rootkey:=HKEY_LOCAL_MACHINE; //Hauptschlüssel
//Reg.RootKey:=HKEY_CURRENT_USER;
if Reg.OpenKey('SOFTWARE\Microsoft\Cryptography\',false) then //Unterschlüssel öffnen
//if Reg.OpenKey('Software\Microsoft\MSNMessenger\',false) then //Unterschlüssel öffnen
    begin
    Result:=Reg.ReadString('MachineGuid');
    end;
finally
     Reg.Free;
end;
end;

This version results in an empty string; you see as comment the result from the registry. The second version for "hkey_Current_user" brings the expected string result.

What is wrong with my code or are parts of the registry read protected?

Christine Ross
  • 465
  • 5
  • 14

2 Answers2

8

Possible explanation 1

For HKLM you are subject to registry redirection. You have a 32 bit process and are trying to read a key from the 64 bit view of the registry. By default, your 32 bit process is redirected to the 32 bit view, which (implementation detail) lives under Wow6432Node.

Use the KEY_WOW64_64KEY access flag to read from the 64 bit view. As detailed here: How can I read 64-bit registry key from a 32-bit process?

Possible explanation 2

Your call to OpenKey fails for keys under HKLM because you are requesting write access and standard user does not have write access to HKLM. Use OpenKeyReadOnly instead.

Other advice

At the very least you should have debugged this a bit more. Does the call to Reg.OpenKey succeed or fail? You should have debugged enough to know that. Perhaps you did but did not say. If Reg.OpenKey failed then explanation 2 is most likely. Even then, you may subsequently suffer from the other problem.

Note also that your function does not assign to the function result variable, or raise an error, if the call to Reg.OpenKey fails. I would expect that the compiler would have warned you about that.

Community
  • 1
  • 1
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • I'm sorry I wrote "results in an empty string" this means that Openkey works and the empty string is a result of the "readstring" line. I think your explanation 1 sounds correct. I must understand, needs a moment – Christine Ross Aug 04 '15 at 15:04
  • 1
    An empty string is likely what you'd see if `OpenKey` failed because you did not assign to Result in that case, and managed types are default initialized. – David Heffernan Aug 04 '15 at 15:05
  • Anyway, your code example you gave with your answer works very well, Thank you – Christine Ross Aug 04 '15 at 15:14
  • Are you running elevated? Do you really need to? Because OpenKey should fail for HKLM. – David Heffernan Aug 04 '15 at 15:18
  • I don't understand what you mean by "elevated". Following code works [Codelink](https://docs.google.com/document/d/1G8zlQsH9jVY1DDf3cu_s4xNwfCF73vHKTO84Nq9eV5Y/edit?usp=sharing) – Christine Ross Aug 04 '15 at 19:40
  • 1
    Only if you disabled UAC, are running virtualized, or UAC is enabled and you are elevated, running as admin. – David Heffernan Aug 04 '15 at 19:44
-1
procedure TForm1.Button1Click(Sender: TObject);
var
    registry: TRegistry;
begin
    Registry := TRegistry.Create(KEY_READ OR KEY_WOW64_64KEY);
    try
        registry.RootKey := HKEY_LOCAL_MACHINE;
        if (registry.KeyExists('\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL')) and
       (registry.OpenKeyReadOnly('\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL')) then
        begin
            showmessage(registry.ReadString('SQLEXPRESS'));
            registry.CloseKey;
        end
        else showmessage('failed');
    finally
        registry.Free;
    end;
end;
Lalji Dhameliya
  • 1,729
  • 1
  • 17
  • 26