The Delphi Bug List

Entry No.
588
VCL - General - Registry - TRegistry
TRegistry.OpenKeyReadOnly set's the access property to KEY_READ
1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 4.03 5.0 5.01 6.0 6.01 6.02 Kylix 1.0
N/AAbsentAbsentAbsentAbsentAbsentAbsentAbsentAbsentExistsExistsGotchaGotchaGotchaN/A
Description
Reported by Jeff Sinclair
See also entry #581.
In Delphi 5, Borland have introduced a new property to the TRegistry Object - "Access".

From the help :
-----------------------------------
property Access: LongWord;

Description
Use Access to specify the level of security access to use when opening keys. The OpenKey method uses the value of Access when opening a registry key. Access is initialized by the TRegistry constructor, but can be altered before calling OpenKey.
--------------------------------------

This is a good feature, but the problem here is that when you use OpenKeyReadOnly it sets the Access property to KEY_READ and leaves it set as KEY_READ. This mean that you can no longer write to the registry without resetting the Access property.

Is this what was intended by Borland ? I can see no reason for doing this. Note that the Access property is not used by OpenKeyReadOnly, merely altered to KEY_READ.

This breaks a large portion of our code since we often read keys "read only" and then modify them later. Does Borland expect us the reset the access parameter every time or were we wrong in reading the keys read only?

As far as I can see this is a Bug.

Solution / workaround
The Offending line indicated below should be removed.
function TRegistry.OpenKeyReadOnly(const Key: String): Boolean;
var
  TempKey: HKey;
  S: string;
  Relative: Boolean;
begin
  S := Key;
  Relative := IsRelative(S);
   if not Relative then Delete(S, 1, 1);
  TempKey := 0;
  Result := RegOpenKeyEx(GetBaseKey(Relative), PChar(S), 0,
      KEY_READ, TempKey) = ERROR_SUCCESS;
  if Result then
  begin
--> FAccess := KEY_READ;
    if (CurrentKey <> 0) and Relative then S := CurrentPath + '\' + S;
    ChangeKey(TempKey, S);
  end;
end;
User-contributed comments
Hallvard Vassbotn
30 Aug 2001  09:59 AM GMT
Bug #588 is still present in Delphi 6.0, but it has been
documented to work this way. From the help:
"Note: after a successful call to OpenKeyReadOnly the Access property of the registry component is automatically changed to KEY_READ, regardless of what that property was set to prior to the method call."
This is not entirely true however. If the RegOpenKeyEx call does
not succeed with KEY_READ, it continues to try with
STANDARD_RIGHTS_READ or KEY_QUERY_VALUE or KEY_ENUMERATE_SUB_KEYS,
then it tries KEY_QUERY_VALUE before giving up.
This can be seen as a feature. Examining the Access property
after calling OpenKeyReadOnly will tell you what kind of
access you have to that key... Maybe not very useful. The
cleanest workaround is probably to write a simple wrapper
routine that saves the old value of the Access property
before the call and restores it afterwards.
Latest update of this entry: 2002-04-09

Post a comment on this bug


Index page
Delphi Bug List home page
The Delphi Bug Lists are presently maintained by Jordan Russell, who has taken over this task from Reinier Sterkenburg since August 2000.
All feedback is appreciated. See also the feedback section of the Delphi Bug List home page.