Browse Source

Implement TRegistry.RegistryConnect for Windows (excluding WinCE).

registry.pp, TRegistry:
  * use FSysData to hold information whether we need to close the RootKey
winrec.inc, TRegistry:
  + add a TWinRegData type that holds the information whether the RootKey was explicitely opened by us
  * SysRegCreate: allocate FSysData as PWinRegData
  * SysRegFree: close the RootKey if necessary and free FSysData
  + RegistryConnect: implement for Win32/Win64; update RootKey only if RegConnectRegistry connects successfully, also the RootKey is now owned by us
  * SetRootKey: update the RootKey only if it differs from previous value (avoids orphaning the key by doing a "reg.RootKey := reg.RootKey") and close the previous RootKey if it was owned by us
  

git-svn-id: trunk@25332 -
svenbarth 12 years ago
parent
commit
a298a9ecf8
2 changed files with 31 additions and 3 deletions
  1. 0 2
      packages/fcl-registry/src/registry.pp
  2. 31 1
      packages/fcl-registry/src/winreg.inc

+ 0 - 2
packages/fcl-registry/src/registry.pp

@@ -45,9 +45,7 @@ type
   TRegistry = class(TObject)
   private
     FStringSizeIncludesNull : Boolean;
-{$ifdef XMLREG}
     FSysData : Pointer;
-{$endif XMLREG}
     fAccess: LongWord;
     fCurrentKey: HKEY;
     fRootKey: HKEY;

+ 31 - 1
packages/fcl-registry/src/winreg.inc

@@ -1,3 +1,9 @@
+type
+  TWinRegData = record
+    RootKeyOwned: Boolean;
+  end;
+  PWinRegData = ^TWinRegData;
+
 {******************************************************************************
                                   TRegistry
  ******************************************************************************}
@@ -5,11 +11,16 @@
 Procedure TRegistry.SysRegCreate;
 begin
   FStringSizeIncludesNull:=True;
+  New(PWinRegData(FSysData));
+  PWinRegData(FSysData)^.RootKeyOwned := False;
 end;
 
 Procedure TRegistry.SysRegfree;
 
 begin
+  if PWinRegData(FSysData)^.RootKeyOwned and (RootKey <> 0) then
+    RegCloseKey(RootKey);
+  Dispose(PWinRegData(FSysData));
 end;
 
 Function PrepKey(Const S : String) : pChar;
@@ -219,8 +230,20 @@ begin
 end;
 
 function TRegistry.RegistryConnect(const UNCName: string): Boolean;
+{$ifndef WinCE}
+var
+  newroot: HKEY;
+{$endif}
 begin
-  Result := False;
+{$ifdef WinCE}
+  Result:=False;
+{$else}
+  Result:=RegConnectRegistryA(PChar(UNCName),RootKey,newroot)=ERROR_SUCCESS;
+  if Result then begin
+    RootKey:=newroot;
+    PWinRegData(FSysData)^.RootKeyOwned:=True;
+  end;
+{$endif}
 end;
 
 function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
@@ -384,6 +407,13 @@ end;
 
 procedure TRegistry.SetRootKey(Value: HKEY);
 begin
+  if fRootKey = Value then
+    Exit;
+  { close a root key that was opened using RegistryConnect }
+  if PWinRegData(FSysData)^.RootKeyOwned and (fRootKey <> 0) then begin
+    RegCloseKey(fRootKey);
+    PWinRegData(FSysData)^.RootKeyOwned := False;
+  end;
   fRootKey := Value;
 end;