Home > Enterprise >  Unable to read registry entries with 32bit program on a 64bit OS unless program ran within IDE
Unable to read registry entries with 32bit program on a 64bit OS unless program ran within IDE

Time:10-14

This function is meant to return the Integer value requested from the Registry.

I cannot use the TRegistry object because it does not return the correct value if the program calling the Registry is 32bit on a 64bit OS, it will return a max value of 10000.

This function returns the correct values if the program is ran from within the IDE but fails if ran outside the IDE.

function LB_ReadRegistryInteger(strSubKey:    String;
                                strValueName: String): Integer;
// *****************************************************************************
// this function will read the registry and return the integer value for the key
// will work for 32 or 64 bit windows. 
// ***************************************************************************** 
   const const_KEY_WOW64_64KEY = $000000100;    // value for KEY_WOW64_64KEY 
   var   Key:     HKey;                         // key value
         TheInt:  Integer;                      // return int value
         IntSize: Integer;                      // integer size
         TheType: Integer;                      // Type of data that is going to be read
begin

   Result  := 0;                                // default error return value
   TheType := REG_DWORD;                        // Type of data that is going to be read
   IntSize := SizeOf(TheInt);;                  // set size of int
                                                // if can get key and read the key
   if RegOpenKeyEx(HKEY_LOCAL_MACHINE,PChar(strSubKey),0
                   ,(KEY_READ or const_KEY_WOW64_64KEY),Key) = ERROR_SUCCESS then
      if RegQueryValueEx(Key,PChar(strValueName),nil
                        ,@TheType,@TheInt,@IntSize) = ERROR_SUCCESS then
         Result := TheInt;                      //    result is value returned

   RegCloseKey(Key);                            // close the registry

end;  // of LB_ReadRegistryInteger

How it is called.

                                                // get the GDIProcessHandleQuota
TheValue := LB_ReadRegistryInteger('\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows'
                                  ,'GDIProcessHandleQuota');

CodePudding user response:

You need to remove first back slash from the key name, so call it as

TheValue := LB_ReadRegistryInteger('SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows'
                                  ,'GDIProcessHandleQuota');

CodePudding user response:

I cannot use the TRegistry object

Yes, you can use the KEY_WOW64_64KEY flag with TRegistry. Simply apply it to the TRegistry.Access property, eg:

function LB_ReadRegistryInteger(strSubKey:    String;
                                strValueName: String): Integer;
const
  const_KEY_WOW64_64KEY = $000000100;
var
  Reg: TRegistry;
begin
  Result := 0;
  Reg := TRegistry.Create;
  try
    Reg.Access := KEY_QUERY_VALUE or const_KEY_WOW64_64KEY;
    Reg.RootKey := HKEY_LOCAL_MACHINE;
    if Reg.OpenKey(strSubKey, False) then
    try
      //if Reg.ValueExists(strValueName) then
        Result := Reg.ReadInteger(strValueName);
    except
    end;
  finally
    Reg.Free;
  end;
end;

This should work just fine, as the TRegistry.OpenKey() method passes the value of the TRegistry.Access property as-is to the RegOpenKeyEx() and RegCreateKeyEx() API functions - even in Delphi 7, which didn't natively support the KEY_WOW64_... flags yet.

Prior to Delphi 2007, the TRegistry.OpenKeyReadOnly() method completely ignores the TRegistry.Access property. However, in later versions, which do natively support the KEY_WOW64_... flags, OpenKeyReadOnly() will honor the KEY_WOW64_... flags in the TRegistry.Access property, eg:

function LB_ReadRegistryInteger(strSubKey:    String;
                                strValueName: String): Integer;
var
  Reg: TRegistry;
begin
  Result := 0;
  Reg := TRegistry.Create;
  try
    Reg.Access := KEY_WOW64_64KEY;
    Reg.RootKey := HKEY_LOCAL_MACHINE;
    if Reg.OpenKeyReadOnly(strSubKey) then
    try
      //if Reg.ValueExists(strValueName) then
        Result := Reg.ReadInteger(strValueName);
    except
    end;
  finally
    Reg.Free;
  end;
end;
  • Related