@@ -983,14 +983,31 @@ function GetEnvVar(const VarName: string): string;
983983 Result := ' ' ;
984984end ;
985985
986- // Creates a read only TRegistry instance. On versions of Delphi that don't
987- // support passing access flags to TRegistry constructor, registry is opened
988- // normally for read/write access.
986+ // Checks if host OS is Windows 2000 or earlier, included any Win9x OS.
987+ // This is a helper function for RegCreate and RegOpenKeyReadOnly and avoids
988+ // avoids using TPJOSInfo to ensure that an infinite loop is not set up with
989+ // TPJOSInfo calling back into RegCreate.
990+ function IsWin2000OrEarlier : Boolean;
991+ begin
992+ // NOTE: all Win9x OSs have Win32MajorVersion < 5, so we don't need to check
993+ // platform.
994+ Result := (Win32MajorVersion < 5 ) or
995+ ((Win32MajorVersion = 5 ) and (Win32MinorVersion = 0 ));
996+ end ;
997+
998+ // Creates a read only TRegistry instance. On versions of Delphi or OSs that
999+ // don't support passing access flags to TRegistry constructor, registry is
1000+ // opened normally for read/write access.
9891001function RegCreate : TRegistry;
9901002begin
9911003 { $IFDEF REGACCESSFLAGS}
992- // ! fix for issue #14 (http://bit.ly/eWkw9X) suggested by Steffen Schaff
993- Result := TRegistry.Create(KEY_READ or KEY_WOW64_64KEY);
1004+ // ! Fix for issue #14 (http://bit.ly/eWkw9X) suggested by Steffen Schaff.
1005+ // ! Later modified to allow for fact that Windows 2000 fails if
1006+ // ! KEY_WOW64_64KEY is used.
1007+ if IsWin2000OrEarlier then
1008+ Result := TRegistry.Create
1009+ else
1010+ Result := TRegistry.Create(KEY_READ or KEY_WOW64_64KEY);
9941011 { $ELSE}
9951012 Result := TRegistry.Create;
9961013 { $ENDIF}
@@ -999,19 +1016,32 @@ function RegCreate: TRegistry;
9991016// Uses registry object to open a key as read only. On versions of Delphi that
10001017// can't open keys as read only the key is opened normally.
10011018function RegOpenKeyReadOnly (const Reg: TRegistry; const Key: string): Boolean;
1019+
1020+ // Opens registry key using TRegistry.OpenKeyReadOnly if supported, otherwise
1021+ // uses TRegistry.OpenKey.
1022+ function TryOpenKeyReadOnly : Boolean;
1023+ begin
1024+ { $IFDEF REGOPENREADONLY}
1025+ Result := Reg.OpenKeyReadOnly(Key);
1026+ { $ELSE}
1027+ Result := Reg.OpenKey(Key, False);
1028+ { $ENDIF}
1029+ end ;
1030+
10021031begin
10031032 { $IFDEF REGACCESSFLAGS}
1004- // ! Fix for problem with OpenKeyReadOnly on 64 bit Windows
1005- // ! requires Reg has (KEY_READ or KEY_WOW64_64KEY) access flags
1006- Result := Reg.OpenKey(Key, False);
1033+ // ! Fix for problem with OpenKeyReadOnly on 64 bit Windows requires Reg has
1034+ // ! (KEY_READ or KEY_WOW64_64KEY) access flags.
1035+ // ! Even though these flags aren't provided on Windows 2000 and earlier, the
1036+ // ! following code should still work
1037+ if IsWin2000OrEarlier then
1038+ Result := TryOpenKeyReadOnly
1039+ else
1040+ Result := Reg.OpenKey(Key, False);
10071041 { $ELSE}
10081042 // Can't fix Win 64 problem since this version of Delphi does not support
10091043 // customisation of registry access flags.
1010- { $IFDEF REGOPENREADONLY}
1011- Result := Reg.OpenKeyReadOnly(Key);
1012- { $ELSE}
1013- Result := Reg.OpenKey(Key, False);
1014- { $ENDIF}
1044+ Result := TryOpenKeyReadOnly;
10151045 { $ENDIF}
10161046end ;
10171047
0 commit comments