View Issue Details

IDProjectCategoryView StatusLast Update
0035213FPCPackagespublic2019-03-24 12:00
ReporterBart BroersmaAssigned ToMichael Van Canneyt 
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Product Version3.3.1Product Buildr41352 
Target Version3.2.0Fixed in Version3.3.1 
Summary0035213: Make TRegistry fully Unicode capable
DescriptionMake API of TRegistry unicode capable, providing backwards-compatibility overloads for people that use an ANSI version
TagsNo tags attached.
Fixed in Revision41784
FPCOldBugId
FPCTarget
Attached Files
  • registry.no-utf8encode.diff (2,444 bytes)
    Index: packages/fcl-registry/src/registry.pp
    ===================================================================
    --- packages/fcl-registry/src/registry.pp	(revision 41558)
    +++ packages/fcl-registry/src/registry.pp	(working copy)
    @@ -421,7 +421,7 @@
           if StringSizeIncludesNull and
              (u[Length(u)] = WideChar(0)) then
             SetLength(u,Length(u)-1);
    -      Result:=UTF8Encode(u);
    +      Result:=u;
         end;
       end;
     end;
    Index: packages/fcl-registry/src/winreg.inc
    ===================================================================
    --- packages/fcl-registry/src/winreg.inc	(revision 41558)
    +++ packages/fcl-registry/src/winreg.inc	(working copy)
    @@ -232,7 +232,7 @@
         if RelativeKey(Key) then
           S:=CurrentPath + Key
         else
    -      S:=UTF8Encode(u);
    +      S:=u;
         ChangeKey(Handle, S);
       end;
     end;
    Index: packages/fcl-registry/src/xmlreg.pp
    ===================================================================
    --- packages/fcl-registry/src/xmlreg.pp	(revision 41558)
    +++ packages/fcl-registry/src/xmlreg.pp	(working copy)
    @@ -329,7 +329,7 @@
                          begin
                          if not IsUnicode then
                            begin
    -                       S:=UTF8Encode(DataNode.NodeValue); // Convert to ansistring
    +                       S:=DataNode.NodeValue; // Convert to ansistring
                            NS:=Length(S);
                            Result:=(DataSize>=NS);
                            if Result then
    @@ -390,7 +390,7 @@
                        SW:=UnicodeString(PUnicodeChar(@Data))
                      else
                        SW:=UnicodeString(PAnsiChar(@Data));
    -                   //S:=UTF8Encode(SW);
    +                   //S:=SW;
                      end;
           dtBinary : SW:=BufToHex(Data,DataSize);
           dtStrings : SW:=BufToHex(Data,DataSize);
    @@ -671,7 +671,7 @@
             L:=Length(DN.NodeValue)*SizeOf(UnicodeChar)
           else
             begin
    -        S := UTF8Encode(DN.NodeValue);
    +        S := DN.NodeValue;
             L:=Length(S);
             end
           end
    @@ -727,7 +727,7 @@
                   Case TDataType(StrToIntDef(TDomElement(Node)[SType],0)) of
                     dtUnknown : L:=0;
                     dtDWord   : L:=4;
    -                DtString  : L:=Length(UTF8Encode(DataNode.NodeValue));
    +                DtString  : L:=Length(String(DataNode.NodeValue));
                     dtBinary  : L:=Length(DataNode.NodeValue) div 2;
                   end
                 else
    
  • registry.unicode.part1.diff (37,734 bytes)
    Index: packages/fcl-registry/src/regdef.inc
    ===================================================================
    --- packages/fcl-registry/src/regdef.inc	(revision 41667)
    +++ packages/fcl-registry/src/regdef.inc	(working copy)
    @@ -2,7 +2,7 @@
       HKEY = THandle;
       PHKEY = ^HKEY;
       
    -{$ifdef windows}
    +{$if defined(windows) and not defined(XMLREG)}
     
     { Direct mapping to constants in Windows unit }
     
    Index: packages/fcl-registry/src/registry.pp
    ===================================================================
    --- packages/fcl-registry/src/registry.pp	(revision 41667)
    +++ packages/fcl-registry/src/registry.pp	(working copy)
    @@ -54,22 +54,28 @@
         fCurrentKey: HKEY;
         fRootKey: HKEY;
         fLazyWrite: Boolean;
    -    fCurrentPath: string;
    +    fCurrentPath: UnicodeString;
         function GetLastErrorMsg: string;
         procedure SetRootKey(Value: HKEY);
         Procedure SysRegCreate;
         Procedure SysRegFree;
    -    Function  SysGetData(const Name: String; Buffer: Pointer; BufSize: Integer; Out RegData: TRegDataType): Integer;
    -    Function  SysPutData(const Name: string; Buffer: Pointer; BufSize: Integer; RegData: TRegDataType) : Boolean;
    -    Function  SysCreateKey(const Key: String): Boolean;
    +    Function  SysGetData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; Out RegData: TRegDataType): Integer;
    +    Function  SysPutData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; RegData: TRegDataType) : Boolean;
    +    Function  SysCreateKey(Key: UnicodeString): Boolean;
       protected
         function GetBaseKey(Relative: Boolean): HKey;
    -    function GetData(const Name: string; Buffer: Pointer;
    +    function GetData(const Name: UnicodeString; Buffer: Pointer;
                       BufSize: Integer; Out RegData: TRegDataType): Integer;
    -    function GetKey(const Key: string): HKEY;
    -    procedure ChangeKey(Value: HKey; const Path: string);
    -    procedure PutData(const Name: string; Buffer: Pointer;
    +    function GetData(const Name: String; Buffer: Pointer;
    +                  BufSize: Integer; Out RegData: TRegDataType): Integer;
    +    function GetKey(Key: UnicodeString): HKEY;
    +    function GetKey(Key: String): HKEY;
    +    procedure ChangeKey(Value: HKey; const Path: UnicodeString);
    +    procedure ChangeKey(Value: HKey; const Path: String);
    +    procedure PutData(const Name: UnicodeString; Buffer: Pointer;
                       BufSize: Integer; RegData: TRegDataType);
    +    procedure PutData(const Name: String; Buffer: Pointer;
    +                  BufSize: Integer; RegData: TRegDataType);
         procedure SetCurrentKey(Value: HKEY);
       public
         constructor Create; overload;
    @@ -76,58 +82,85 @@
         constructor Create(aaccess:longword); overload;
         destructor Destroy; override;
     
    -    function CreateKey(const Key: string): Boolean;
    -    function DeleteKey(const Key: string): Boolean;
    -    function DeleteValue(const Name: string): Boolean;
    -    function GetDataInfo(const ValueName: string; Out Value: TRegDataInfo): Boolean;
    -    function GetDataSize(const ValueName: string): Integer;
    -    function GetDataType(const ValueName: string): TRegDataType;
    +    function CreateKey(const Key: UnicodeString): Boolean;
    +    function CreateKey(const Key: String): Boolean;
    +    function DeleteKey(const Key: UnicodeString): Boolean;
    +    function DeleteKey(const Key: String): Boolean;
    +    function DeleteValue(const Name: UnicodeString): Boolean;
    +    function DeleteValue(const Name: String): Boolean;
    +    function GetDataInfo(const ValueName: UnicodeString; Out Value: TRegDataInfo): Boolean;
    +    function GetDataInfo(const ValueName: String; Out Value: TRegDataInfo): Boolean;
    +    function GetDataSize(const ValueName: UnicodeString): Integer;
    +    function GetDataSize(const ValueName: String): Integer;
    +    function GetDataType(const ValueName: UnicodeString): TRegDataType;
    +    function GetDataType(const ValueName: String): TRegDataType;
         function GetKeyInfo(Out Value: TRegKeyInfo): Boolean;
         function HasSubKeys: Boolean;
    -    function KeyExists(const Key: string): Boolean;
    -    function LoadKey(const Key, FileName: string): Boolean;
    -    function OpenKey(const Key: string; CanCreate: Boolean): Boolean;
    -    function OpenKeyReadOnly(const Key: string): Boolean;
    -    function ReadCurrency(const Name: string): Currency;
    -    function ReadBinaryData(const Name: string; var Buffer; BufSize: Integer): Integer;
    -    function ReadBool(const Name: string): Boolean;
    -    function ReadDate(const Name: string): TDateTime;
    -    function ReadDateTime(const Name: string): TDateTime;
    -    function ReadFloat(const Name: string): Double;
    -    function ReadInteger(const Name: string): Integer;
    -    function ReadInt64(const Name: string): Int64;
    -    function ReadString(const Name: string): string;
    -    procedure ReadStringList(const Name: string; AList: TStrings);
    -    function ReadTime(const Name: string): TDateTime;
    -    function RegistryConnect(const UNCName: string): Boolean;
    -    function ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
    -    function RestoreKey(const Key, FileName: string): Boolean;
    -    function SaveKey(const Key, FileName: string): Boolean;
    -    function UnLoadKey(const Key: string): Boolean;
    -    function ValueExists(const Name: string): Boolean;
    +    function KeyExists(const Key: UnicodeString): Boolean;
    +    function KeyExists(const Key: String): Boolean;
    +    function LoadKey(const Key, FileName: UnicodeString): Boolean;
    +    function LoadKey(const Key, FileName: String): Boolean;
    +    function OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
    +    function OpenKey(const Key: String; CanCreate: Boolean): Boolean;
    +    function OpenKeyReadOnly(const Key: UnicodeString): Boolean;
    +    function OpenKeyReadOnly(const Key: String): Boolean;
    +    function ReadCurrency(const Name: UnicodeString): Currency;
    +    function ReadCurrency(const Name: String): Currency;
    +    function ReadBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer): Integer;
    +    function ReadBinaryData(const Name: String; var Buffer; BufSize: Integer): Integer;
    +    function ReadBool(const Name: UnicodeString): Boolean;
    +    function ReadBool(const Name: String): Boolean;
    +    function ReadDate(const Name: UnicodeString): TDateTime;
    +    function ReadDate(const Name: String): TDateTime;
    +    function ReadDateTime(const Name: UnicodeString): TDateTime;
    +    function ReadDateTime(const Name: String): TDateTime;
    +    function ReadFloat(const Name: UnicodeString): Double;
    +    function ReadFloat(const Name: String): Double;
    +    function ReadInteger(const Name: UnicodeString): Integer;
    +    function ReadInteger(const Name: String): Integer;
    +    function ReadInt64(const Name: UnicodeString): Int64;
    +    function ReadInt64(const Name: String): Int64;
    +    function ReadString(const Name: UnicodeString): string;
    +    function ReadString(const Name: String): string;
    +    procedure ReadStringList(const Name: UnicodeString; AList: TStrings);
    +    procedure ReadStringList(const Name: String; AList: TStrings);
    +    function ReadTime(const Name: UnicodeString): TDateTime;
    +    function ReadTime(const Name: String): TDateTime;
    +    function RegistryConnect(const UNCName: UnicodeString): Boolean;
    +    function RegistryConnect(const UNCName: String): Boolean;
    +    function ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
    +    function ReplaceKey(const Key, FileName, BackUpFileName: String): Boolean;
    +    function RestoreKey(const Key, FileName: UnicodeString): Boolean;
    +    function RestoreKey(const Key, FileName: String): Boolean;
    +    function SaveKey(const Key, FileName: UnicodeString): Boolean;
    +    function SaveKey(const Key, FileName: String): Boolean;
    +    function UnLoadKey(const Key: UnicodeString): Boolean;
    +    function UnLoadKey(const Key: String): Boolean;
    +    function ValueExists(const Name: UnicodeString): Boolean;
    +    function ValueExists(const Name: String): Boolean;
     
         procedure CloseKey;
         procedure CloseKey(key:HKEY);
         procedure GetKeyNames(Strings: TStrings);
         procedure GetValueNames(Strings: TStrings);
    -    procedure MoveKey(const OldName, NewName: string; Delete: Boolean);
    -    procedure RenameValue(const OldName, NewName: string);
    -    procedure WriteCurrency(const Name: string; Value: Currency);
    -    procedure WriteBinaryData(const Name: string; var Buffer; BufSize: Integer);
    -    procedure WriteBool(const Name: string; Value: Boolean);
    -    procedure WriteDate(const Name: string; Value: TDateTime);
    -    procedure WriteDateTime(const Name: string; Value: TDateTime);
    -    procedure WriteFloat(const Name: string; Value: Double);
    -    procedure WriteInteger(const Name: string; Value: Integer);
    -    procedure WriteInt64(const Name: string; Value: Int64);
    -    procedure WriteString(const Name, Value: string);
    -    procedure WriteExpandString(const Name, Value: string);
    -    procedure WriteStringList(const Name: string; List: TStrings);
    -    procedure WriteTime(const Name: string; Value: TDateTime);
    +    procedure MoveKey(const OldName, NewName: UnicodeString; Delete: Boolean);
    +    procedure RenameValue(const OldName, NewName: UnicodeString);
    +    procedure WriteCurrency(const Name: UnicodeString; Value: Currency);
    +    procedure WriteBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer);
    +    procedure WriteBool(const Name: UnicodeString; Value: Boolean);
    +    procedure WriteDate(const Name: UnicodeString; Value: TDateTime);
    +    procedure WriteDateTime(const Name: UnicodeString; Value: TDateTime);
    +    procedure WriteFloat(const Name: UnicodeString; Value: Double);
    +    procedure WriteInteger(const Name: UnicodeString; Value: Integer);
    +    procedure WriteInt64(const Name: UnicodeString; Value: Int64);
    +    procedure WriteString(const Name, Value: UnicodeString);
    +    procedure WriteExpandString(const Name, Value: UnicodeString);
    +    procedure WriteStringList(const Name: UnicodeString; List: TStrings);
    +    procedure WriteTime(const Name: UnicodeString; Value: TDateTime);
     
         property Access: LongWord read fAccess write fAccess;
         property CurrentKey: HKEY read fCurrentKey;
    -    property CurrentPath: string read fCurrentPath;
    +    property CurrentPath: UnicodeString read fCurrentPath;
         property LazyWrite: Boolean read fLazyWrite write fLazyWrite;
         property RootKey: HKEY read fRootKey write SetRootKey;
         Property StringSizeIncludesNull : Boolean read FStringSizeIncludesNull;
    @@ -261,7 +294,7 @@
       inherited Destroy;
     end;
     
    -function TRegistry.CreateKey(const Key: string): Boolean;
    +function TRegistry.CreateKey(const Key: UnicodeString): Boolean;
     
     begin
       Result:=SysCreateKey(Key);
    @@ -269,6 +302,27 @@
         Raise ERegistryException.CreateFmt(SRegCreateFailed, [Key]);
     end;
     
    +function TRegistry.CreateKey(const Key: String): Boolean;
    +begin
    +  Result:=CreateKey(UnicodeString(Key));
    +end;
    +
    +function TRegistry.DeleteKey(const Key: String): Boolean;
    +begin
    +  Result:=DeleteKey(UnicodeString(Key));
    +end;
    +
    +function TRegistry.DeleteValue(const Name: String): Boolean;
    +begin
    +  Result:=DeleteValue(UnicodeString(Name));
    +end;
    +
    +function TRegistry.GetDataInfo(const ValueName: String; out Value: TRegDataInfo
    +  ): Boolean;
    +begin
    +  Result:=GetDataInfo(UnicodeString(ValueName), Value);
    +end;
    +
     function TRegistry.GetBaseKey(Relative: Boolean): HKey;
     begin
       If Relative and (CurrentKey<>0) Then
    @@ -277,7 +331,7 @@
         Result := RootKey;
     end;
     
    -function TRegistry.GetData(const Name: string; Buffer: Pointer; BufSize: Integer; out RegData: TRegDataType): Integer;
    +function TRegistry.GetData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; out RegData: TRegDataType): Integer;
     begin
       Result:=SysGetData(Name,Buffer,BufSize,RegData);
       If (Result=-1) then
    @@ -284,7 +338,24 @@
         Raise ERegistryException.CreateFmt(SRegGetDataFailed, [Name]);
     end;
     
    -procedure TRegistry.PutData(const Name: string; Buffer: Pointer;
    +function TRegistry.GetData(const Name: String; Buffer: Pointer;
    +  BufSize: Integer; out RegData: TRegDataType): Integer;
    +begin
    +  Result:=GetData(UnicodeString(Name), Buffer, BufSize, RegData);
    +end;
    +
    +function TRegistry.GetKey(Key: String): HKEY;
    +begin
    +  Result:=GetKey(UnicodeString(Key));
    +end;
    +
    +procedure TRegistry.ChangeKey(Value: HKey; const Path: String);
    +begin
    +  ChangeKey(Value, UnicodeString(Path));
    +end;
    +
    +
    +procedure TRegistry.PutData(const Name: UnicodeString; Buffer: Pointer;
       BufSize: Integer; RegData: TRegDataType);
     
     begin
    @@ -292,9 +363,15 @@
         Raise ERegistryException.CreateFmt(SRegSetDataFailed, [Name]);
     end;
     
    +procedure TRegistry.PutData(const Name: String; Buffer: Pointer;
    +  BufSize: Integer; RegData: TRegDataType);
    +begin
    +  PutData(UnicodeString(Name), Buffer, BufSize, RegData);
    +end;
     
    -function TRegistry.GetDataSize(const ValueName: string): Integer;
     
    +function TRegistry.GetDataSize(const ValueName: UnicodeString): Integer;
    +
     Var
       Info: TRegDataInfo;
     
    @@ -305,8 +382,13 @@
         Result := -1;
     end;
     
    -function TRegistry.GetDataType(const ValueName: string): TRegDataType;
    +function TRegistry.GetDataSize(const ValueName: String): Integer;
    +begin
    +  Result:=GetDataSize(UnicodeString(ValueName));
    +end;
     
    +function TRegistry.GetDataType(const ValueName: UnicodeString): TRegDataType;
    +
     Var
       Info: TRegDataInfo;
     
    @@ -315,6 +397,32 @@
       Result:=Info.RegData;
     end;
     
    +function TRegistry.GetDataType(const ValueName: String): TRegDataType;
    +begin
    +  Result:=GetDataType(UnicodeString(ValueName));
    +end;
    +
    +
    +function TRegistry.KeyExists(const Key: String): Boolean;
    +begin
    +  Result:=KeyExists(UnicodeString(Key));
    +end;
    +
    +function TRegistry.LoadKey(const Key, FileName: String): Boolean;
    +begin
    +  Result:=LoadKey(UnicodeString(Key), UnicodeString(FileName));
    +end;
    +
    +function TRegistry.OpenKey(const Key: String; CanCreate: Boolean): Boolean;
    +begin
    +  Result:=OpenKey(UnicodeString(Key), CanCreate);
    +end;
    +
    +function TRegistry.OpenKeyReadOnly(const Key: String): Boolean;
    +begin
    +  Result:=OpenKeyReadOnly(UnicodeString(Key));
    +end;
    +
     function TRegistry.HasSubKeys: Boolean;
     
     Var
    @@ -326,7 +434,7 @@
         Result:=(Info.NumSubKeys>0);
     end;
     
    -function TRegistry.ReadBinaryData(const Name: string; var Buffer; BufSize: Integer): Integer;
    +function TRegistry.ReadBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer): Integer;
     
     Var
       RegDataType: TRegDataType;
    @@ -337,8 +445,14 @@
         Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
     end;
     
    -function TRegistry.ReadInteger(const Name: string): Integer;
    +function TRegistry.ReadBinaryData(const Name: String; var Buffer;
    +  BufSize: Integer): Integer;
    +begin
    +  Result:=ReadBinaryData(UnicodeString(Name), Buffer, BufSize);
    +end;
     
    +function TRegistry.ReadInteger(const Name: UnicodeString): Integer;
    +
     Var
       RegDataType: TRegDataType;
     
    @@ -348,8 +462,13 @@
         Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
     end;
     
    -function TRegistry.ReadInt64(const Name: string): Int64;
    +function TRegistry.ReadInteger(const Name: String): Integer;
    +begin
    +  Result:=ReadInteger(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadInt64(const Name: UnicodeString): Int64;
    +
     Var
       RegDataType: TRegDataType;
     
    @@ -359,21 +478,36 @@
         Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
     end;
     
    -function TRegistry.ReadBool(const Name: string): Boolean;
    +function TRegistry.ReadInt64(const Name: String): Int64;
    +begin
    +  Result:=ReadInt64(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadBool(const Name: UnicodeString): Boolean;
    +
     begin
       Result:=ReadInteger(Name)<>0;
     end;
     
    -function TRegistry.ReadCurrency(const Name: string): Currency;
    +function TRegistry.ReadBool(const Name: String): Boolean;
    +begin
    +  Result:=ReadBool(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadCurrency(const Name: UnicodeString): Currency;
    +
     begin
       Result:=Default(Currency);
       ReadBinaryData(Name, Result, SizeOf(Currency));
     end;
     
    -function TRegistry.ReadDate(const Name: string): TDateTime;
    +function TRegistry.ReadCurrency(const Name: String): Currency;
    +begin
    +  Result:=ReadCurrency(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadDate(const Name: UnicodeString): TDateTime;
    +
     begin
       Result:=Default(TDateTime);
       ReadBinaryData(Name, Result, SizeOf(TDateTime));
    @@ -380,22 +514,37 @@
       Result:=Trunc(Result);
     end;
     
    -function TRegistry.ReadDateTime(const Name: string): TDateTime;
    +function TRegistry.ReadDate(const Name: String): TDateTime;
    +begin
    +  Result:=ReadDate(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadDateTime(const Name: UnicodeString): TDateTime;
    +
     begin
       Result:=Default(TDateTime);
       ReadBinaryData(Name, Result, SizeOf(TDateTime));
     end;
     
    -function TRegistry.ReadFloat(const Name: string): Double;
    +function TRegistry.ReadDateTime(const Name: String): TDateTime;
    +begin
    +  Result:=ReadDateTime(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadFloat(const Name: UnicodeString): Double;
    +
     begin
       Result:=Default(Double);
       ReadBinaryData(Name,Result,SizeOf(Double));
     end;
     
    -function TRegistry.ReadString(const Name: string): string;
    +function TRegistry.ReadFloat(const Name: String): Double;
    +begin
    +  Result:=ReadFloat(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadString(const Name: UnicodeString): string;
    +
     Var
       Info : TRegDataInfo;
       ReadDataSize: Integer;
    @@ -421,17 +570,22 @@
           if StringSizeIncludesNull and
              (u[Length(u)] = WideChar(0)) then
             SetLength(u,Length(u)-1);
    -      Result:=UTF8Encode(u);
    +      Result:=u;
         end;
       end;
     end;
     
    -procedure TRegistry.ReadStringList(const Name: string; AList: TStrings);
    +function TRegistry.ReadString(const Name: String): string;
    +begin
    +  Result:=ReadString(UnicodeString(Name));
    +end;
     
    +procedure TRegistry.ReadStringList(const Name: UnicodeString; AList: TStrings);
    +
     Var
       Info : TRegDataInfo;
    -  ReadDataSize: Integer;
    -  Data: string;
    +  ReadDataSize, i: Integer;
    +  Data: UnicodeString;
     
     begin
       AList.Clear;
    @@ -441,7 +595,7 @@
          If Not (Info.RegData in [rdMultiString]) then
            Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
          SetLength(Data,Info.DataSize);
    -     ReadDataSize := GetData(Name,PChar(Data),Info.DataSize,Info.RegData);
    +     ReadDataSize := GetData(Name,PWideChar(Data),Info.DataSize,Info.RegData) div SizeOf(WideChar);
          if ReadDataSize > 0 then
          begin
            // If the data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type,
    @@ -454,14 +608,19 @@
                Dec(ReadDataSize);
            end;
            SetLength(Data, ReadDataSize);
    -       Data := StringReplace(Data, #0, LineEnding, [rfReplaceAll]);
    +       Data := UnicodeStringReplace(Data, #0, AList.LineBreak, [rfReplaceAll]);
            AList.Text := Data;
          end
        end
     end;
     
    -function TRegistry.ReadTime(const Name: string): TDateTime;
    +procedure TRegistry.ReadStringList(const Name: String; AList: TStrings);
    +begin
    +  ReadStringList(UnicodeString(Name), AList);
    +end;
     
    +function TRegistry.ReadTime(const Name: UnicodeString): TDateTime;
    +
     begin
       Result:=Default(TDateTime);
       ReadBinaryData(Name, Result, SizeOf(TDateTime));
    @@ -468,81 +627,123 @@
       Result:=Frac(Result);
     end;
     
    -procedure TRegistry.WriteBinaryData(const Name: string; var Buffer; BufSize: Integer);
    +function TRegistry.ReadTime(const Name: String): TDateTime;
     begin
    +  Result:=ReadTime(UnicodeString(Name));
    +end;
    +
    +function TRegistry.RegistryConnect(const UNCName: String): Boolean;
    +begin
    +  Result:=RegistryConnect(UnicodeString(UNCName));
    +end;
    +
    +function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: String): Boolean;
    +begin
    +  Result:=ReplaceKey(UnicodeString(Key), UnicodeString(FileName), UnicodeString(BackUpFileName))
    +end;
    +
    +function TRegistry.RestoreKey(const Key, FileName: String): Boolean;
    +begin
    +  Result:=RestoreKey(UnicodeString(Key), UnicodeString(FileName));
    +end;
    +
    +function TRegistry.SaveKey(const Key, FileName: String): Boolean;
    +begin
    +  Result:=SaveKey(UnicodeString(Key), UnicodeString(FileName));
    +end;
    +
    +function TRegistry.UnLoadKey(const Key: String): Boolean;
    +begin
    +  Result:=UnloadKey(UnicodeString(Key));
    +end;
    +
    +function TRegistry.ValueExists(const Name: String): Boolean;
    +begin
    +  Result:=ValueExists(UnicodeString(Name));
    +end;
    +
    +procedure TRegistry.WriteBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer);
    +begin
       PutData(Name, @Buffer, BufSize, rdBinary);
     end;
     
    -procedure TRegistry.WriteBool(const Name: string; Value: Boolean);
    +procedure TRegistry.WriteBool(const Name: UnicodeString; Value: Boolean);
     
     begin
       WriteInteger(Name,Ord(Value));
     end;
     
    -procedure TRegistry.WriteCurrency(const Name: string; Value: Currency);
    +procedure TRegistry.WriteCurrency(const Name: UnicodeString; Value: Currency);
     begin
       WriteBinaryData(Name, Value, SizeOf(Currency));
     end;
     
    -procedure TRegistry.WriteDate(const Name: string; Value: TDateTime);
    +procedure TRegistry.WriteDate(const Name: UnicodeString; Value: TDateTime);
     begin
       WriteBinarydata(Name, Value, SizeOf(TDateTime));
     end;
     
    -procedure TRegistry.WriteTime(const Name: string; Value: TDateTime);
    +procedure TRegistry.WriteTime(const Name: UnicodeString; Value: TDateTime);
     begin
       WriteBinaryData(Name, Value, SizeOf(TDateTime));
     end;
     
    -procedure TRegistry.WriteDateTime(const Name: string; Value: TDateTime);
    +procedure TRegistry.WriteDateTime(const Name: UnicodeString; Value: TDateTime);
     begin
       WriteBinaryData(Name, Value, SizeOf(TDateTime));
     end;
     
    -procedure TRegistry.WriteExpandString(const Name, Value: string);
    -var
    -  u: UnicodeString;
    -
    +procedure TRegistry.WriteExpandString(const Name, Value: UnicodeString);
     begin
    -  u:=Value;
    -  PutData(Name, PWideChar(u), ByteLength(u), rdExpandString);
    +  PutData(Name, PWideChar(Value), ByteLength(Value), rdExpandString);
     end;
     
    -procedure TRegistry.WriteStringList(const Name: string; List: TStrings);
    +procedure TRegistry.WriteStringList(const Name: UnicodeString; List: TStrings);
     
     Var
    -  Data: string;
    -
    +  Data: UnicodeString;
    +  u: UnicodeString;
    +  i: Integer;
     begin
    -  Data := StringReplace(List.Text, LineEnding, #0, [rfReplaceAll]) + #0#0;
    -  PutData(Name, PChar(Data), Length(Data),rdMultiString);
    +  Data := '';
    +  //REG_MULTI_SZ data cannot contain empty strings
    +  for i := 0 to List.Count - 1 do
    +  begin
    +    u := List[i];
    +    if (u>'') then
    +    begin
    +      if (Data>'') then
    +        Data := Data + #0 + u
    +      else
    +        Data := Data + u;
    +    end;
    +  end;
    +  if StringSizeIncludesNull then
    +    Data := Data + #0#0;
    +  PutData(Name, PWideChar(Data), ByteLength(Data), rdMultiString);
     end;
     
    -procedure TRegistry.WriteFloat(const Name: string; Value: Double);
    +procedure TRegistry.WriteFloat(const Name: UnicodeString; Value: Double);
     begin
       WriteBinaryData(Name, Value, SizeOf(Double));
     end;
     
    -procedure TRegistry.WriteInteger(const Name: string; Value: Integer);
    +procedure TRegistry.WriteInteger(const Name: UnicodeString; Value: Integer);
     begin
       PutData(Name, @Value, SizeOf(Integer), rdInteger);
     end;
     
    -procedure TRegistry.WriteInt64(const Name: string; Value: Int64);
    +procedure TRegistry.WriteInt64(const Name: UnicodeString; Value: Int64);
     begin
       PutData(Name, @Value, SizeOf(Int64), rdInt64);
     end;
     
    -procedure TRegistry.WriteString(const Name, Value: string);
    -var
    -  u: UnicodeString;
    -
    +procedure TRegistry.WriteString(const Name, Value: UnicodeString);
     begin
    -  u:=Value;
    -  PutData(Name, PWideChar(u), ByteLength(u), rdString);
    +  PutData(Name, PWideChar(Value), ByteLength(Value), rdString);
     end;
     
    -procedure TRegistry.MoveKey(const OldName, NewName: string; Delete: Boolean);
    +procedure TRegistry.MoveKey(const OldName, NewName: UnicodeString; Delete: Boolean);
     begin
     
     end;
    Index: packages/fcl-registry/src/winreg.inc
    ===================================================================
    --- packages/fcl-registry/src/winreg.inc	(revision 41667)
    +++ packages/fcl-registry/src/winreg.inc	(working copy)
    @@ -1,7 +1,7 @@
     Const
       RegDataWords : Array [TRegDataType] of DWORD
                    = (REG_NONE,REG_SZ,REG_EXPAND_SZ,REG_BINARY,REG_DWORD,REG_DWORD_BIG_ENDIAN,
    -                  REG_LINK,REG_MULTI_SZ,REG_RESOURCE_LIST,REG_FULL_RESOURCE_DESCRIPTOR,REG_RESOURCE_REQUIREMENTS_LIST,REG_QWORD);
    +                  REG_LINK,REG_MULTI_SZ,REG_RESOURCE_LIST,REG_FULL_RESOURCE_DESCRIPTOR,REG_RESOURCE_REQUIREMENTS_LIST,11{REG_QWORD}); //*****UNDO THIS!
     
     type
       TWinRegData = record
    @@ -28,7 +28,7 @@
       Dispose(PWinRegData(FSysData));
     end;
     
    -Function PrepKey(Const S : String) : String;
    +Function PrepKey(Const S : UnicodeString) : UnicodeString;
     
     begin
       Result := S;
    @@ -36,7 +36,7 @@
         System.Delete(Result, 1, 1);
     end;
     
    -Function RelativeKey(Const S : String) : Boolean;
    +Function RelativeKey(Const S : UnicodeString) : Boolean;
     
     begin
       Result:=(S='') or (S[1]<>'\')
    @@ -43,7 +43,7 @@
     end;
     
     
    -function TRegistry.sysCreateKey(const Key: String): Boolean;
    +function TRegistry.sysCreateKey(Key: UnicodeString): Boolean;
     Var
       u: UnicodeString;
       Disposition: Dword;
    @@ -52,9 +52,9 @@
     
     begin
       SecurityAttributes := Nil;
    -  u:=PrepKey(Key);
    +  Key:=PrepKey(Key);
       FLastError:=RegCreateKeyExW(GetBaseKey(RelativeKey(Key)),
    -                              PWideChar(u),
    +                              PWideChar(Key),
                                   0,
                                   '',
                                   REG_OPTION_NON_VOLATILE,
    @@ -66,7 +66,7 @@
       RegCloseKey(Handle);
     end;
     
    -function TRegistry.DeleteKey(const Key: String): Boolean;
    +function TRegistry.DeleteKey(const Key: UnicodeString): Boolean;
     
     Var
       u: UnicodeString;
    @@ -76,21 +76,21 @@
       Result:=FLastError=ERROR_SUCCESS;
     end;
     
    -function TRegistry.DeleteValue(const Name: String): Boolean;
    +
    +function TRegistry.DeleteValue(const Name: UnicodeString): Boolean;
     begin
    -  FLastError:= RegDeleteValueW(fCurrentKey, PWideChar(UnicodeString(Name)));
    +  FLastError:= RegDeleteValueW(fCurrentKey, PWideChar(Name));
       Result:=FLastError=ERROR_SUCCESS;
     end;
     
    -function TRegistry.SysGetData(const Name: String; Buffer: Pointer;
    +
    +function TRegistry.SysGetData(const Name: UnicodeString; Buffer: Pointer;
               BufSize: Integer; Out RegData: TRegDataType): Integer;
     Var
    -  u: UnicodeString;
       RD : DWord;
     
     begin
    -  u := Name;
    -  FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(u),Nil,
    +  FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(Name),Nil,
                           @RD,Buffer,lpdword(@BufSize));
       if (FLastError<>ERROR_SUCCESS) Then
         Result:=-1
    @@ -103,17 +103,15 @@
         end;
     end;
     
    -function TRegistry.GetDataInfo(const ValueName: String; out Value: TRegDataInfo): Boolean;
    +function TRegistry.GetDataInfo(const ValueName: UnicodeString; out Value: TRegDataInfo): Boolean;
     
     Var
    -  u: UnicodeString;
       RD : DWord;
     
     begin
    -  u:=ValueName;
       With Value do
         begin
    -    FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(u),Nil,lpdword(@RegData),Nil,lpdword(@DataSize));
    +    FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(ValueName),Nil,lpdword(@RegData),Nil,lpdword(@DataSize));
         Result:=FLastError=ERROR_SUCCESS;
         if Result then
           begin
    @@ -131,24 +129,18 @@
     end;
     
     
    -function TRegistry.GetKey(const Key: String): HKEY;
    +function TRegistry.GetKey(Key: UnicodeString): HKEY;
     var
    -  S : string;
    -{$ifndef WinCE}
    -  u : UnicodeString;
    -{$endif}
       Rel : Boolean;
     begin
       Result:=0;
    -  S:=Key;
    -  Rel:=RelativeKey(S);
    +  Rel:=RelativeKey(Key);
       if not(Rel) then
    -    Delete(S,1,1);
    +    Delete(Key,1,1);
     {$ifdef WinCE}
    -  FLastError:=RegOpenKeyEx(GetBaseKey(Rel),PWideChar(WideString(S)),0,FAccess,Result);
    +  FLastError:=RegOpenKeyEx(GetBaseKey(Rel),PWideChar(Key),0,FAccess,Result);
     {$else WinCE}
    -  u:=UnicodeString(S);
    -  FLastError:=RegOpenKeyExW(GetBaseKey(Rel),PWideChar(u),0,FAccess,Result);
    +  FLastError:=RegOpenKeyExW(GetBaseKey(Rel),PWideChar(Key),0,FAccess,Result);
     {$endif WinCE}
     end;
     
    @@ -174,7 +166,7 @@
     end;
     
     
    -function TRegistry.KeyExists(const Key: string): Boolean;
    +function TRegistry.KeyExists(const Key: UnicodeString): Boolean;
     var
       KeyHandle : HKEY;
       OldAccess : LONG;
    @@ -196,20 +188,20 @@
     end;
     
     
    -function TRegistry.LoadKey(const Key, FileName: string): Boolean;
    +function TRegistry.LoadKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
     
    -function TRegistry.OpenKey(const Key: string; CanCreate: Boolean): Boolean;
     
    +function TRegistry.OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
    +
     Var
    -  u: UnicodeString;
    +  u, S: UnicodeString;
       Handle: HKEY;
       Disposition: Integer;
       SecurityAttributes: Pointer; //LPSECURITY_ATTRIBUTES;
    -  S: string;
     begin
       SecurityAttributes := Nil;
       u:=PrepKey(Key);
    @@ -232,13 +224,14 @@
         if RelativeKey(Key) then
           S:=CurrentPath + Key
         else
    -      S:=UTF8Encode(u);
    +      S:=u;
         ChangeKey(Handle, S);
       end;
     end;
     
    -function TRegistry.OpenKeyReadOnly(const Key: string): Boolean;
     
    +function TRegistry.OpenKeyReadOnly(const Key: UnicodeString): Boolean;
    +
     Var
       OldAccess: LongWord;
     begin
    @@ -251,7 +244,8 @@
       end;
     end;
     
    -function TRegistry.RegistryConnect(const UNCName: string): Boolean;
    +
    +function TRegistry.RegistryConnect(const UNCName: UnicodeString): Boolean;
     {$ifndef WinCE}
     var
       newroot: HKEY;
    @@ -260,7 +254,7 @@
     {$ifdef WinCE}
       Result:=False;
     {$else}
    -  FLastError:=RegConnectRegistryW(PWideChar(UnicodeString(UNCName)),RootKey,newroot);
    +  FLastError:=RegConnectRegistryW(PWideChar(UNCName),RootKey,newroot);
       Result:=FLastError=ERROR_SUCCESS;
       if Result then begin
         RootKey:=newroot;
    @@ -269,28 +263,33 @@
     {$endif}
     end;
     
    -function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
    +
    +function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.RestoreKey(const Key, FileName: string): Boolean;
    +
    +function TRegistry.RestoreKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.SaveKey(const Key, FileName: string): Boolean;
    +
    +function TRegistry.SaveKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.UnLoadKey(const Key: string): Boolean;
    +
    +function TRegistry.UnLoadKey(const Key: UnicodeString): Boolean;
     begin
       Result := false;
     end;
     
    -function TRegistry.ValueExists(const Name: string): Boolean;
     
    +function TRegistry.ValueExists(const Name: UnicodeString): Boolean;
    +
     var
       Info : TRegDataInfo;
     
    @@ -298,6 +297,7 @@
       Result:=GetDataInfo(Name,Info);
     end;
     
    +
     procedure TRegistry.CloseKey;
     begin
       If (CurrentKey<>0) then
    @@ -316,7 +316,7 @@
       RegCloseKey(key);
     end;
     
    -procedure TRegistry.ChangeKey(Value: HKey; const Path: String);
    +procedure TRegistry.ChangeKey(Value: HKey; const Path: UnicodeString);
     begin
       CloseKey;
       FCurrentKey:=Value;
    @@ -323,6 +323,7 @@
       FCurrentPath:=Path;
     end;
     
    +
     procedure TRegistry.GetKeyNames(Strings: TStrings);
     
     var
    @@ -410,12 +411,11 @@
     end;
     
     
    -Function TRegistry.SysPutData(const Name: string; Buffer: Pointer;
    +Function TRegistry.SysPutData(const Name: UnicodeString; Buffer: Pointer;
       BufSize: Integer; RegData: TRegDataType) : Boolean;
     
     
     Var
    -  u: UnicodeString;
       RegDataType: DWORD;
       B : Pchar;
       S : String;
    @@ -422,12 +422,11 @@
     
     begin
       RegDataType:=RegDataWords[RegData];
    -  u:=UnicodeString(Name);
    -  FLastError:=RegSetValueExW(fCurrentKey,PWideChar(u),0,RegDataType,Buffer,BufSize);
    +  FLastError:=RegSetValueExW(fCurrentKey,PWideChar(Name),0,RegDataType,Buffer,BufSize);
       Result:=FLastError=ERROR_SUCCESS;
     end;
     
    -procedure TRegistry.RenameValue(const OldName, NewName: string);
    +procedure TRegistry.RenameValue(const OldName, NewName: UnicodeString);
     
     var
       L: Integer;
    Index: packages/fcl-registry/src/xmlreg.pp
    ===================================================================
    --- packages/fcl-registry/src/xmlreg.pp	(revision 41667)
    +++ packages/fcl-registry/src/xmlreg.pp	(working copy)
    @@ -329,7 +329,7 @@
                          begin
                          if not IsUnicode then
                            begin
    -                       S:=UTF8Encode(DataNode.NodeValue); // Convert to ansistring
    +                       S:=DataNode.NodeValue; // Convert to ansistring
                            NS:=Length(S);
                            Result:=(DataSize>=NS);
                            if Result then
    @@ -390,7 +390,7 @@
                        SW:=UnicodeString(PUnicodeChar(@Data))
                      else
                        SW:=UnicodeString(PAnsiChar(@Data));
    -                   //S:=UTF8Encode(SW);
    +                   //S:=SW;
                      end;
           dtBinary : SW:=BufToHex(Data,DataSize);
           dtStrings : SW:=BufToHex(Data,DataSize);
    @@ -671,7 +671,7 @@
             L:=Length(DN.NodeValue)*SizeOf(UnicodeChar)
           else
             begin
    -        S := UTF8Encode(DN.NodeValue);
    +        S := DN.NodeValue;
             L:=Length(S);
             end
           end
    @@ -727,7 +727,7 @@
                   Case TDataType(StrToIntDef(TDomElement(Node)[SType],0)) of
                     dtUnknown : L:=0;
                     dtDWord   : L:=4;
    -                DtString  : L:=Length(UTF8Encode(DataNode.NodeValue));
    +                DtString  : L:=Length(String(DataNode.NodeValue));
                     dtBinary  : L:=Length(DataNode.NodeValue) div 2;
                   end
                 else
    Index: packages/fcl-registry/src/xregreg.inc
    ===================================================================
    --- packages/fcl-registry/src/xregreg.inc	(revision 41667)
    +++ packages/fcl-registry/src/xregreg.inc	(working copy)
    @@ -130,24 +130,24 @@
       TXMLRegistryInstance.FreeXMLRegistry(TXMLRegistry(FSysData));
     end;
     
    -function TRegistry.SysCreateKey(const Key: String): Boolean;
    +function TRegistry.SysCreateKey(Key: UnicodeString): Boolean;
     
     begin
       Result:=TXmlRegistry(FSysData).CreateKey(Key);
     end;
     
    -function TRegistry.DeleteKey(const Key: string): Boolean;
    +function TRegistry.DeleteKey(const Key: UnicodeString): Boolean;
     
     begin
       Result:=TXMLRegistry(FSysData).DeleteKey(Key);
     end;
     
    -function TRegistry.DeleteValue(const Name: string): Boolean;
    +function TRegistry.DeleteValue(const Name: UnicodeString): Boolean;
     begin
       Result:=TXmlRegistry(FSysData).DeleteValue(Name);
     end;
     
    -function TRegistry.SysGetData(const Name: String; Buffer: Pointer;
    +function TRegistry.SysGetData(const Name: UnicodeString; Buffer: Pointer;
               BufSize: Integer; Out RegData: TRegDataType): Integer;
     
     Var
    @@ -160,7 +160,7 @@
         Result:=-1;
     end;
     
    -function TRegistry.GetDataInfo(const ValueName: string; out Value: TRegDataInfo): Boolean;
    +function TRegistry.GetDataInfo(const ValueName: UnicodeString; out Value: TRegDataInfo): Boolean;
     
     Var
       Info : TDataInfo;
    @@ -181,7 +181,7 @@
           end;
     end;
     
    -function TRegistry.GetKey(const Key: string): HKEY;
    +function TRegistry.GetKey(Key: UnicodeString): HKEY;
     begin
       Result := 0;
     end;
    @@ -205,17 +205,17 @@
           end;
     end;
     
    -function TRegistry.KeyExists(const Key: string): Boolean;
    +function TRegistry.KeyExists(const Key: UnicodeString): Boolean;
     begin
       Result:=TXmlRegistry(FSysData).KeyExists(Key);
     end;
     
    -function TRegistry.LoadKey(const Key, FileName: string): Boolean;
    +function TRegistry.LoadKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.OpenKey(const Key: string; CanCreate: Boolean): Boolean;
    +function TRegistry.OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
     
     begin
       Result:=TXmlRegistry(FSysData).SetKey(Key,CanCreate);
    @@ -222,43 +222,43 @@
       FCurrentKey:=1;
     end;
     
    -function TRegistry.OpenKeyReadOnly(const Key: string): Boolean;
    +function TRegistry.OpenKeyReadOnly(const Key: UnicodeString): Boolean;
     
     begin
       Result:=TXmlRegistry(FSysData).SetKey(Key,False);
     end;
     
    -function TRegistry.RegistryConnect(const UNCName: string): Boolean;
    +function TRegistry.RegistryConnect(const UNCName: UnicodeString): Boolean;
     begin
       Result := True;
     end;
     
    -function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
    +function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.RestoreKey(const Key, FileName: string): Boolean;
    +function TRegistry.RestoreKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.SaveKey(const Key, FileName: string): Boolean;
    +function TRegistry.SaveKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.UnLoadKey(const Key: string): Boolean;
    +function TRegistry.UnLoadKey(const Key: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.ValueExists(const Name: string): Boolean;
    +function TRegistry.ValueExists(const Name: UnicodeString): Boolean;
     begin
       Result := TXmlRegistry(FSysData).ValueExists(Name);
     end;
     
    -procedure TRegistry.ChangeKey(Value: HKey; const Path: string);
    +procedure TRegistry.ChangeKey(Value: HKey; const Path: UnicodeString);
     begin
     
     end;
    @@ -274,7 +274,7 @@
     end;
     
     
    -function TRegistry.SysPutData(const Name: string; Buffer: Pointer;
    +function TRegistry.SysPutData(const Name: UnicodeString; Buffer: Pointer;
       BufSize: Integer; RegData: TRegDataType): Boolean;
     
     Var
    @@ -285,7 +285,7 @@
       Result:=TXMLRegistry(FSysData).SetValueDataUnicode(Name,DataType,Buffer^,BufSize);
     end;
     
    -procedure TRegistry.RenameValue(const OldName, NewName: string);
    +procedure TRegistry.RenameValue(const OldName, NewName: UnicodeString);
     begin
       TXMLRegistry(FSysData).RenameValue(OldName,NewName);
     end;
    
  • registry.unicode.part2.diff (53,709 bytes)
    Index: packages/fcl-registry/src/regdef.inc
    ===================================================================
    --- packages/fcl-registry/src/regdef.inc	(revision 41667)
    +++ packages/fcl-registry/src/regdef.inc	(working copy)
    @@ -2,7 +2,7 @@
       HKEY = THandle;
       PHKEY = ^HKEY;
       
    -{$ifdef windows}
    +{$if defined(windows) and not defined(XMLREG)}
     
     { Direct mapping to constants in Windows unit }
     
    Index: packages/fcl-registry/src/registry.pp
    ===================================================================
    --- packages/fcl-registry/src/registry.pp	(revision 41667)
    +++ packages/fcl-registry/src/registry.pp	(working copy)
    @@ -54,22 +54,28 @@
         fCurrentKey: HKEY;
         fRootKey: HKEY;
         fLazyWrite: Boolean;
    -    fCurrentPath: string;
    +    fCurrentPath: UnicodeString;
         function GetLastErrorMsg: string;
         procedure SetRootKey(Value: HKEY);
         Procedure SysRegCreate;
         Procedure SysRegFree;
    -    Function  SysGetData(const Name: String; Buffer: Pointer; BufSize: Integer; Out RegData: TRegDataType): Integer;
    -    Function  SysPutData(const Name: string; Buffer: Pointer; BufSize: Integer; RegData: TRegDataType) : Boolean;
    -    Function  SysCreateKey(const Key: String): Boolean;
    +    Function  SysGetData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; Out RegData: TRegDataType): Integer;
    +    Function  SysPutData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; RegData: TRegDataType) : Boolean;
    +    Function  SysCreateKey(Key: UnicodeString): Boolean;
       protected
         function GetBaseKey(Relative: Boolean): HKey;
    -    function GetData(const Name: string; Buffer: Pointer;
    +    function GetData(const Name: UnicodeString; Buffer: Pointer;
                       BufSize: Integer; Out RegData: TRegDataType): Integer;
    -    function GetKey(const Key: string): HKEY;
    -    procedure ChangeKey(Value: HKey; const Path: string);
    -    procedure PutData(const Name: string; Buffer: Pointer;
    +    function GetData(const Name: String; Buffer: Pointer;
    +                  BufSize: Integer; Out RegData: TRegDataType): Integer;
    +    function GetKey(Key: UnicodeString): HKEY;
    +    function GetKey(Key: String): HKEY;
    +    procedure ChangeKey(Value: HKey; const Path: UnicodeString);
    +    procedure ChangeKey(Value: HKey; const Path: String);
    +    procedure PutData(const Name: UnicodeString; Buffer: Pointer;
                       BufSize: Integer; RegData: TRegDataType);
    +    procedure PutData(const Name: String; Buffer: Pointer;
    +                  BufSize: Integer; RegData: TRegDataType);
         procedure SetCurrentKey(Value: HKEY);
       public
         constructor Create; overload;
    @@ -76,58 +82,85 @@
         constructor Create(aaccess:longword); overload;
         destructor Destroy; override;
     
    -    function CreateKey(const Key: string): Boolean;
    -    function DeleteKey(const Key: string): Boolean;
    -    function DeleteValue(const Name: string): Boolean;
    -    function GetDataInfo(const ValueName: string; Out Value: TRegDataInfo): Boolean;
    -    function GetDataSize(const ValueName: string): Integer;
    -    function GetDataType(const ValueName: string): TRegDataType;
    +    function CreateKey(const Key: UnicodeString): Boolean;
    +    function CreateKey(const Key: String): Boolean;
    +    function DeleteKey(const Key: UnicodeString): Boolean;
    +    function DeleteKey(const Key: String): Boolean;
    +    function DeleteValue(const Name: UnicodeString): Boolean;
    +    function DeleteValue(const Name: String): Boolean;
    +    function GetDataInfo(const ValueName: UnicodeString; Out Value: TRegDataInfo): Boolean;
    +    function GetDataInfo(const ValueName: String; Out Value: TRegDataInfo): Boolean;
    +    function GetDataSize(const ValueName: UnicodeString): Integer;
    +    function GetDataSize(const ValueName: String): Integer;
    +    function GetDataType(const ValueName: UnicodeString): TRegDataType;
    +    function GetDataType(const ValueName: String): TRegDataType;
         function GetKeyInfo(Out Value: TRegKeyInfo): Boolean;
         function HasSubKeys: Boolean;
    -    function KeyExists(const Key: string): Boolean;
    -    function LoadKey(const Key, FileName: string): Boolean;
    -    function OpenKey(const Key: string; CanCreate: Boolean): Boolean;
    -    function OpenKeyReadOnly(const Key: string): Boolean;
    -    function ReadCurrency(const Name: string): Currency;
    -    function ReadBinaryData(const Name: string; var Buffer; BufSize: Integer): Integer;
    -    function ReadBool(const Name: string): Boolean;
    -    function ReadDate(const Name: string): TDateTime;
    -    function ReadDateTime(const Name: string): TDateTime;
    -    function ReadFloat(const Name: string): Double;
    -    function ReadInteger(const Name: string): Integer;
    -    function ReadInt64(const Name: string): Int64;
    -    function ReadString(const Name: string): string;
    -    procedure ReadStringList(const Name: string; AList: TStrings);
    -    function ReadTime(const Name: string): TDateTime;
    -    function RegistryConnect(const UNCName: string): Boolean;
    -    function ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
    -    function RestoreKey(const Key, FileName: string): Boolean;
    -    function SaveKey(const Key, FileName: string): Boolean;
    -    function UnLoadKey(const Key: string): Boolean;
    -    function ValueExists(const Name: string): Boolean;
    +    function KeyExists(const Key: UnicodeString): Boolean;
    +    function KeyExists(const Key: String): Boolean;
    +    function LoadKey(const Key, FileName: UnicodeString): Boolean;
    +    function LoadKey(const Key, FileName: String): Boolean;
    +    function OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
    +    function OpenKey(const Key: String; CanCreate: Boolean): Boolean;
    +    function OpenKeyReadOnly(const Key: UnicodeString): Boolean;
    +    function OpenKeyReadOnly(const Key: String): Boolean;
    +    function ReadCurrency(const Name: UnicodeString): Currency;
    +    function ReadCurrency(const Name: String): Currency;
    +    function ReadBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer): Integer;
    +    function ReadBinaryData(const Name: String; var Buffer; BufSize: Integer): Integer;
    +    function ReadBool(const Name: UnicodeString): Boolean;
    +    function ReadBool(const Name: String): Boolean;
    +    function ReadDate(const Name: UnicodeString): TDateTime;
    +    function ReadDate(const Name: String): TDateTime;
    +    function ReadDateTime(const Name: UnicodeString): TDateTime;
    +    function ReadDateTime(const Name: String): TDateTime;
    +    function ReadFloat(const Name: UnicodeString): Double;
    +    function ReadFloat(const Name: String): Double;
    +    function ReadInteger(const Name: UnicodeString): Integer;
    +    function ReadInteger(const Name: String): Integer;
    +    function ReadInt64(const Name: UnicodeString): Int64;
    +    function ReadInt64(const Name: String): Int64;
    +    function ReadString(const Name: UnicodeString): string;
    +    function ReadString(const Name: String): string;
    +    procedure ReadStringList(const Name: UnicodeString; AList: TStrings);
    +    procedure ReadStringList(const Name: String; AList: TStrings);
    +    function ReadTime(const Name: UnicodeString): TDateTime;
    +    function ReadTime(const Name: String): TDateTime;
    +    function RegistryConnect(const UNCName: UnicodeString): Boolean;
    +    function RegistryConnect(const UNCName: String): Boolean;
    +    function ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
    +    function ReplaceKey(const Key, FileName, BackUpFileName: String): Boolean;
    +    function RestoreKey(const Key, FileName: UnicodeString): Boolean;
    +    function RestoreKey(const Key, FileName: String): Boolean;
    +    function SaveKey(const Key, FileName: UnicodeString): Boolean;
    +    function SaveKey(const Key, FileName: String): Boolean;
    +    function UnLoadKey(const Key: UnicodeString): Boolean;
    +    function UnLoadKey(const Key: String): Boolean;
    +    function ValueExists(const Name: UnicodeString): Boolean;
    +    function ValueExists(const Name: String): Boolean;
     
         procedure CloseKey;
         procedure CloseKey(key:HKEY);
         procedure GetKeyNames(Strings: TStrings);
         procedure GetValueNames(Strings: TStrings);
    -    procedure MoveKey(const OldName, NewName: string; Delete: Boolean);
    -    procedure RenameValue(const OldName, NewName: string);
    -    procedure WriteCurrency(const Name: string; Value: Currency);
    -    procedure WriteBinaryData(const Name: string; var Buffer; BufSize: Integer);
    -    procedure WriteBool(const Name: string; Value: Boolean);
    -    procedure WriteDate(const Name: string; Value: TDateTime);
    -    procedure WriteDateTime(const Name: string; Value: TDateTime);
    -    procedure WriteFloat(const Name: string; Value: Double);
    -    procedure WriteInteger(const Name: string; Value: Integer);
    -    procedure WriteInt64(const Name: string; Value: Int64);
    -    procedure WriteString(const Name, Value: string);
    -    procedure WriteExpandString(const Name, Value: string);
    -    procedure WriteStringList(const Name: string; List: TStrings);
    -    procedure WriteTime(const Name: string; Value: TDateTime);
    +    procedure MoveKey(const OldName, NewName: UnicodeString; Delete: Boolean);
    +    procedure RenameValue(const OldName, NewName: UnicodeString);
    +    procedure WriteCurrency(const Name: UnicodeString; Value: Currency);
    +    procedure WriteBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer);
    +    procedure WriteBool(const Name: UnicodeString; Value: Boolean);
    +    procedure WriteDate(const Name: UnicodeString; Value: TDateTime);
    +    procedure WriteDateTime(const Name: UnicodeString; Value: TDateTime);
    +    procedure WriteFloat(const Name: UnicodeString; Value: Double);
    +    procedure WriteInteger(const Name: UnicodeString; Value: Integer);
    +    procedure WriteInt64(const Name: UnicodeString; Value: Int64);
    +    procedure WriteString(const Name, Value: UnicodeString);
    +    procedure WriteExpandString(const Name, Value: UnicodeString);
    +    procedure WriteStringList(const Name: UnicodeString; List: TStrings);
    +    procedure WriteTime(const Name: UnicodeString; Value: TDateTime);
     
         property Access: LongWord read fAccess write fAccess;
         property CurrentKey: HKEY read fCurrentKey;
    -    property CurrentPath: string read fCurrentPath;
    +    property CurrentPath: UnicodeString read fCurrentPath;
         property LazyWrite: Boolean read fLazyWrite write fLazyWrite;
         property RootKey: HKEY read fRootKey write SetRootKey;
         Property StringSizeIncludesNull : Boolean read FStringSizeIncludesNull;
    @@ -261,7 +294,7 @@
       inherited Destroy;
     end;
     
    -function TRegistry.CreateKey(const Key: string): Boolean;
    +function TRegistry.CreateKey(const Key: UnicodeString): Boolean;
     
     begin
       Result:=SysCreateKey(Key);
    @@ -269,6 +302,27 @@
         Raise ERegistryException.CreateFmt(SRegCreateFailed, [Key]);
     end;
     
    +function TRegistry.CreateKey(const Key: String): Boolean;
    +begin
    +  Result:=CreateKey(UnicodeString(Key));
    +end;
    +
    +function TRegistry.DeleteKey(const Key: String): Boolean;
    +begin
    +  Result:=DeleteKey(UnicodeString(Key));
    +end;
    +
    +function TRegistry.DeleteValue(const Name: String): Boolean;
    +begin
    +  Result:=DeleteValue(UnicodeString(Name));
    +end;
    +
    +function TRegistry.GetDataInfo(const ValueName: String; out Value: TRegDataInfo
    +  ): Boolean;
    +begin
    +  Result:=GetDataInfo(UnicodeString(ValueName), Value);
    +end;
    +
     function TRegistry.GetBaseKey(Relative: Boolean): HKey;
     begin
       If Relative and (CurrentKey<>0) Then
    @@ -277,7 +331,7 @@
         Result := RootKey;
     end;
     
    -function TRegistry.GetData(const Name: string; Buffer: Pointer; BufSize: Integer; out RegData: TRegDataType): Integer;
    +function TRegistry.GetData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; out RegData: TRegDataType): Integer;
     begin
       Result:=SysGetData(Name,Buffer,BufSize,RegData);
       If (Result=-1) then
    @@ -284,7 +338,24 @@
         Raise ERegistryException.CreateFmt(SRegGetDataFailed, [Name]);
     end;
     
    -procedure TRegistry.PutData(const Name: string; Buffer: Pointer;
    +function TRegistry.GetData(const Name: String; Buffer: Pointer;
    +  BufSize: Integer; out RegData: TRegDataType): Integer;
    +begin
    +  Result:=GetData(UnicodeString(Name), Buffer, BufSize, RegData);
    +end;
    +
    +function TRegistry.GetKey(Key: String): HKEY;
    +begin
    +  Result:=GetKey(UnicodeString(Key));
    +end;
    +
    +procedure TRegistry.ChangeKey(Value: HKey; const Path: String);
    +begin
    +  ChangeKey(Value, UnicodeString(Path));
    +end;
    +
    +
    +procedure TRegistry.PutData(const Name: UnicodeString; Buffer: Pointer;
       BufSize: Integer; RegData: TRegDataType);
     
     begin
    @@ -292,9 +363,15 @@
         Raise ERegistryException.CreateFmt(SRegSetDataFailed, [Name]);
     end;
     
    +procedure TRegistry.PutData(const Name: String; Buffer: Pointer;
    +  BufSize: Integer; RegData: TRegDataType);
    +begin
    +  PutData(UnicodeString(Name), Buffer, BufSize, RegData);
    +end;
     
    -function TRegistry.GetDataSize(const ValueName: string): Integer;
     
    +function TRegistry.GetDataSize(const ValueName: UnicodeString): Integer;
    +
     Var
       Info: TRegDataInfo;
     
    @@ -305,8 +382,13 @@
         Result := -1;
     end;
     
    -function TRegistry.GetDataType(const ValueName: string): TRegDataType;
    +function TRegistry.GetDataSize(const ValueName: String): Integer;
    +begin
    +  Result:=GetDataSize(UnicodeString(ValueName));
    +end;
     
    +function TRegistry.GetDataType(const ValueName: UnicodeString): TRegDataType;
    +
     Var
       Info: TRegDataInfo;
     
    @@ -315,6 +397,32 @@
       Result:=Info.RegData;
     end;
     
    +function TRegistry.GetDataType(const ValueName: String): TRegDataType;
    +begin
    +  Result:=GetDataType(UnicodeString(ValueName));
    +end;
    +
    +
    +function TRegistry.KeyExists(const Key: String): Boolean;
    +begin
    +  Result:=KeyExists(UnicodeString(Key));
    +end;
    +
    +function TRegistry.LoadKey(const Key, FileName: String): Boolean;
    +begin
    +  Result:=LoadKey(UnicodeString(Key), UnicodeString(FileName));
    +end;
    +
    +function TRegistry.OpenKey(const Key: String; CanCreate: Boolean): Boolean;
    +begin
    +  Result:=OpenKey(UnicodeString(Key), CanCreate);
    +end;
    +
    +function TRegistry.OpenKeyReadOnly(const Key: String): Boolean;
    +begin
    +  Result:=OpenKeyReadOnly(UnicodeString(Key));
    +end;
    +
     function TRegistry.HasSubKeys: Boolean;
     
     Var
    @@ -326,7 +434,7 @@
         Result:=(Info.NumSubKeys>0);
     end;
     
    -function TRegistry.ReadBinaryData(const Name: string; var Buffer; BufSize: Integer): Integer;
    +function TRegistry.ReadBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer): Integer;
     
     Var
       RegDataType: TRegDataType;
    @@ -337,8 +445,14 @@
         Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
     end;
     
    -function TRegistry.ReadInteger(const Name: string): Integer;
    +function TRegistry.ReadBinaryData(const Name: String; var Buffer;
    +  BufSize: Integer): Integer;
    +begin
    +  Result:=ReadBinaryData(UnicodeString(Name), Buffer, BufSize);
    +end;
     
    +function TRegistry.ReadInteger(const Name: UnicodeString): Integer;
    +
     Var
       RegDataType: TRegDataType;
     
    @@ -348,8 +462,13 @@
         Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
     end;
     
    -function TRegistry.ReadInt64(const Name: string): Int64;
    +function TRegistry.ReadInteger(const Name: String): Integer;
    +begin
    +  Result:=ReadInteger(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadInt64(const Name: UnicodeString): Int64;
    +
     Var
       RegDataType: TRegDataType;
     
    @@ -359,21 +478,36 @@
         Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
     end;
     
    -function TRegistry.ReadBool(const Name: string): Boolean;
    +function TRegistry.ReadInt64(const Name: String): Int64;
    +begin
    +  Result:=ReadInt64(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadBool(const Name: UnicodeString): Boolean;
    +
     begin
       Result:=ReadInteger(Name)<>0;
     end;
     
    -function TRegistry.ReadCurrency(const Name: string): Currency;
    +function TRegistry.ReadBool(const Name: String): Boolean;
    +begin
    +  Result:=ReadBool(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadCurrency(const Name: UnicodeString): Currency;
    +
     begin
       Result:=Default(Currency);
       ReadBinaryData(Name, Result, SizeOf(Currency));
     end;
     
    -function TRegistry.ReadDate(const Name: string): TDateTime;
    +function TRegistry.ReadCurrency(const Name: String): Currency;
    +begin
    +  Result:=ReadCurrency(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadDate(const Name: UnicodeString): TDateTime;
    +
     begin
       Result:=Default(TDateTime);
       ReadBinaryData(Name, Result, SizeOf(TDateTime));
    @@ -380,22 +514,37 @@
       Result:=Trunc(Result);
     end;
     
    -function TRegistry.ReadDateTime(const Name: string): TDateTime;
    +function TRegistry.ReadDate(const Name: String): TDateTime;
    +begin
    +  Result:=ReadDate(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadDateTime(const Name: UnicodeString): TDateTime;
    +
     begin
       Result:=Default(TDateTime);
       ReadBinaryData(Name, Result, SizeOf(TDateTime));
     end;
     
    -function TRegistry.ReadFloat(const Name: string): Double;
    +function TRegistry.ReadDateTime(const Name: String): TDateTime;
    +begin
    +  Result:=ReadDateTime(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadFloat(const Name: UnicodeString): Double;
    +
     begin
       Result:=Default(Double);
       ReadBinaryData(Name,Result,SizeOf(Double));
     end;
     
    -function TRegistry.ReadString(const Name: string): string;
    +function TRegistry.ReadFloat(const Name: String): Double;
    +begin
    +  Result:=ReadFloat(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadString(const Name: UnicodeString): string;
    +
     Var
       Info : TRegDataInfo;
       ReadDataSize: Integer;
    @@ -421,17 +570,22 @@
           if StringSizeIncludesNull and
              (u[Length(u)] = WideChar(0)) then
             SetLength(u,Length(u)-1);
    -      Result:=UTF8Encode(u);
    +      Result:=u;
         end;
       end;
     end;
     
    -procedure TRegistry.ReadStringList(const Name: string; AList: TStrings);
    +function TRegistry.ReadString(const Name: String): string;
    +begin
    +  Result:=ReadString(UnicodeString(Name));
    +end;
     
    +procedure TRegistry.ReadStringList(const Name: UnicodeString; AList: TStrings);
    +
     Var
       Info : TRegDataInfo;
    -  ReadDataSize: Integer;
    -  Data: string;
    +  ReadDataSize, i: Integer;
    +  Data: UnicodeString;
     
     begin
       AList.Clear;
    @@ -441,7 +595,7 @@
          If Not (Info.RegData in [rdMultiString]) then
            Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
          SetLength(Data,Info.DataSize);
    -     ReadDataSize := GetData(Name,PChar(Data),Info.DataSize,Info.RegData);
    +     ReadDataSize := GetData(Name,PWideChar(Data),Info.DataSize,Info.RegData) div SizeOf(WideChar);
          if ReadDataSize > 0 then
          begin
            // If the data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type,
    @@ -454,14 +608,19 @@
                Dec(ReadDataSize);
            end;
            SetLength(Data, ReadDataSize);
    -       Data := StringReplace(Data, #0, LineEnding, [rfReplaceAll]);
    +       Data := UnicodeStringReplace(Data, #0, AList.LineBreak, [rfReplaceAll]);
            AList.Text := Data;
          end
        end
     end;
     
    -function TRegistry.ReadTime(const Name: string): TDateTime;
    +procedure TRegistry.ReadStringList(const Name: String; AList: TStrings);
    +begin
    +  ReadStringList(UnicodeString(Name), AList);
    +end;
     
    +function TRegistry.ReadTime(const Name: UnicodeString): TDateTime;
    +
     begin
       Result:=Default(TDateTime);
       ReadBinaryData(Name, Result, SizeOf(TDateTime));
    @@ -468,81 +627,123 @@
       Result:=Frac(Result);
     end;
     
    -procedure TRegistry.WriteBinaryData(const Name: string; var Buffer; BufSize: Integer);
    +function TRegistry.ReadTime(const Name: String): TDateTime;
     begin
    +  Result:=ReadTime(UnicodeString(Name));
    +end;
    +
    +function TRegistry.RegistryConnect(const UNCName: String): Boolean;
    +begin
    +  Result:=RegistryConnect(UnicodeString(UNCName));
    +end;
    +
    +function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: String): Boolean;
    +begin
    +  Result:=ReplaceKey(UnicodeString(Key), UnicodeString(FileName), UnicodeString(BackUpFileName))
    +end;
    +
    +function TRegistry.RestoreKey(const Key, FileName: String): Boolean;
    +begin
    +  Result:=RestoreKey(UnicodeString(Key), UnicodeString(FileName));
    +end;
    +
    +function TRegistry.SaveKey(const Key, FileName: String): Boolean;
    +begin
    +  Result:=SaveKey(UnicodeString(Key), UnicodeString(FileName));
    +end;
    +
    +function TRegistry.UnLoadKey(const Key: String): Boolean;
    +begin
    +  Result:=UnloadKey(UnicodeString(Key));
    +end;
    +
    +function TRegistry.ValueExists(const Name: String): Boolean;
    +begin
    +  Result:=ValueExists(UnicodeString(Name));
    +end;
    +
    +procedure TRegistry.WriteBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer);
    +begin
       PutData(Name, @Buffer, BufSize, rdBinary);
     end;
     
    -procedure TRegistry.WriteBool(const Name: string; Value: Boolean);
    +procedure TRegistry.WriteBool(const Name: UnicodeString; Value: Boolean);
     
     begin
       WriteInteger(Name,Ord(Value));
     end;
     
    -procedure TRegistry.WriteCurrency(const Name: string; Value: Currency);
    +procedure TRegistry.WriteCurrency(const Name: UnicodeString; Value: Currency);
     begin
       WriteBinaryData(Name, Value, SizeOf(Currency));
     end;
     
    -procedure TRegistry.WriteDate(const Name: string; Value: TDateTime);
    +procedure TRegistry.WriteDate(const Name: UnicodeString; Value: TDateTime);
     begin
       WriteBinarydata(Name, Value, SizeOf(TDateTime));
     end;
     
    -procedure TRegistry.WriteTime(const Name: string; Value: TDateTime);
    +procedure TRegistry.WriteTime(const Name: UnicodeString; Value: TDateTime);
     begin
       WriteBinaryData(Name, Value, SizeOf(TDateTime));
     end;
     
    -procedure TRegistry.WriteDateTime(const Name: string; Value: TDateTime);
    +procedure TRegistry.WriteDateTime(const Name: UnicodeString; Value: TDateTime);
     begin
       WriteBinaryData(Name, Value, SizeOf(TDateTime));
     end;
     
    -procedure TRegistry.WriteExpandString(const Name, Value: string);
    -var
    -  u: UnicodeString;
    -
    +procedure TRegistry.WriteExpandString(const Name, Value: UnicodeString);
     begin
    -  u:=Value;
    -  PutData(Name, PWideChar(u), ByteLength(u), rdExpandString);
    +  PutData(Name, PWideChar(Value), ByteLength(Value), rdExpandString);
     end;
     
    -procedure TRegistry.WriteStringList(const Name: string; List: TStrings);
    +procedure TRegistry.WriteStringList(const Name: UnicodeString; List: TStrings);
     
     Var
    -  Data: string;
    -
    +  Data: UnicodeString;
    +  u: UnicodeString;
    +  i: Integer;
     begin
    -  Data := StringReplace(List.Text, LineEnding, #0, [rfReplaceAll]) + #0#0;
    -  PutData(Name, PChar(Data), Length(Data),rdMultiString);
    +  Data := '';
    +  //REG_MULTI_SZ data cannot contain empty strings
    +  for i := 0 to List.Count - 1 do
    +  begin
    +    u := List[i];
    +    if (u>'') then
    +    begin
    +      if (Data>'') then
    +        Data := Data + #0 + u
    +      else
    +        Data := Data + u;
    +    end;
    +  end;
    +  if StringSizeIncludesNull then
    +    Data := Data + #0#0;
    +  PutData(Name, PWideChar(Data), ByteLength(Data), rdMultiString);
     end;
     
    -procedure TRegistry.WriteFloat(const Name: string; Value: Double);
    +procedure TRegistry.WriteFloat(const Name: UnicodeString; Value: Double);
     begin
       WriteBinaryData(Name, Value, SizeOf(Double));
     end;
     
    -procedure TRegistry.WriteInteger(const Name: string; Value: Integer);
    +procedure TRegistry.WriteInteger(const Name: UnicodeString; Value: Integer);
     begin
       PutData(Name, @Value, SizeOf(Integer), rdInteger);
     end;
     
    -procedure TRegistry.WriteInt64(const Name: string; Value: Int64);
    +procedure TRegistry.WriteInt64(const Name: UnicodeString; Value: Int64);
     begin
       PutData(Name, @Value, SizeOf(Int64), rdInt64);
     end;
     
    -procedure TRegistry.WriteString(const Name, Value: string);
    -var
    -  u: UnicodeString;
    -
    +procedure TRegistry.WriteString(const Name, Value: UnicodeString);
     begin
    -  u:=Value;
    -  PutData(Name, PWideChar(u), ByteLength(u), rdString);
    +  PutData(Name, PWideChar(Value), ByteLength(Value), rdString);
     end;
     
    -procedure TRegistry.MoveKey(const OldName, NewName: string; Delete: Boolean);
    +procedure TRegistry.MoveKey(const OldName, NewName: UnicodeString; Delete: Boolean);
     begin
     
     end;
    Index: packages/fcl-registry/src/winreg.inc
    ===================================================================
    --- packages/fcl-registry/src/winreg.inc	(revision 41667)
    +++ packages/fcl-registry/src/winreg.inc	(working copy)
    @@ -1,7 +1,7 @@
     Const
       RegDataWords : Array [TRegDataType] of DWORD
                    = (REG_NONE,REG_SZ,REG_EXPAND_SZ,REG_BINARY,REG_DWORD,REG_DWORD_BIG_ENDIAN,
    -                  REG_LINK,REG_MULTI_SZ,REG_RESOURCE_LIST,REG_FULL_RESOURCE_DESCRIPTOR,REG_RESOURCE_REQUIREMENTS_LIST,REG_QWORD);
    +                  REG_LINK,REG_MULTI_SZ,REG_RESOURCE_LIST,REG_FULL_RESOURCE_DESCRIPTOR,REG_RESOURCE_REQUIREMENTS_LIST,11{REG_QWORD}); //*****UNDO THIS!
     
     type
       TWinRegData = record
    @@ -28,7 +28,7 @@
       Dispose(PWinRegData(FSysData));
     end;
     
    -Function PrepKey(Const S : String) : String;
    +Function PrepKey(Const S : UnicodeString) : UnicodeString;
     
     begin
       Result := S;
    @@ -36,7 +36,7 @@
         System.Delete(Result, 1, 1);
     end;
     
    -Function RelativeKey(Const S : String) : Boolean;
    +Function RelativeKey(Const S : UnicodeString) : Boolean;
     
     begin
       Result:=(S='') or (S[1]<>'\')
    @@ -43,7 +43,7 @@
     end;
     
     
    -function TRegistry.sysCreateKey(const Key: String): Boolean;
    +function TRegistry.sysCreateKey(Key: UnicodeString): Boolean;
     Var
       u: UnicodeString;
       Disposition: Dword;
    @@ -52,9 +52,9 @@
     
     begin
       SecurityAttributes := Nil;
    -  u:=PrepKey(Key);
    +  Key:=PrepKey(Key);
       FLastError:=RegCreateKeyExW(GetBaseKey(RelativeKey(Key)),
    -                              PWideChar(u),
    +                              PWideChar(Key),
                                   0,
                                   '',
                                   REG_OPTION_NON_VOLATILE,
    @@ -66,7 +66,7 @@
       RegCloseKey(Handle);
     end;
     
    -function TRegistry.DeleteKey(const Key: String): Boolean;
    +function TRegistry.DeleteKey(const Key: UnicodeString): Boolean;
     
     Var
       u: UnicodeString;
    @@ -76,21 +76,21 @@
       Result:=FLastError=ERROR_SUCCESS;
     end;
     
    -function TRegistry.DeleteValue(const Name: String): Boolean;
    +
    +function TRegistry.DeleteValue(const Name: UnicodeString): Boolean;
     begin
    -  FLastError:= RegDeleteValueW(fCurrentKey, PWideChar(UnicodeString(Name)));
    +  FLastError:= RegDeleteValueW(fCurrentKey, PWideChar(Name));
       Result:=FLastError=ERROR_SUCCESS;
     end;
     
    -function TRegistry.SysGetData(const Name: String; Buffer: Pointer;
    +
    +function TRegistry.SysGetData(const Name: UnicodeString; Buffer: Pointer;
               BufSize: Integer; Out RegData: TRegDataType): Integer;
     Var
    -  u: UnicodeString;
       RD : DWord;
     
     begin
    -  u := Name;
    -  FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(u),Nil,
    +  FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(Name),Nil,
                           @RD,Buffer,lpdword(@BufSize));
       if (FLastError<>ERROR_SUCCESS) Then
         Result:=-1
    @@ -103,17 +103,15 @@
         end;
     end;
     
    -function TRegistry.GetDataInfo(const ValueName: String; out Value: TRegDataInfo): Boolean;
    +function TRegistry.GetDataInfo(const ValueName: UnicodeString; out Value: TRegDataInfo): Boolean;
     
     Var
    -  u: UnicodeString;
       RD : DWord;
     
     begin
    -  u:=ValueName;
       With Value do
         begin
    -    FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(u),Nil,lpdword(@RegData),Nil,lpdword(@DataSize));
    +    FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(ValueName),Nil,lpdword(@RegData),Nil,lpdword(@DataSize));
         Result:=FLastError=ERROR_SUCCESS;
         if Result then
           begin
    @@ -131,24 +129,18 @@
     end;
     
     
    -function TRegistry.GetKey(const Key: String): HKEY;
    +function TRegistry.GetKey(Key: UnicodeString): HKEY;
     var
    -  S : string;
    -{$ifndef WinCE}
    -  u : UnicodeString;
    -{$endif}
       Rel : Boolean;
     begin
       Result:=0;
    -  S:=Key;
    -  Rel:=RelativeKey(S);
    +  Rel:=RelativeKey(Key);
       if not(Rel) then
    -    Delete(S,1,1);
    +    Delete(Key,1,1);
     {$ifdef WinCE}
    -  FLastError:=RegOpenKeyEx(GetBaseKey(Rel),PWideChar(WideString(S)),0,FAccess,Result);
    +  FLastError:=RegOpenKeyEx(GetBaseKey(Rel),PWideChar(Key),0,FAccess,Result);
     {$else WinCE}
    -  u:=UnicodeString(S);
    -  FLastError:=RegOpenKeyExW(GetBaseKey(Rel),PWideChar(u),0,FAccess,Result);
    +  FLastError:=RegOpenKeyExW(GetBaseKey(Rel),PWideChar(Key),0,FAccess,Result);
     {$endif WinCE}
     end;
     
    @@ -174,7 +166,7 @@
     end;
     
     
    -function TRegistry.KeyExists(const Key: string): Boolean;
    +function TRegistry.KeyExists(const Key: UnicodeString): Boolean;
     var
       KeyHandle : HKEY;
       OldAccess : LONG;
    @@ -196,20 +188,20 @@
     end;
     
     
    -function TRegistry.LoadKey(const Key, FileName: string): Boolean;
    +function TRegistry.LoadKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
     
    -function TRegistry.OpenKey(const Key: string; CanCreate: Boolean): Boolean;
     
    +function TRegistry.OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
    +
     Var
    -  u: UnicodeString;
    +  u, S: UnicodeString;
       Handle: HKEY;
       Disposition: Integer;
       SecurityAttributes: Pointer; //LPSECURITY_ATTRIBUTES;
    -  S: string;
     begin
       SecurityAttributes := Nil;
       u:=PrepKey(Key);
    @@ -232,13 +224,14 @@
         if RelativeKey(Key) then
           S:=CurrentPath + Key
         else
    -      S:=UTF8Encode(u);
    +      S:=u;
         ChangeKey(Handle, S);
       end;
     end;
     
    -function TRegistry.OpenKeyReadOnly(const Key: string): Boolean;
     
    +function TRegistry.OpenKeyReadOnly(const Key: UnicodeString): Boolean;
    +
     Var
       OldAccess: LongWord;
     begin
    @@ -251,7 +244,8 @@
       end;
     end;
     
    -function TRegistry.RegistryConnect(const UNCName: string): Boolean;
    +
    +function TRegistry.RegistryConnect(const UNCName: UnicodeString): Boolean;
     {$ifndef WinCE}
     var
       newroot: HKEY;
    @@ -260,7 +254,7 @@
     {$ifdef WinCE}
       Result:=False;
     {$else}
    -  FLastError:=RegConnectRegistryW(PWideChar(UnicodeString(UNCName)),RootKey,newroot);
    +  FLastError:=RegConnectRegistryW(PWideChar(UNCName),RootKey,newroot);
       Result:=FLastError=ERROR_SUCCESS;
       if Result then begin
         RootKey:=newroot;
    @@ -269,28 +263,33 @@
     {$endif}
     end;
     
    -function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
    +
    +function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.RestoreKey(const Key, FileName: string): Boolean;
    +
    +function TRegistry.RestoreKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.SaveKey(const Key, FileName: string): Boolean;
    +
    +function TRegistry.SaveKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.UnLoadKey(const Key: string): Boolean;
    +
    +function TRegistry.UnLoadKey(const Key: UnicodeString): Boolean;
     begin
       Result := false;
     end;
     
    -function TRegistry.ValueExists(const Name: string): Boolean;
     
    +function TRegistry.ValueExists(const Name: UnicodeString): Boolean;
    +
     var
       Info : TRegDataInfo;
     
    @@ -298,6 +297,7 @@
       Result:=GetDataInfo(Name,Info);
     end;
     
    +
     procedure TRegistry.CloseKey;
     begin
       If (CurrentKey<>0) then
    @@ -316,7 +316,7 @@
       RegCloseKey(key);
     end;
     
    -procedure TRegistry.ChangeKey(Value: HKey; const Path: String);
    +procedure TRegistry.ChangeKey(Value: HKey; const Path: UnicodeString);
     begin
       CloseKey;
       FCurrentKey:=Value;
    @@ -323,6 +323,7 @@
       FCurrentPath:=Path;
     end;
     
    +
     procedure TRegistry.GetKeyNames(Strings: TStrings);
     
     var
    @@ -410,12 +411,11 @@
     end;
     
     
    -Function TRegistry.SysPutData(const Name: string; Buffer: Pointer;
    +Function TRegistry.SysPutData(const Name: UnicodeString; Buffer: Pointer;
       BufSize: Integer; RegData: TRegDataType) : Boolean;
     
     
     Var
    -  u: UnicodeString;
       RegDataType: DWORD;
       B : Pchar;
       S : String;
    @@ -422,12 +422,11 @@
     
     begin
       RegDataType:=RegDataWords[RegData];
    -  u:=UnicodeString(Name);
    -  FLastError:=RegSetValueExW(fCurrentKey,PWideChar(u),0,RegDataType,Buffer,BufSize);
    +  FLastError:=RegSetValueExW(fCurrentKey,PWideChar(Name),0,RegDataType,Buffer,BufSize);
       Result:=FLastError=ERROR_SUCCESS;
     end;
     
    -procedure TRegistry.RenameValue(const OldName, NewName: string);
    +procedure TRegistry.RenameValue(const OldName, NewName: UnicodeString);
     
     var
       L: Integer;
    Index: packages/fcl-registry/src/xmlreg.pp
    ===================================================================
    --- packages/fcl-registry/src/xmlreg.pp	(revision 41667)
    +++ packages/fcl-registry/src/xmlreg.pp	(working copy)
    @@ -32,54 +32,54 @@
       Private
         FAutoFlush,
         FDirty : Boolean;
    -    FFileName : String;
    -    FRootKey : String;
    +    FFileName : UnicodeString;
    +    FRootKey : UnicodeString;
         FDocument : TXMLDocument;
         FCurrentElement : TDomElement;
    -    FCurrentKey : String;
    -    Procedure SetFileName(Value : String);
    +    FCurrentKey : UnicodeString;
    +    Procedure SetFileName(Value : UnicodeString);
       Protected
    -    function DoGetValueData(Name: String; out DataType: TDataType; Var Data; Var DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
    -    function DoSetValueData(Name: String; DataType: TDataType; const Data; DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
    +    function DoGetValueData(Name: UnicodeString; out DataType: TDataType; Var Data; Var DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
    +    function DoSetValueData(Name: UnicodeString; DataType: TDataType; const Data; DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
         Procedure LoadFromStream(S : TStream);
    -    Function  NormalizeKey(KeyPath : String) : String;
    +    Function  NormalizeKey(KeyPath : UnicodeString) : UnicodeString;
         Procedure CreateEmptyDoc;
    -    Function  FindKey (S : String) : TDomElement;
    -    Function  FindSubKey (S : String; N : TDomElement) : TDomElement;
    -    Function  CreateSubKey (S : String; N : TDomElement) : TDomElement;
    -    Function  FindValueKey (S : String) : TDomElement;
    -    Function  CreateValueKey (S : String) : TDomElement;
    +    Function  FindKey (S : UnicodeString) : TDomElement;
    +    Function  FindSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
    +    Function  CreateSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
    +    Function  FindValueKey (S : UnicodeString) : TDomElement;
    +    Function  CreateValueKey (S : UnicodeString) : TDomElement;
         Function  BufToHex(Const Buf; Len : Integer) : String;
    -    Function  hexToBuf(Const Str : String; Var Buf; Var Len : Integer ) : Integer;
    +    Function  HexToBuf(Const Str : UnicodeString; Var Buf; Var Len : Integer ) : Integer;
         Procedure MaybeFlush;
         Property  Document : TXMLDocument Read FDocument;
         Property  Dirty : Boolean Read FDirty write FDirty;
       Public
    -    Constructor Create(AFileName : String);
    +    Constructor Create(AFileName : UnicodeString);
         Destructor  Destroy;override;
    -    Function  SetKey(KeyPath : String; AllowCreate : Boolean) : Boolean ;
    -    Procedure SetRootKey(Value : String);
    -    Function  DeleteKey(KeyPath : String) : Boolean;
    -    Function  CreateKey(KeyPath : String) : Boolean;
    -    Function  GetValueSize(Name : String) : Integer;
    -    Function  GetValueType(Name : String) : TDataType;
    -    Function  GetValueInfo(Name : String; Out Info : TDataInfo; AsUnicode : Boolean = False) : Boolean;
    +    Function  SetKey(KeyPath : UnicodeString; AllowCreate : Boolean) : Boolean ;
    +    Procedure SetRootKey(Value : UnicodeString);
    +    Function  DeleteKey(KeyPath : UnicodeString) : Boolean;
    +    Function  CreateKey(KeyPath : UnicodeString) : Boolean;
    +    Function  GetValueSize(Name : UnicodeString) : Integer;
    +    Function  GetValueType(Name : UnicodeString) : TDataType;
    +    Function  GetValueInfo(Name : UnicodeString; Out Info : TDataInfo; AsUnicode : Boolean = False) : Boolean;
         Function  GetKeyInfo(Out Info : TKeyInfo) : Boolean;
         Function  EnumSubKeys(List : TStrings) : Integer;
         Function  EnumValues(List : TStrings) : Integer;
    -    Function  KeyExists(KeyPath : String) : Boolean;
    -    Function  ValueExists(ValueName : String) : Boolean;
    -    Function  RenameValue(Const OldName,NewName : String) : Boolean;
    -    Function  DeleteValue(S : String) : Boolean;
    +    Function  KeyExists(KeyPath : UnicodeString) : Boolean;
    +    Function  ValueExists(ValueName : UnicodeString) : Boolean;
    +    Function  RenameValue(Const OldName,NewName : UnicodeString) : Boolean;
    +    Function  DeleteValue(S : UnicodeString) : Boolean;
         Procedure Flush;
         Procedure Load;
    -    Function GetValueData(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
    -    Function SetValueData(Name : String; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
    +    Function GetValueData(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
    +    Function SetValueData(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
         // These interpret the Data buffer as unicode data
    -    Function GetValueDataUnicode(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
    -    Function SetValueDataUnicode(Name : String; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
    -    Property FileName : String Read FFileName Write SetFileName;
    -    Property RootKey : String Read FRootKey Write SetRootkey;
    +    Function GetValueDataUnicode(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
    +    Function SetValueDataUnicode(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
    +    Property FileName : UnicodeString Read FFileName Write SetFileName;
    +    Property RootKey : UnicodeString Read FRootKey Write SetRootkey;
         Property AutoFlush : Boolean Read FAutoFlush Write FAutoFlush;
       end;
     
    @@ -96,7 +96,7 @@
     Implementation
     
     
    -Constructor TXmlRegistry.Create(AFileName : String);
    +Constructor TXmlRegistry.Create(AFileName : UnicodeString);
     
     begin
       FFileName:=AFileName;
    @@ -113,7 +113,7 @@
       inherited Destroy;
     end;
     
    -Procedure TXmlRegistry.SetFileName(Value : String);
    +Procedure TXmlRegistry.SetFileName(Value : UnicodeString);
     
     begin
       If Value<>FFileName then
    @@ -143,13 +143,13 @@
       end;
     end;
     
    -Function TXmlRegistry.NormalizeKey(KeyPath : String) : String;
    +Function TXmlRegistry.NormalizeKey(KeyPath : UnicodeString) : UnicodeString;
     
     Var
       L : Integer;
     
     begin
    -  Result:=StringReplace(KeyPath,'\','/',[rfReplaceAll]);
    +  Result:=UnicodeStringReplace(KeyPath,'\','/',[rfReplaceAll]);
       L:=Length(Result);
       If (L>0) and (Result[L]<>'/') then
         Result:=Result+'/';
    @@ -157,10 +157,10 @@
         Result:='/' + Result;
     end;
     
    -Function TXmlRegistry.SetKey(KeyPath : String; AllowCreate : Boolean) : boolean;
    +Function TXmlRegistry.SetKey(KeyPath : UnicodeString; AllowCreate : Boolean) : boolean;
     
     Var
    -  SubKey,ResultKey : String;
    +  SubKey,ResultKey : UnicodeString;
       P : Integer;
       Node,Node2 : TDomElement;
     
    @@ -218,7 +218,7 @@
       MaybeFlush;
     end;
     
    -Procedure TXmlRegistry.SetRootKey(Value : String);
    +Procedure TXmlRegistry.SetRootKey(Value : UnicodeString);
     
     begin
       FRootKey:=NormalizeKey(Value);
    @@ -228,7 +228,7 @@
       FCurrentElement:=Nil;
     end;
     
    -Function TXmlRegistry.DeleteKey(KeyPath : String) : Boolean;
    +Function TXmlRegistry.DeleteKey(KeyPath : UnicodeString) : Boolean;
     
     Var
       N : TDomElement;
    @@ -244,10 +244,10 @@
        end;
     end;
     
    -Function TXmlRegistry.CreateKey(KeyPath : String) : Boolean;
    +Function TXmlRegistry.CreateKey(KeyPath : UnicodeString) : Boolean;
     
     Var
    -  SubKey : String;
    +  SubKey : UnicodeString;
       P : Integer;
       Node,Node2 : TDomElement;
     
    @@ -290,7 +290,7 @@
       MaybeFlush;
     end;
     
    -Function TXmlRegistry.DoGetValueData(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer; IsUnicode : Boolean) : Boolean;
    +Function TXmlRegistry.DoGetValueData(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer; IsUnicode : Boolean) : Boolean;
     
     Type
       PCardinal = ^Cardinal;
    @@ -305,17 +305,22 @@
       D : DWord;
       
     begin
    +  writeln('TXmlRegistry.DoGetValueData: Name=',Name,' IsUnicode=',IsUnicode);
       Node:=FindValueKey(Name);
       Result:=Node<>Nil;
       If Result then
         begin
    +    writeln('TXmlRegistry.DoGetValueData: Node<>nil');
         DataNode:=Node.FirstChild;
         HasData:=Assigned(DataNode) and (DataNode.NodeType=TEXT_NODE);
    +    writeln('TXmlRegistry.DoGetValueData: HasData=',hasdata);
         ND:=StrToIntDef(Node[Stype],0);
    +    writeln('TXmlRegistry.DoGetValueData: ND=',ND);
         Result:=ND<=Ord(High(TDataType));
         If Result then
           begin
           DataType:=TDataType(ND);
    +      writeln('TXmlRegistry.DoGetValueData: DataType=',DataType);
           NS:=0; // Initialize, for optional nodes.
           Case DataType of
             dtDWORD : begin   // DataNode is required
    @@ -329,7 +334,7 @@
                          begin
                          if not IsUnicode then
                            begin
    -                       S:=UTF8Encode(DataNode.NodeValue); // Convert to ansistring
    +                       S:=DataNode.NodeValue; // Convert to ansistring
                            NS:=Length(S);
                            Result:=(DataSize>=NS);
                            if Result then
    @@ -350,8 +355,10 @@
                        if HasData then
                          begin
                          BL:=Length(DataNode.NodeValue);
    +                     writeln('TXmlRegistry.DoGetValueData: BL=',BL);
                          NS:=BL div 2;
                          Result:=DataSize>=NS;
    +                     writeln('TXmlRegistry.DoGetValueData: Result=',Result);
                          If Result then
                            // No need to check for -1, We checked NS before calling.
                            NS:=HexToBuf(DataNode.NodeValue,Data,BL);
    @@ -363,7 +370,7 @@
         end;
     end;
     
    -Function TXmlRegistry.DoSetValueData(Name : String; DataType : TDataType; Const Data; DataSize : Integer; IsUnicode : Boolean) : Boolean;
    +Function TXmlRegistry.DoSetValueData(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer; IsUnicode : Boolean) : Boolean;
     
     Type
       PCardinal = ^Cardinal;
    @@ -390,7 +397,7 @@
                        SW:=UnicodeString(PUnicodeChar(@Data))
                      else
                        SW:=UnicodeString(PAnsiChar(@Data));
    -                   //S:=UTF8Encode(SW);
    +                   //S:=SW;
                      end;
           dtBinary : SW:=BufToHex(Data,DataSize);
           dtStrings : SW:=BufToHex(Data,DataSize);
    @@ -416,29 +423,29 @@
         end;
     end;
     
    -Function TXmlRegistry.SetValueData(Name : String; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
    +Function TXmlRegistry.SetValueData(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
     
     begin
       Result:=DoSetValueData(Name,DataType,Data,DataSize,False);
     end;
     
    -Function TXmlRegistry.GetValueData(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
    +Function TXmlRegistry.GetValueData(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
     
     begin
       Result:=DoGetValueData(Name,DataType,Data,DataSize,False);
     end;
     
    -function TXmlRegistry.GetValueDataUnicode(Name: String; out DataType: TDataType; Var Data; Var DataSize: Integer): Boolean;
    +function TXmlRegistry.GetValueDataUnicode(Name: UnicodeString; out DataType: TDataType; Var Data; Var DataSize: Integer): Boolean;
     begin
       Result:=DoGetValueData(Name,DataType,Data,DataSize,True);
     end;
     
    -function TXmlRegistry.SetValueDataUnicode(Name: String; DataType: TDataType; const Data; DataSize: Integer): Boolean;
    +function TXmlRegistry.SetValueDataUnicode(Name: UnicodeString; DataType: TDataType; const Data; DataSize: Integer): Boolean;
     begin
       Result:=DoSetValueData(Name,DataType,Data,DataSize,True)
     end;
     
    -Function TXmlRegistry.FindSubKey (S : String; N : TDomElement) : TDomElement;
    +Function TXmlRegistry.FindSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
     
     Var
       Node : TDOMNode;
    @@ -451,7 +458,7 @@
         While (Result=Nil) and (Assigned(Node)) do
           begin
           If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SKey) then
    -        If CompareText(TDomElement(Node)[SName],S)=0 then
    +        If UnicodeCompareText(TDomElement(Node)[SName],S)=0 then
               Result:=TDomElement(Node);
           Node:=Node.NextSibling;
           end;
    @@ -458,7 +465,7 @@
         end;
     end;
     
    -Function TXmlRegistry.CreateSubKey (S : String; N : TDomElement) : TDomElement;
    +Function TXmlRegistry.CreateSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
     
     begin
       Result:=FDocument.CreateElement(SKey);
    @@ -468,7 +475,7 @@
       FDirty:=True;
     end;
     
    -Function  TXmlRegistry.FindValueKey (S : String) : TDomElement;
    +Function  TXmlRegistry.FindValueKey (S : UnicodeString) : TDomElement;
     
     Var
       Node : TDOMNode;
    @@ -481,7 +488,7 @@
         While (Result=Nil) and (Assigned(Node)) do
           begin
           If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SValue) then
    -        If CompareText(TDomElement(Node)[SName],S)=0 then
    +        If UnicodeCompareText(TDomElement(Node)[SName],S)=0 then
               Result:=TDomElement(Node);
           Node:=Node.NextSibling;
           end;
    @@ -488,7 +495,7 @@
         end;
     end;
     
    -Function  TXmlRegistry.CreateValueKey (S : String) : TDomElement;
    +Function  TXmlRegistry.CreateValueKey (S : UnicodeString) : TDomElement;
     
     begin
       If Assigned(FCurrentElement) then
    @@ -581,7 +588,7 @@
         end;
     end;
     
    -Function TXMLRegistry.hexToBuf(Const Str : String; Var Buf; Var Len : Integer ) : Integer;
    +Function TXMLRegistry.HexToBuf(Const Str : UnicodeString; Var Buf; Var Len : Integer ) : Integer;
     
     Var
       NLeN,I : Integer;
    @@ -591,17 +598,22 @@
       Code : Integer;
     
     begin
    +  writeln('TXMLRegistry.HexToBuf A: Str=',Str,', Len=',Len);
       Result:=0;
       P:=@Buf;
    +  writeln('TXMLRegistry.HexToBuf B: (p=nil)=',p=nil);
       NLen:= Length(Str) div 2;
    +  writeln('TXMLRegistry.HexToBuf C: NLen=',NLen,', SizeOf(TDateTime)=',SizeOf(TDateTime));
       If (NLen>Len) then
         begin
         Len:=NLen;
         Exit(-1);
         end;
    -  For I:=0 to Len-1 do
    +  For I:=0 to NLen-1 do
         begin
    +    write('TXMLRegistry.HexToBuf: i=',i);
         S:='$'+Copy(Str,(I*2)+1,2);
    +    writeln('TXMLRegistry.HexToBuf: S=',S);
         Val(S,B,Code);
         If Code<>0 then
           begin
    @@ -612,7 +624,7 @@
         end;
     end;
     
    -Function TXMLRegistry.DeleteValue(S : String) : Boolean;
    +Function TXMLRegistry.DeleteValue(S : UnicodeString) : Boolean;
     
     Var
       N : TDomElement;
    @@ -628,31 +640,31 @@
         end;
     end;
     
    -Function TXMLRegistry.GetValueSize(Name : String) : Integer;
    +Function TXMLRegistry.GetValueSize(Name : UnicodeString) : Integer;
     
     Var
       Info : TDataInfo;
     
     begin
    -  If GetValueInfo(Name,Info) then
    +  If GetValueInfo(Name,Info,True) then
         Result:=Info.DataSize
       else
         Result:=-1;
     end;
     
    -Function TXMLRegistry.GetValueType(Name : String) : TDataType;
    +Function TXMLRegistry.GetValueType(Name : UnicodeString) : TDataType;
     
     Var
       Info : TDataInfo;
     
     begin
    -  If GetValueInfo(Name,Info) then
    +  If GetValueInfo(Name,Info,True) then
         Result:=Info.DataType
       else
         Result:=dtUnknown;
     end;
     
    -function TXmlRegistry.GetValueInfo(Name: String; out Info: TDataInfo; AsUnicode: Boolean): Boolean;
    +function TXmlRegistry.GetValueInfo(Name: UnicodeString; out Info: TDataInfo; AsUnicode: Boolean): Boolean;
     
     Var
       N  : TDomElement;
    @@ -671,7 +683,7 @@
             L:=Length(DN.NodeValue)*SizeOf(UnicodeChar)
           else
             begin
    -        S := UTF8Encode(DN.NodeValue);
    +        S := DN.NodeValue;
             L:=Length(S);
             end
           end
    @@ -727,7 +739,7 @@
                   Case TDataType(StrToIntDef(TDomElement(Node)[SType],0)) of
                     dtUnknown : L:=0;
                     dtDWord   : L:=4;
    -                DtString  : L:=Length(UTF8Encode(DataNode.NodeValue));
    +                DtString  : L:=Length(String(DataNode.NodeValue));
                     dtBinary  : L:=Length(DataNode.NodeValue) div 2;
                   end
                 else
    @@ -782,13 +794,13 @@
         end;
     end;
     
    -Function TXMLRegistry.KeyExists(KeyPath : String) : Boolean;
    +Function TXMLRegistry.KeyExists(KeyPath : UnicodeString) : Boolean;
     
     begin
       Result:=FindKey(KeyPath)<>Nil;
     end;
     
    -Function TXMLRegistry.RenameValue(Const OldName,NewName : String) : Boolean;
    +Function TXMLRegistry.RenameValue(Const OldName,NewName : UnicodeString) : Boolean;
     
     Var
       N : TDomElement;
    @@ -804,10 +816,10 @@
         end;
     end;
     
    -Function TXMLRegistry.FindKey (S : String) : TDomElement;
    +Function TXMLRegistry.FindKey (S : UnicodeString) : TDomElement;
     
     Var
    -  SubKey : String;
    +  SubKey : UnicodeString;
       P : Integer;
       Node : TDomElement;
     
    @@ -840,7 +852,7 @@
       Until (Result=Nil) or (Length(S)=0);
     end;
     
    -Function  TXmlRegistry.ValueExists(ValueName : String) : Boolean;
    +Function  TXmlRegistry.ValueExists(ValueName : UnicodeString) : Boolean;
     
     begin
       Result:=FindValueKey(ValueName)<>Nil;
    Index: packages/fcl-registry/src/xregreg.inc
    ===================================================================
    --- packages/fcl-registry/src/xregreg.inc	(revision 41667)
    +++ packages/fcl-registry/src/xregreg.inc	(working copy)
    @@ -47,7 +47,7 @@
         Class Var XMLRegistryCache: Tlist;
         Class procedure FreeXMLRegistryCache;
       public
    -    constructor Create(AFileName : String);
    +    constructor Create(AFileName : UnicodeString);
         Class Function GetXMLRegistry(aFileName: string): TXMLRegistry;
         Class Procedure FreeXMLRegistry(XMLRegistry: TXMLRegistry);
         procedure IncRefCount;
    @@ -97,7 +97,7 @@
     
     { TXMLRegistryInstance }
     
    -constructor TXMLRegistryInstance.Create(AFileName: String);
    +constructor TXMLRegistryInstance.Create(AFileName: UnicodeString);
     begin
       inherited;
       FRefCount := 1;
    @@ -117,6 +117,7 @@
     var s : string;
     begin
       s:=includetrailingpathdelimiter(GetAppConfigDir(GlobalXMLFile));
    +s:='.\';//**********UNDO THIS
       ForceDirectories(s);
       FSysData:=TXMLRegistryInstance.GetXMLRegistry(s+XFileName);
       TXmlRegistry(FSysData).AutoFlush:=False;
    @@ -130,24 +131,24 @@
       TXMLRegistryInstance.FreeXMLRegistry(TXMLRegistry(FSysData));
     end;
     
    -function TRegistry.SysCreateKey(const Key: String): Boolean;
    +function TRegistry.SysCreateKey(Key: UnicodeString): Boolean;
     
     begin
       Result:=TXmlRegistry(FSysData).CreateKey(Key);
     end;
     
    -function TRegistry.DeleteKey(const Key: string): Boolean;
    +function TRegistry.DeleteKey(const Key: UnicodeString): Boolean;
     
     begin
       Result:=TXMLRegistry(FSysData).DeleteKey(Key);
     end;
     
    -function TRegistry.DeleteValue(const Name: string): Boolean;
    +function TRegistry.DeleteValue(const Name: UnicodeString): Boolean;
     begin
       Result:=TXmlRegistry(FSysData).DeleteValue(Name);
     end;
     
    -function TRegistry.SysGetData(const Name: String; Buffer: Pointer;
    +function TRegistry.SysGetData(const Name: UnicodeString; Buffer: Pointer;
               BufSize: Integer; Out RegData: TRegDataType): Integer;
     
     Var
    @@ -160,7 +161,7 @@
         Result:=-1;
     end;
     
    -function TRegistry.GetDataInfo(const ValueName: string; out Value: TRegDataInfo): Boolean;
    +function TRegistry.GetDataInfo(const ValueName: UnicodeString; out Value: TRegDataInfo): Boolean;
     
     Var
       Info : TDataInfo;
    @@ -181,7 +182,7 @@
           end;
     end;
     
    -function TRegistry.GetKey(const Key: string): HKEY;
    +function TRegistry.GetKey(Key: UnicodeString): HKEY;
     begin
       Result := 0;
     end;
    @@ -205,17 +206,17 @@
           end;
     end;
     
    -function TRegistry.KeyExists(const Key: string): Boolean;
    +function TRegistry.KeyExists(const Key: UnicodeString): Boolean;
     begin
       Result:=TXmlRegistry(FSysData).KeyExists(Key);
     end;
     
    -function TRegistry.LoadKey(const Key, FileName: string): Boolean;
    +function TRegistry.LoadKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.OpenKey(const Key: string; CanCreate: Boolean): Boolean;
    +function TRegistry.OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
     
     begin
       Result:=TXmlRegistry(FSysData).SetKey(Key,CanCreate);
    @@ -222,43 +223,43 @@
       FCurrentKey:=1;
     end;
     
    -function TRegistry.OpenKeyReadOnly(const Key: string): Boolean;
    +function TRegistry.OpenKeyReadOnly(const Key: UnicodeString): Boolean;
     
     begin
       Result:=TXmlRegistry(FSysData).SetKey(Key,False);
     end;
     
    -function TRegistry.RegistryConnect(const UNCName: string): Boolean;
    +function TRegistry.RegistryConnect(const UNCName: UnicodeString): Boolean;
     begin
       Result := True;
     end;
     
    -function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
    +function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.RestoreKey(const Key, FileName: string): Boolean;
    +function TRegistry.RestoreKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.SaveKey(const Key, FileName: string): Boolean;
    +function TRegistry.SaveKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.UnLoadKey(const Key: string): Boolean;
    +function TRegistry.UnLoadKey(const Key: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.ValueExists(const Name: string): Boolean;
    +function TRegistry.ValueExists(const Name: UnicodeString): Boolean;
     begin
       Result := TXmlRegistry(FSysData).ValueExists(Name);
     end;
     
    -procedure TRegistry.ChangeKey(Value: HKey; const Path: string);
    +procedure TRegistry.ChangeKey(Value: HKey; const Path: UnicodeString);
     begin
     
     end;
    @@ -274,7 +275,7 @@
     end;
     
     
    -function TRegistry.SysPutData(const Name: string; Buffer: Pointer;
    +function TRegistry.SysPutData(const Name: UnicodeString; Buffer: Pointer;
       BufSize: Integer; RegData: TRegDataType): Boolean;
     
     Var
    @@ -285,7 +286,7 @@
       Result:=TXMLRegistry(FSysData).SetValueDataUnicode(Name,DataType,Buffer^,BufSize);
     end;
     
    -procedure TRegistry.RenameValue(const OldName, NewName: string);
    +procedure TRegistry.RenameValue(const OldName, NewName: UnicodeString);
     begin
       TXMLRegistry(FSysData).RenameValue(OldName,NewName);
     end;
    
  • registry.unicode.part3.diff (60,913 bytes)
    Index: packages/fcl-registry/src/regdef.inc
    ===================================================================
    --- packages/fcl-registry/src/regdef.inc	(revision 41667)
    +++ packages/fcl-registry/src/regdef.inc	(working copy)
    @@ -2,7 +2,7 @@
       HKEY = THandle;
       PHKEY = ^HKEY;
       
    -{$ifdef windows}
    +{$if defined(windows) and not defined(XMLREG)}
     
     { Direct mapping to constants in Windows unit }
     
    Index: packages/fcl-registry/src/registry.pp
    ===================================================================
    --- packages/fcl-registry/src/registry.pp	(revision 41667)
    +++ packages/fcl-registry/src/registry.pp	(working copy)
    @@ -1,4 +1,5 @@
     Unit Registry;
    +Unit uRegistry;
     
     {$mode objfpc}
     {$H+}
    @@ -39,6 +40,8 @@
         DataSize: Integer;
       end;
     
    +  TUnicodeStringArray = Array of UnicodeString;
    +
     { ---------------------------------------------------------------------
         TRegistry
       ---------------------------------------------------------------------}
    @@ -54,22 +57,29 @@
         fCurrentKey: HKEY;
         fRootKey: HKEY;
         fLazyWrite: Boolean;
    -    fCurrentPath: string;
    +    fCurrentPath: UnicodeString;
         function GetLastErrorMsg: string;
    +    function RegMultiSzDataToUnicodeStringArray(U: UnicodeString): TUnicodeStringArray;
         procedure SetRootKey(Value: HKEY);
         Procedure SysRegCreate;
         Procedure SysRegFree;
    -    Function  SysGetData(const Name: String; Buffer: Pointer; BufSize: Integer; Out RegData: TRegDataType): Integer;
    -    Function  SysPutData(const Name: string; Buffer: Pointer; BufSize: Integer; RegData: TRegDataType) : Boolean;
    -    Function  SysCreateKey(const Key: String): Boolean;
    +    Function  SysGetData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; Out RegData: TRegDataType): Integer;
    +    Function  SysPutData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; RegData: TRegDataType) : Boolean;
    +    Function  SysCreateKey(Key: UnicodeString): Boolean;
       protected
         function GetBaseKey(Relative: Boolean): HKey;
    -    function GetData(const Name: string; Buffer: Pointer;
    +    function GetData(const Name: UnicodeString; Buffer: Pointer;
                       BufSize: Integer; Out RegData: TRegDataType): Integer;
    -    function GetKey(const Key: string): HKEY;
    -    procedure ChangeKey(Value: HKey; const Path: string);
    -    procedure PutData(const Name: string; Buffer: Pointer;
    +    function GetData(const Name: String; Buffer: Pointer;
    +                  BufSize: Integer; Out RegData: TRegDataType): Integer;
    +    function GetKey(Key: UnicodeString): HKEY;
    +    function GetKey(Key: String): HKEY;
    +    procedure ChangeKey(Value: HKey; const Path: UnicodeString);
    +    procedure ChangeKey(Value: HKey; const Path: String);
    +    procedure PutData(const Name: UnicodeString; Buffer: Pointer;
                       BufSize: Integer; RegData: TRegDataType);
    +    procedure PutData(const Name: String; Buffer: Pointer;
    +                  BufSize: Integer; RegData: TRegDataType);
         procedure SetCurrentKey(Value: HKEY);
       public
         constructor Create; overload;
    @@ -76,58 +86,89 @@
         constructor Create(aaccess:longword); overload;
         destructor Destroy; override;
     
    -    function CreateKey(const Key: string): Boolean;
    -    function DeleteKey(const Key: string): Boolean;
    -    function DeleteValue(const Name: string): Boolean;
    -    function GetDataInfo(const ValueName: string; Out Value: TRegDataInfo): Boolean;
    -    function GetDataSize(const ValueName: string): Integer;
    -    function GetDataType(const ValueName: string): TRegDataType;
    +    function CreateKey(const Key: UnicodeString): Boolean;
    +    function CreateKey(const Key: String): Boolean;
    +    function DeleteKey(const Key: UnicodeString): Boolean;
    +    function DeleteKey(const Key: String): Boolean;
    +    function DeleteValue(const Name: UnicodeString): Boolean;
    +    function DeleteValue(const Name: String): Boolean;
    +    function GetDataInfo(const ValueName: UnicodeString; Out Value: TRegDataInfo): Boolean;
    +    function GetDataInfo(const ValueName: String; Out Value: TRegDataInfo): Boolean;
    +    function GetDataSize(const ValueName: UnicodeString): Integer;
    +    function GetDataSize(const ValueName: String): Integer;
    +    function GetDataType(const ValueName: UnicodeString): TRegDataType;
    +    function GetDataType(const ValueName: String): TRegDataType;
         function GetKeyInfo(Out Value: TRegKeyInfo): Boolean;
         function HasSubKeys: Boolean;
    -    function KeyExists(const Key: string): Boolean;
    -    function LoadKey(const Key, FileName: string): Boolean;
    -    function OpenKey(const Key: string; CanCreate: Boolean): Boolean;
    -    function OpenKeyReadOnly(const Key: string): Boolean;
    -    function ReadCurrency(const Name: string): Currency;
    -    function ReadBinaryData(const Name: string; var Buffer; BufSize: Integer): Integer;
    -    function ReadBool(const Name: string): Boolean;
    -    function ReadDate(const Name: string): TDateTime;
    -    function ReadDateTime(const Name: string): TDateTime;
    -    function ReadFloat(const Name: string): Double;
    -    function ReadInteger(const Name: string): Integer;
    -    function ReadInt64(const Name: string): Int64;
    -    function ReadString(const Name: string): string;
    -    procedure ReadStringList(const Name: string; AList: TStrings);
    -    function ReadTime(const Name: string): TDateTime;
    -    function RegistryConnect(const UNCName: string): Boolean;
    -    function ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
    -    function RestoreKey(const Key, FileName: string): Boolean;
    -    function SaveKey(const Key, FileName: string): Boolean;
    -    function UnLoadKey(const Key: string): Boolean;
    -    function ValueExists(const Name: string): Boolean;
    +    function KeyExists(const Key: UnicodeString): Boolean;
    +    function KeyExists(const Key: String): Boolean;
    +    function LoadKey(const Key, FileName: UnicodeString): Boolean;
    +    function LoadKey(const Key, FileName: String): Boolean;
    +    function OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
    +    function OpenKey(const Key: String; CanCreate: Boolean): Boolean;
    +    function OpenKeyReadOnly(const Key: UnicodeString): Boolean;
    +    function OpenKeyReadOnly(const Key: String): Boolean;
    +    function ReadCurrency(const Name: UnicodeString): Currency;
    +    function ReadCurrency(const Name: String): Currency;
    +    function ReadBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer): Integer;
    +    function ReadBinaryData(const Name: String; var Buffer; BufSize: Integer): Integer;
    +    function ReadBool(const Name: UnicodeString): Boolean;
    +    function ReadBool(const Name: String): Boolean;
    +    function ReadDate(const Name: UnicodeString): TDateTime;
    +    function ReadDate(const Name: String): TDateTime;
    +    function ReadDateTime(const Name: UnicodeString): TDateTime;
    +    function ReadDateTime(const Name: String): TDateTime;
    +    function ReadFloat(const Name: UnicodeString): Double;
    +    function ReadFloat(const Name: String): Double;
    +    function ReadInteger(const Name: UnicodeString): Integer;
    +    function ReadInteger(const Name: String): Integer;
    +    function ReadInt64(const Name: UnicodeString): Int64;
    +    function ReadInt64(const Name: String): Int64;
    +    function ReadString(const Name: UnicodeString): UnicodeString;
    +    function ReadString(const Name: String): string;
    +    procedure ReadStringList(const Name: UnicodeString; AList: TStrings; ForceUtf8: Boolean=False);
    +    procedure ReadStringList(const Name: String; AList: TStrings);
    +    function ReadStringArray(const Name: UnicodeString): TUnicodeStringArray;
    +    function ReadStringArray(const Name: String): TStringArray;
    +    function ReadTime(const Name: UnicodeString): TDateTime;
    +    function ReadTime(const Name: String): TDateTime;
    +    function RegistryConnect(const UNCName: UnicodeString): Boolean;
    +    function RegistryConnect(const UNCName: String): Boolean;
    +    function ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
    +    function ReplaceKey(const Key, FileName, BackUpFileName: String): Boolean;
    +    function RestoreKey(const Key, FileName: UnicodeString): Boolean;
    +    function RestoreKey(const Key, FileName: String): Boolean;
    +    function SaveKey(const Key, FileName: UnicodeString): Boolean;
    +    function SaveKey(const Key, FileName: String): Boolean;
    +    function UnLoadKey(const Key: UnicodeString): Boolean;
    +    function UnLoadKey(const Key: String): Boolean;
    +    function ValueExists(const Name: UnicodeString): Boolean;
    +    function ValueExists(const Name: String): Boolean;
     
         procedure CloseKey;
         procedure CloseKey(key:HKEY);
         procedure GetKeyNames(Strings: TStrings);
         procedure GetValueNames(Strings: TStrings);
    -    procedure MoveKey(const OldName, NewName: string; Delete: Boolean);
    -    procedure RenameValue(const OldName, NewName: string);
    -    procedure WriteCurrency(const Name: string; Value: Currency);
    -    procedure WriteBinaryData(const Name: string; var Buffer; BufSize: Integer);
    -    procedure WriteBool(const Name: string; Value: Boolean);
    -    procedure WriteDate(const Name: string; Value: TDateTime);
    -    procedure WriteDateTime(const Name: string; Value: TDateTime);
    -    procedure WriteFloat(const Name: string; Value: Double);
    -    procedure WriteInteger(const Name: string; Value: Integer);
    -    procedure WriteInt64(const Name: string; Value: Int64);
    -    procedure WriteString(const Name, Value: string);
    -    procedure WriteExpandString(const Name, Value: string);
    -    procedure WriteStringList(const Name: string; List: TStrings);
    -    procedure WriteTime(const Name: string; Value: TDateTime);
    +    procedure MoveKey(const OldName, NewName: UnicodeString; Delete: Boolean);
    +    procedure RenameValue(const OldName, NewName: UnicodeString);
    +    procedure WriteCurrency(const Name: UnicodeString; Value: Currency);
    +    procedure WriteBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer);
    +    procedure WriteBool(const Name: UnicodeString; Value: Boolean);
    +    procedure WriteDate(const Name: UnicodeString; Value: TDateTime);
    +    procedure WriteDateTime(const Name: UnicodeString; Value: TDateTime);
    +    procedure WriteFloat(const Name: UnicodeString; Value: Double);
    +    procedure WriteInteger(const Name: UnicodeString; Value: Integer);
    +    procedure WriteInt64(const Name: UnicodeString; Value: Int64);
    +    procedure WriteString(const Name, Value: UnicodeString);
    +    procedure WriteExpandString(const Name, Value: UnicodeString);
    +    procedure WriteStringList(const Name: UnicodeString; List: TStrings; IsUtf8: Boolean=False);
    +    procedure WriteStringArray(const Name: UnicodeString; const Arr: TUnicodeStringArray);
    +    procedure WriteStringArray(const Name: String; const Arr: TStringArray);
    +    procedure WriteTime(const Name: UnicodeString; Value: TDateTime);
     
         property Access: LongWord read fAccess write fAccess;
         property CurrentKey: HKEY read fCurrentKey;
    -    property CurrentPath: string read fCurrentPath;
    +    property CurrentPath: UnicodeString read fCurrentPath;
         property LazyWrite: Boolean read fLazyWrite write fLazyWrite;
         property RootKey: HKEY read fRootKey write SetRootKey;
         Property StringSizeIncludesNull : Boolean read FStringSizeIncludesNull;
    @@ -261,7 +302,7 @@
       inherited Destroy;
     end;
     
    -function TRegistry.CreateKey(const Key: string): Boolean;
    +function TRegistry.CreateKey(const Key: UnicodeString): Boolean;
     
     begin
       Result:=SysCreateKey(Key);
    @@ -269,6 +310,27 @@
         Raise ERegistryException.CreateFmt(SRegCreateFailed, [Key]);
     end;
     
    +function TRegistry.CreateKey(const Key: String): Boolean;
    +begin
    +  Result:=CreateKey(UnicodeString(Key));
    +end;
    +
    +function TRegistry.DeleteKey(const Key: String): Boolean;
    +begin
    +  Result:=DeleteKey(UnicodeString(Key));
    +end;
    +
    +function TRegistry.DeleteValue(const Name: String): Boolean;
    +begin
    +  Result:=DeleteValue(UnicodeString(Name));
    +end;
    +
    +function TRegistry.GetDataInfo(const ValueName: String; out Value: TRegDataInfo
    +  ): Boolean;
    +begin
    +  Result:=GetDataInfo(UnicodeString(ValueName), Value);
    +end;
    +
     function TRegistry.GetBaseKey(Relative: Boolean): HKey;
     begin
       If Relative and (CurrentKey<>0) Then
    @@ -277,7 +339,7 @@
         Result := RootKey;
     end;
     
    -function TRegistry.GetData(const Name: string; Buffer: Pointer; BufSize: Integer; out RegData: TRegDataType): Integer;
    +function TRegistry.GetData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; out RegData: TRegDataType): Integer;
     begin
       Result:=SysGetData(Name,Buffer,BufSize,RegData);
       If (Result=-1) then
    @@ -284,7 +346,24 @@
         Raise ERegistryException.CreateFmt(SRegGetDataFailed, [Name]);
     end;
     
    -procedure TRegistry.PutData(const Name: string; Buffer: Pointer;
    +function TRegistry.GetData(const Name: String; Buffer: Pointer;
    +  BufSize: Integer; out RegData: TRegDataType): Integer;
    +begin
    +  Result:=GetData(UnicodeString(Name), Buffer, BufSize, RegData);
    +end;
    +
    +function TRegistry.GetKey(Key: String): HKEY;
    +begin
    +  Result:=GetKey(UnicodeString(Key));
    +end;
    +
    +procedure TRegistry.ChangeKey(Value: HKey; const Path: String);
    +begin
    +  ChangeKey(Value, UnicodeString(Path));
    +end;
    +
    +
    +procedure TRegistry.PutData(const Name: UnicodeString; Buffer: Pointer;
       BufSize: Integer; RegData: TRegDataType);
     
     begin
    @@ -292,9 +371,15 @@
         Raise ERegistryException.CreateFmt(SRegSetDataFailed, [Name]);
     end;
     
    +procedure TRegistry.PutData(const Name: String; Buffer: Pointer;
    +  BufSize: Integer; RegData: TRegDataType);
    +begin
    +  PutData(UnicodeString(Name), Buffer, BufSize, RegData);
    +end;
     
    -function TRegistry.GetDataSize(const ValueName: string): Integer;
     
    +function TRegistry.GetDataSize(const ValueName: UnicodeString): Integer;
    +
     Var
       Info: TRegDataInfo;
     
    @@ -305,8 +390,13 @@
         Result := -1;
     end;
     
    -function TRegistry.GetDataType(const ValueName: string): TRegDataType;
    +function TRegistry.GetDataSize(const ValueName: String): Integer;
    +begin
    +  Result:=GetDataSize(UnicodeString(ValueName));
    +end;
     
    +function TRegistry.GetDataType(const ValueName: UnicodeString): TRegDataType;
    +
     Var
       Info: TRegDataInfo;
     
    @@ -315,6 +405,32 @@
       Result:=Info.RegData;
     end;
     
    +function TRegistry.GetDataType(const ValueName: String): TRegDataType;
    +begin
    +  Result:=GetDataType(UnicodeString(ValueName));
    +end;
    +
    +
    +function TRegistry.KeyExists(const Key: String): Boolean;
    +begin
    +  Result:=KeyExists(UnicodeString(Key));
    +end;
    +
    +function TRegistry.LoadKey(const Key, FileName: String): Boolean;
    +begin
    +  Result:=LoadKey(UnicodeString(Key), UnicodeString(FileName));
    +end;
    +
    +function TRegistry.OpenKey(const Key: String; CanCreate: Boolean): Boolean;
    +begin
    +  Result:=OpenKey(UnicodeString(Key), CanCreate);
    +end;
    +
    +function TRegistry.OpenKeyReadOnly(const Key: String): Boolean;
    +begin
    +  Result:=OpenKeyReadOnly(UnicodeString(Key));
    +end;
    +
     function TRegistry.HasSubKeys: Boolean;
     
     Var
    @@ -326,7 +442,7 @@
         Result:=(Info.NumSubKeys>0);
     end;
     
    -function TRegistry.ReadBinaryData(const Name: string; var Buffer; BufSize: Integer): Integer;
    +function TRegistry.ReadBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer): Integer;
     
     Var
       RegDataType: TRegDataType;
    @@ -337,8 +453,14 @@
         Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
     end;
     
    -function TRegistry.ReadInteger(const Name: string): Integer;
    +function TRegistry.ReadBinaryData(const Name: String; var Buffer;
    +  BufSize: Integer): Integer;
    +begin
    +  Result:=ReadBinaryData(UnicodeString(Name), Buffer, BufSize);
    +end;
     
    +function TRegistry.ReadInteger(const Name: UnicodeString): Integer;
    +
     Var
       RegDataType: TRegDataType;
     
    @@ -348,8 +470,13 @@
         Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
     end;
     
    -function TRegistry.ReadInt64(const Name: string): Int64;
    +function TRegistry.ReadInteger(const Name: String): Integer;
    +begin
    +  Result:=ReadInteger(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadInt64(const Name: UnicodeString): Int64;
    +
     Var
       RegDataType: TRegDataType;
     
    @@ -359,21 +486,36 @@
         Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
     end;
     
    -function TRegistry.ReadBool(const Name: string): Boolean;
    +function TRegistry.ReadInt64(const Name: String): Int64;
    +begin
    +  Result:=ReadInt64(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadBool(const Name: UnicodeString): Boolean;
    +
     begin
       Result:=ReadInteger(Name)<>0;
     end;
     
    -function TRegistry.ReadCurrency(const Name: string): Currency;
    +function TRegistry.ReadBool(const Name: String): Boolean;
    +begin
    +  Result:=ReadBool(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadCurrency(const Name: UnicodeString): Currency;
    +
     begin
       Result:=Default(Currency);
       ReadBinaryData(Name, Result, SizeOf(Currency));
     end;
     
    -function TRegistry.ReadDate(const Name: string): TDateTime;
    +function TRegistry.ReadCurrency(const Name: String): Currency;
    +begin
    +  Result:=ReadCurrency(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadDate(const Name: UnicodeString): TDateTime;
    +
     begin
       Result:=Default(TDateTime);
       ReadBinaryData(Name, Result, SizeOf(TDateTime));
    @@ -380,22 +522,37 @@
       Result:=Trunc(Result);
     end;
     
    -function TRegistry.ReadDateTime(const Name: string): TDateTime;
    +function TRegistry.ReadDate(const Name: String): TDateTime;
    +begin
    +  Result:=ReadDate(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadDateTime(const Name: UnicodeString): TDateTime;
    +
     begin
       Result:=Default(TDateTime);
       ReadBinaryData(Name, Result, SizeOf(TDateTime));
     end;
     
    -function TRegistry.ReadFloat(const Name: string): Double;
    +function TRegistry.ReadDateTime(const Name: String): TDateTime;
    +begin
    +  Result:=ReadDateTime(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadFloat(const Name: UnicodeString): Double;
    +
     begin
       Result:=Default(Double);
       ReadBinaryData(Name,Result,SizeOf(Double));
     end;
     
    -function TRegistry.ReadString(const Name: string): string;
    +function TRegistry.ReadFloat(const Name: String): Double;
    +begin
    +  Result:=ReadFloat(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadString(const Name: UnicodeString): UnicodeString;
    +
     Var
       Info : TRegDataInfo;
       ReadDataSize: Integer;
    @@ -421,27 +578,54 @@
           if StringSizeIncludesNull and
              (u[Length(u)] = WideChar(0)) then
             SetLength(u,Length(u)-1);
    -      Result:=UTF8Encode(u);
    +      Result:=u;
         end;
       end;
     end;
     
    -procedure TRegistry.ReadStringList(const Name: string; AList: TStrings);
    +function TRegistry.ReadString(const Name: String): string;
    +begin
    +  Result:=ReadString(UnicodeString(Name));
    +end;
     
    +//**************************REMOVE
    +function DbgS(const S: UnicodeString): String;
    +var
    +  C: WideChar;
    +begin
    +  Result := format('[%5d] ',[StringCodePage((S))]);
    +  for C in S do Result := Result + IntToHex(Word(C),4) + #32;
    +  Result := TrimRight(Result);
    +end;
    +
    +procedure TRegistry.ReadStringList(const Name: UnicodeString; AList: TStrings; ForceUtf8: Boolean=False);
    +
     Var
       Info : TRegDataInfo;
    -  ReadDataSize: Integer;
    -  Data: string;
    +  ReadDataSize, i: Integer;
    +  Data: UnicodeString;
    +  UArr: TUnicodeStringArray;
     
     begin
       AList.Clear;
    +  UArr := ReadStringArray(Name);
    +  for i := Low(UArr) to High(UArr) do
    +  begin
    +    if ForceUtf8 then
    +      AList.Add(Utf8Encode(UArr[i]))
    +    else
    +      AList.Add(String(UArr[i]));
    +  end;
    +{
       GetDataInfo(Name,Info);
    +  writeln('TRegistry.ReadStringList: datasize=',info.datasize);
       if info.datasize>0 then
         begin
          If Not (Info.RegData in [rdMultiString]) then
            Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
          SetLength(Data,Info.DataSize);
    -     ReadDataSize := GetData(Name,PChar(Data),Info.DataSize,Info.RegData);
    +     ReadDataSize := GetData(Name,PWideChar(Data),Info.DataSize,Info.RegData) div SizeOf(WideChar);
    +     writeln('TRegistry.ReadStringList: ReadDataSize=',ReadDataSize);
          if ReadDataSize > 0 then
          begin
            // If the data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type,
    @@ -454,95 +638,253 @@
                Dec(ReadDataSize);
            end;
            SetLength(Data, ReadDataSize);
    -       Data := StringReplace(Data, #0, LineEnding, [rfReplaceAll]);
    +       writeln('Data=',dbgs(data));
    +       Data := UnicodeStringReplace(Data, #0, AList.LineBreak, [rfReplaceAll]);
            AList.Text := Data;
          end
        end
    +}
     end;
     
    -function TRegistry.ReadTime(const Name: string): TDateTime;
    +procedure TRegistry.ReadStringList(const Name: String; AList: TStrings);
    +begin
    +  ReadStringList(UnicodeString(Name), AList);
    +end;
     
    +function TRegistry.RegMultiSzDataToUnicodeStringArray(U: UnicodeString): TUnicodeStringArray;
    +var
    +  Len, i, p: Integer;
    +  Sub: UnicodeString;
     begin
    +  Result := nil;
    +  if (U = '') then Exit;
    +  Len := 1;
    +  for i := 1 to Length(U) do if (U[i] = #0) then Inc(Len);
    +  SetLength(Result, Len);
    +  i := 0;
    +
    +  while (U <> '') and (i < Length(Result)) do
    +  begin
    +    p := Pos(#0, U);
    +    if (p = 0) then p := Length(U) + 1;
    +    Sub := Copy(U, 1, p - 1);
    +    Result[i] := Sub;
    +    System.Delete(U, 1, p);
    +    Inc(i);
    +  end;
    +end;
    +
    +function TRegistry.ReadStringArray(const Name: UnicodeString): TUnicodeStringArray;
    +Var
    +  Info : TRegDataInfo;
    +  ReadDataSize, i: Integer;
    +  Data: UnicodeString;
    +
    +begin
    +  Result := nil;
    +  GetDataInfo(Name,Info);
    +  writeln('TRegistry.ReadStringArray: datasize=',info.datasize);
    +  if info.datasize>0 then
    +    begin
    +     If Not (Info.RegData in [rdMultiString]) then
    +       Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
    +     SetLength(Data,Info.DataSize);
    +     ReadDataSize := GetData(Name,PWideChar(Data),Info.DataSize,Info.RegData) div SizeOf(WideChar);
    +     writeln('TRegistry.ReadStringArray: ReadDataSize=',ReadDataSize);
    +     if ReadDataSize > 0 then
    +     begin
    +       // Windows returns the data with or without trailing zero's, so just strip all trailing null characters
    +        while (Data[ReadDataSize] = #0) do Dec(ReadDataSize);
    +       SetLength(Data, ReadDataSize);
    +       writeln('Data=',dbgs(data));
    +       //Data := UnicodeStringReplace(Data, #0, AList.LineBreak, [rfReplaceAll]);
    +       //AList.Text := Data;
    +       Result := RegMultiSzDataToUnicodeStringArray(Data);
    +     end
    +   end
    +end;
    +
    +function TRegistry.ReadStringArray(const Name: String): TStringArray;
    +var
    +  UArr: TUnicodeStringArray;
    +  i: Integer;
    +begin
    +  Result := nil;
    +  UArr := ReadStringArray(UnicodeString(Name));
    +  SetLength(Result, Length(UArr));
    +  for i := Low(UArr) to High(UArr) do Result[i] := UArr[i];
    +end;
    +
    +function TRegistry.ReadTime(const Name: UnicodeString): TDateTime;
    +
    +begin
       Result:=Default(TDateTime);
       ReadBinaryData(Name, Result, SizeOf(TDateTime));
       Result:=Frac(Result);
     end;
     
    -procedure TRegistry.WriteBinaryData(const Name: string; var Buffer; BufSize: Integer);
    +function TRegistry.ReadTime(const Name: String): TDateTime;
     begin
    +  Result:=ReadTime(UnicodeString(Name));
    +end;
    +
    +function TRegistry.RegistryConnect(const UNCName: String): Boolean;
    +begin
    +  Result:=RegistryConnect(UnicodeString(UNCName));
    +end;
    +
    +function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: String): Boolean;
    +begin
    +  Result:=ReplaceKey(UnicodeString(Key), UnicodeString(FileName), UnicodeString(BackUpFileName))
    +end;
    +
    +function TRegistry.RestoreKey(const Key, FileName: String): Boolean;
    +begin
    +  Result:=RestoreKey(UnicodeString(Key), UnicodeString(FileName));
    +end;
    +
    +function TRegistry.SaveKey(const Key, FileName: String): Boolean;
    +begin
    +  Result:=SaveKey(UnicodeString(Key), UnicodeString(FileName));
    +end;
    +
    +function TRegistry.UnLoadKey(const Key: String): Boolean;
    +begin
    +  Result:=UnloadKey(UnicodeString(Key));
    +end;
    +
    +function TRegistry.ValueExists(const Name: String): Boolean;
    +begin
    +  Result:=ValueExists(UnicodeString(Name));
    +end;
    +
    +procedure TRegistry.WriteBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer);
    +begin
       PutData(Name, @Buffer, BufSize, rdBinary);
     end;
     
    -procedure TRegistry.WriteBool(const Name: string; Value: Boolean);
    +procedure TRegistry.WriteBool(const Name: UnicodeString; Value: Boolean);
     
     begin
       WriteInteger(Name,Ord(Value));
     end;
     
    -procedure TRegistry.WriteCurrency(const Name: string; Value: Currency);
    +procedure TRegistry.WriteCurrency(const Name: UnicodeString; Value: Currency);
     begin
       WriteBinaryData(Name, Value, SizeOf(Currency));
     end;
     
    -procedure TRegistry.WriteDate(const Name: string; Value: TDateTime);
    +procedure TRegistry.WriteDate(const Name: UnicodeString; Value: TDateTime);
     begin
       WriteBinarydata(Name, Value, SizeOf(TDateTime));
     end;
     
    -procedure TRegistry.WriteTime(const Name: string; Value: TDateTime);
    +procedure TRegistry.WriteTime(const Name: UnicodeString; Value: TDateTime);
     begin
       WriteBinaryData(Name, Value, SizeOf(TDateTime));
     end;
     
    -procedure TRegistry.WriteDateTime(const Name: string; Value: TDateTime);
    +procedure TRegistry.WriteDateTime(const Name: UnicodeString; Value: TDateTime);
     begin
       WriteBinaryData(Name, Value, SizeOf(TDateTime));
     end;
     
    -procedure TRegistry.WriteExpandString(const Name, Value: string);
    -var
    -  u: UnicodeString;
    -
    +procedure TRegistry.WriteExpandString(const Name, Value: UnicodeString);
     begin
    -  u:=Value;
    -  PutData(Name, PWideChar(u), ByteLength(u), rdExpandString);
    +  PutData(Name, PWideChar(Value), ByteLength(Value), rdExpandString);
     end;
     
    -procedure TRegistry.WriteStringList(const Name: string; List: TStrings);
     
    +procedure TRegistry.WriteStringList(const Name: UnicodeString; List: TStrings; IsUtf8: Boolean=False);
    +
     Var
    -  Data: string;
    +  Data: UnicodeString;
    +  u: UnicodeString;
    +  UArr: TUnicodeStringArray;
    +  i, Len: Integer;
    +begin
    +  Data := '';
    +  UArr := nil;
    +  //REG_MULTI_SZ data cannot contain empty strings
    +  Len := List.Count;
    +  SetLength(UArr, Len);
    +  for i := 0 to List.Count - 1 do
    +  begin
    +    if IsUtf8 then
    +      u := Utf8Decode(List[i])
    +    else
    +      u := List[i];
    +    if (u>'') then
    +    begin
    +      if (Data>'') then
    +        Data := Data + #0 + u
    +      else
    +        Data := Data + u;
    +    end
    +    else
    +      Dec(Len);
    +  end;
    +  if (Len <> List.Count) then SetLength(UArr, Len);
    +  WriteStringArray(Name, UArr);
    +end;
     
    +procedure TRegistry.WriteStringArray(const Name: UnicodeString; const Arr: TUnicodeStringArray);
    +Var
    +  Data: UnicodeString;
    +  u: UnicodeString;
    +  i: Integer;
     begin
    -  Data := StringReplace(List.Text, LineEnding, #0, [rfReplaceAll]) + #0#0;
    -  PutData(Name, PChar(Data), Length(Data),rdMultiString);
    +  Data := '';
    +  //REG_MULTI_SZ data cannot contain empty strings
    +  for i := Low(Arr) to High(Arr) do
    +  begin
    +    u := Arr[i];
    +    if (u>'') then
    +    begin
    +      if (Data>'') then
    +        Data := Data + #0 + u
    +      else
    +        Data := Data + u;
    +    end;
    +  end;
    +  if StringSizeIncludesNull then
    +    Data := Data + #0#0;
    +  //writeln('Data=',Dbgs(Data));
    +  PutData(Name, PWideChar(Data), ByteLength(Data), rdMultiString);
     end;
     
    -procedure TRegistry.WriteFloat(const Name: string; Value: Double);
    +procedure TRegistry.WriteStringArray(const Name: String; const Arr: TStringArray);
    +var
    +  UArr: TUnicodeStringArray;
    +  i: Integer;
     begin
    +  UArr := nil;
    +  SetLength(UArr, Length(Arr));
    +  for i := Low(Arr) to High(Arr) do UArr[i] := Arr[i];
    +  WriteStringArray(UnicodeString(Name), UArr);
    +end;
    +
    +procedure TRegistry.WriteFloat(const Name: UnicodeString; Value: Double);
    +begin
       WriteBinaryData(Name, Value, SizeOf(Double));
     end;
     
    -procedure TRegistry.WriteInteger(const Name: string; Value: Integer);
    +procedure TRegistry.WriteInteger(const Name: UnicodeString; Value: Integer);
     begin
       PutData(Name, @Value, SizeOf(Integer), rdInteger);
     end;
     
    -procedure TRegistry.WriteInt64(const Name: string; Value: Int64);
    +procedure TRegistry.WriteInt64(const Name: UnicodeString; Value: Int64);
     begin
       PutData(Name, @Value, SizeOf(Int64), rdInt64);
     end;
     
    -procedure TRegistry.WriteString(const Name, Value: string);
    -var
    -  u: UnicodeString;
    -
    +procedure TRegistry.WriteString(const Name, Value: UnicodeString);
     begin
    -  u:=Value;
    -  PutData(Name, PWideChar(u), ByteLength(u), rdString);
    +  PutData(Name, PWideChar(Value), ByteLength(Value), rdString);
     end;
     
    -procedure TRegistry.MoveKey(const OldName, NewName: string; Delete: Boolean);
    +procedure TRegistry.MoveKey(const OldName, NewName: UnicodeString; Delete: Boolean);
     begin
     
     end;
    @@ -583,7 +925,7 @@
       Value: TStream): Integer;
     begin
       result:=-1; // unimplemented
    - // 
    + //
     end;
     
     function TRegistryIniFile.ReadDate(const Section, Name: string;
    Index: packages/fcl-registry/src/winreg.inc
    ===================================================================
    --- packages/fcl-registry/src/winreg.inc	(revision 41667)
    +++ packages/fcl-registry/src/winreg.inc	(working copy)
    @@ -1,7 +1,7 @@
     Const
       RegDataWords : Array [TRegDataType] of DWORD
                    = (REG_NONE,REG_SZ,REG_EXPAND_SZ,REG_BINARY,REG_DWORD,REG_DWORD_BIG_ENDIAN,
    -                  REG_LINK,REG_MULTI_SZ,REG_RESOURCE_LIST,REG_FULL_RESOURCE_DESCRIPTOR,REG_RESOURCE_REQUIREMENTS_LIST,REG_QWORD);
    +                  REG_LINK,REG_MULTI_SZ,REG_RESOURCE_LIST,REG_FULL_RESOURCE_DESCRIPTOR,REG_RESOURCE_REQUIREMENTS_LIST,11{REG_QWORD}); //*****UNDO THIS!
     
     type
       TWinRegData = record
    @@ -28,7 +28,7 @@
       Dispose(PWinRegData(FSysData));
     end;
     
    -Function PrepKey(Const S : String) : String;
    +Function PrepKey(Const S : UnicodeString) : UnicodeString;
     
     begin
       Result := S;
    @@ -36,7 +36,7 @@
         System.Delete(Result, 1, 1);
     end;
     
    -Function RelativeKey(Const S : String) : Boolean;
    +Function RelativeKey(Const S : UnicodeString) : Boolean;
     
     begin
       Result:=(S='') or (S[1]<>'\')
    @@ -43,7 +43,7 @@
     end;
     
     
    -function TRegistry.sysCreateKey(const Key: String): Boolean;
    +function TRegistry.sysCreateKey(Key: UnicodeString): Boolean;
     Var
       u: UnicodeString;
       Disposition: Dword;
    @@ -52,9 +52,9 @@
     
     begin
       SecurityAttributes := Nil;
    -  u:=PrepKey(Key);
    +  Key:=PrepKey(Key);
       FLastError:=RegCreateKeyExW(GetBaseKey(RelativeKey(Key)),
    -                              PWideChar(u),
    +                              PWideChar(Key),
                                   0,
                                   '',
                                   REG_OPTION_NON_VOLATILE,
    @@ -66,7 +66,7 @@
       RegCloseKey(Handle);
     end;
     
    -function TRegistry.DeleteKey(const Key: String): Boolean;
    +function TRegistry.DeleteKey(const Key: UnicodeString): Boolean;
     
     Var
       u: UnicodeString;
    @@ -76,21 +76,21 @@
       Result:=FLastError=ERROR_SUCCESS;
     end;
     
    -function TRegistry.DeleteValue(const Name: String): Boolean;
    +
    +function TRegistry.DeleteValue(const Name: UnicodeString): Boolean;
     begin
    -  FLastError:= RegDeleteValueW(fCurrentKey, PWideChar(UnicodeString(Name)));
    +  FLastError:= RegDeleteValueW(fCurrentKey, PWideChar(Name));
       Result:=FLastError=ERROR_SUCCESS;
     end;
     
    -function TRegistry.SysGetData(const Name: String; Buffer: Pointer;
    +
    +function TRegistry.SysGetData(const Name: UnicodeString; Buffer: Pointer;
               BufSize: Integer; Out RegData: TRegDataType): Integer;
     Var
    -  u: UnicodeString;
       RD : DWord;
     
     begin
    -  u := Name;
    -  FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(u),Nil,
    +  FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(Name),Nil,
                           @RD,Buffer,lpdword(@BufSize));
       if (FLastError<>ERROR_SUCCESS) Then
         Result:=-1
    @@ -103,17 +103,15 @@
         end;
     end;
     
    -function TRegistry.GetDataInfo(const ValueName: String; out Value: TRegDataInfo): Boolean;
    +function TRegistry.GetDataInfo(const ValueName: UnicodeString; out Value: TRegDataInfo): Boolean;
     
     Var
    -  u: UnicodeString;
       RD : DWord;
     
     begin
    -  u:=ValueName;
       With Value do
         begin
    -    FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(u),Nil,lpdword(@RegData),Nil,lpdword(@DataSize));
    +    FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(ValueName),Nil,lpdword(@RegData),Nil,lpdword(@DataSize));
         Result:=FLastError=ERROR_SUCCESS;
         if Result then
           begin
    @@ -131,24 +129,18 @@
     end;
     
     
    -function TRegistry.GetKey(const Key: String): HKEY;
    +function TRegistry.GetKey(Key: UnicodeString): HKEY;
     var
    -  S : string;
    -{$ifndef WinCE}
    -  u : UnicodeString;
    -{$endif}
       Rel : Boolean;
     begin
       Result:=0;
    -  S:=Key;
    -  Rel:=RelativeKey(S);
    +  Rel:=RelativeKey(Key);
       if not(Rel) then
    -    Delete(S,1,1);
    +    Delete(Key,1,1);
     {$ifdef WinCE}
    -  FLastError:=RegOpenKeyEx(GetBaseKey(Rel),PWideChar(WideString(S)),0,FAccess,Result);
    +  FLastError:=RegOpenKeyEx(GetBaseKey(Rel),PWideChar(Key),0,FAccess,Result);
     {$else WinCE}
    -  u:=UnicodeString(S);
    -  FLastError:=RegOpenKeyExW(GetBaseKey(Rel),PWideChar(u),0,FAccess,Result);
    +  FLastError:=RegOpenKeyExW(GetBaseKey(Rel),PWideChar(Key),0,FAccess,Result);
     {$endif WinCE}
     end;
     
    @@ -174,7 +166,7 @@
     end;
     
     
    -function TRegistry.KeyExists(const Key: string): Boolean;
    +function TRegistry.KeyExists(const Key: UnicodeString): Boolean;
     var
       KeyHandle : HKEY;
       OldAccess : LONG;
    @@ -196,20 +188,20 @@
     end;
     
     
    -function TRegistry.LoadKey(const Key, FileName: string): Boolean;
    +function TRegistry.LoadKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
     
    -function TRegistry.OpenKey(const Key: string; CanCreate: Boolean): Boolean;
     
    +function TRegistry.OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
    +
     Var
    -  u: UnicodeString;
    +  u, S: UnicodeString;
       Handle: HKEY;
       Disposition: Integer;
       SecurityAttributes: Pointer; //LPSECURITY_ATTRIBUTES;
    -  S: string;
     begin
       SecurityAttributes := Nil;
       u:=PrepKey(Key);
    @@ -232,13 +224,14 @@
         if RelativeKey(Key) then
           S:=CurrentPath + Key
         else
    -      S:=UTF8Encode(u);
    +      S:=u;
         ChangeKey(Handle, S);
       end;
     end;
     
    -function TRegistry.OpenKeyReadOnly(const Key: string): Boolean;
     
    +function TRegistry.OpenKeyReadOnly(const Key: UnicodeString): Boolean;
    +
     Var
       OldAccess: LongWord;
     begin
    @@ -251,7 +244,8 @@
       end;
     end;
     
    -function TRegistry.RegistryConnect(const UNCName: string): Boolean;
    +
    +function TRegistry.RegistryConnect(const UNCName: UnicodeString): Boolean;
     {$ifndef WinCE}
     var
       newroot: HKEY;
    @@ -260,7 +254,7 @@
     {$ifdef WinCE}
       Result:=False;
     {$else}
    -  FLastError:=RegConnectRegistryW(PWideChar(UnicodeString(UNCName)),RootKey,newroot);
    +  FLastError:=RegConnectRegistryW(PWideChar(UNCName),RootKey,newroot);
       Result:=FLastError=ERROR_SUCCESS;
       if Result then begin
         RootKey:=newroot;
    @@ -269,28 +263,33 @@
     {$endif}
     end;
     
    -function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
    +
    +function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.RestoreKey(const Key, FileName: string): Boolean;
    +
    +function TRegistry.RestoreKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.SaveKey(const Key, FileName: string): Boolean;
    +
    +function TRegistry.SaveKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.UnLoadKey(const Key: string): Boolean;
    +
    +function TRegistry.UnLoadKey(const Key: UnicodeString): Boolean;
     begin
       Result := false;
     end;
     
    -function TRegistry.ValueExists(const Name: string): Boolean;
     
    +function TRegistry.ValueExists(const Name: UnicodeString): Boolean;
    +
     var
       Info : TRegDataInfo;
     
    @@ -298,6 +297,7 @@
       Result:=GetDataInfo(Name,Info);
     end;
     
    +
     procedure TRegistry.CloseKey;
     begin
       If (CurrentKey<>0) then
    @@ -316,7 +316,7 @@
       RegCloseKey(key);
     end;
     
    -procedure TRegistry.ChangeKey(Value: HKey; const Path: String);
    +procedure TRegistry.ChangeKey(Value: HKey; const Path: UnicodeString);
     begin
       CloseKey;
       FCurrentKey:=Value;
    @@ -323,6 +323,7 @@
       FCurrentPath:=Path;
     end;
     
    +
     procedure TRegistry.GetKeyNames(Strings: TStrings);
     
     var
    @@ -410,12 +411,11 @@
     end;
     
     
    -Function TRegistry.SysPutData(const Name: string; Buffer: Pointer;
    +Function TRegistry.SysPutData(const Name: UnicodeString; Buffer: Pointer;
       BufSize: Integer; RegData: TRegDataType) : Boolean;
     
     
     Var
    -  u: UnicodeString;
       RegDataType: DWORD;
       B : Pchar;
       S : String;
    @@ -422,12 +422,11 @@
     
     begin
       RegDataType:=RegDataWords[RegData];
    -  u:=UnicodeString(Name);
    -  FLastError:=RegSetValueExW(fCurrentKey,PWideChar(u),0,RegDataType,Buffer,BufSize);
    +  FLastError:=RegSetValueExW(fCurrentKey,PWideChar(Name),0,RegDataType,Buffer,BufSize);
       Result:=FLastError=ERROR_SUCCESS;
     end;
     
    -procedure TRegistry.RenameValue(const OldName, NewName: string);
    +procedure TRegistry.RenameValue(const OldName, NewName: UnicodeString);
     
     var
       L: Integer;
    Index: packages/fcl-registry/src/xmlreg.pp
    ===================================================================
    --- packages/fcl-registry/src/xmlreg.pp	(revision 41667)
    +++ packages/fcl-registry/src/xmlreg.pp	(working copy)
    @@ -32,54 +32,54 @@
       Private
         FAutoFlush,
         FDirty : Boolean;
    -    FFileName : String;
    -    FRootKey : String;
    +    FFileName : UnicodeString;
    +    FRootKey : UnicodeString;
         FDocument : TXMLDocument;
         FCurrentElement : TDomElement;
    -    FCurrentKey : String;
    -    Procedure SetFileName(Value : String);
    +    FCurrentKey : UnicodeString;
    +    Procedure SetFileName(Value : UnicodeString);
       Protected
    -    function DoGetValueData(Name: String; out DataType: TDataType; Var Data; Var DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
    -    function DoSetValueData(Name: String; DataType: TDataType; const Data; DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
    +    function DoGetValueData(Name: UnicodeString; out DataType: TDataType; Var Data; Var DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
    +    function DoSetValueData(Name: UnicodeString; DataType: TDataType; const Data; DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
         Procedure LoadFromStream(S : TStream);
    -    Function  NormalizeKey(KeyPath : String) : String;
    +    Function  NormalizeKey(KeyPath : UnicodeString) : UnicodeString;
         Procedure CreateEmptyDoc;
    -    Function  FindKey (S : String) : TDomElement;
    -    Function  FindSubKey (S : String; N : TDomElement) : TDomElement;
    -    Function  CreateSubKey (S : String; N : TDomElement) : TDomElement;
    -    Function  FindValueKey (S : String) : TDomElement;
    -    Function  CreateValueKey (S : String) : TDomElement;
    +    Function  FindKey (S : UnicodeString) : TDomElement;
    +    Function  FindSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
    +    Function  CreateSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
    +    Function  FindValueKey (S : UnicodeString) : TDomElement;
    +    Function  CreateValueKey (S : UnicodeString) : TDomElement;
         Function  BufToHex(Const Buf; Len : Integer) : String;
    -    Function  hexToBuf(Const Str : String; Var Buf; Var Len : Integer ) : Integer;
    +    Function  HexToBuf(Const Str : UnicodeString; Var Buf; Var Len : Integer ) : Integer;
         Procedure MaybeFlush;
         Property  Document : TXMLDocument Read FDocument;
         Property  Dirty : Boolean Read FDirty write FDirty;
       Public
    -    Constructor Create(AFileName : String);
    +    Constructor Create(AFileName : UnicodeString);
         Destructor  Destroy;override;
    -    Function  SetKey(KeyPath : String; AllowCreate : Boolean) : Boolean ;
    -    Procedure SetRootKey(Value : String);
    -    Function  DeleteKey(KeyPath : String) : Boolean;
    -    Function  CreateKey(KeyPath : String) : Boolean;
    -    Function  GetValueSize(Name : String) : Integer;
    -    Function  GetValueType(Name : String) : TDataType;
    -    Function  GetValueInfo(Name : String; Out Info : TDataInfo; AsUnicode : Boolean = False) : Boolean;
    +    Function  SetKey(KeyPath : UnicodeString; AllowCreate : Boolean) : Boolean ;
    +    Procedure SetRootKey(Value : UnicodeString);
    +    Function  DeleteKey(KeyPath : UnicodeString) : Boolean;
    +    Function  CreateKey(KeyPath : UnicodeString) : Boolean;
    +    Function  GetValueSize(Name : UnicodeString) : Integer;
    +    Function  GetValueType(Name : UnicodeString) : TDataType;
    +    Function  GetValueInfo(Name : UnicodeString; Out Info : TDataInfo; AsUnicode : Boolean = False) : Boolean;
         Function  GetKeyInfo(Out Info : TKeyInfo) : Boolean;
         Function  EnumSubKeys(List : TStrings) : Integer;
         Function  EnumValues(List : TStrings) : Integer;
    -    Function  KeyExists(KeyPath : String) : Boolean;
    -    Function  ValueExists(ValueName : String) : Boolean;
    -    Function  RenameValue(Const OldName,NewName : String) : Boolean;
    -    Function  DeleteValue(S : String) : Boolean;
    +    Function  KeyExists(KeyPath : UnicodeString) : Boolean;
    +    Function  ValueExists(ValueName : UnicodeString) : Boolean;
    +    Function  RenameValue(Const OldName,NewName : UnicodeString) : Boolean;
    +    Function  DeleteValue(S : UnicodeString) : Boolean;
         Procedure Flush;
         Procedure Load;
    -    Function GetValueData(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
    -    Function SetValueData(Name : String; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
    +    Function GetValueData(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
    +    Function SetValueData(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
         // These interpret the Data buffer as unicode data
    -    Function GetValueDataUnicode(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
    -    Function SetValueDataUnicode(Name : String; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
    -    Property FileName : String Read FFileName Write SetFileName;
    -    Property RootKey : String Read FRootKey Write SetRootkey;
    +    Function GetValueDataUnicode(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
    +    Function SetValueDataUnicode(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
    +    Property FileName : UnicodeString Read FFileName Write SetFileName;
    +    Property RootKey : UnicodeString Read FRootKey Write SetRootkey;
         Property AutoFlush : Boolean Read FAutoFlush Write FAutoFlush;
       end;
     
    @@ -96,7 +96,7 @@
     Implementation
     
     
    -Constructor TXmlRegistry.Create(AFileName : String);
    +Constructor TXmlRegistry.Create(AFileName : UnicodeString);
     
     begin
       FFileName:=AFileName;
    @@ -113,7 +113,7 @@
       inherited Destroy;
     end;
     
    -Procedure TXmlRegistry.SetFileName(Value : String);
    +Procedure TXmlRegistry.SetFileName(Value : UnicodeString);
     
     begin
       If Value<>FFileName then
    @@ -143,13 +143,13 @@
       end;
     end;
     
    -Function TXmlRegistry.NormalizeKey(KeyPath : String) : String;
    +Function TXmlRegistry.NormalizeKey(KeyPath : UnicodeString) : UnicodeString;
     
     Var
       L : Integer;
     
     begin
    -  Result:=StringReplace(KeyPath,'\','/',[rfReplaceAll]);
    +  Result:=UnicodeStringReplace(KeyPath,'\','/',[rfReplaceAll]);
       L:=Length(Result);
       If (L>0) and (Result[L]<>'/') then
         Result:=Result+'/';
    @@ -157,10 +157,10 @@
         Result:='/' + Result;
     end;
     
    -Function TXmlRegistry.SetKey(KeyPath : String; AllowCreate : Boolean) : boolean;
    +Function TXmlRegistry.SetKey(KeyPath : UnicodeString; AllowCreate : Boolean) : boolean;
     
     Var
    -  SubKey,ResultKey : String;
    +  SubKey,ResultKey : UnicodeString;
       P : Integer;
       Node,Node2 : TDomElement;
     
    @@ -218,7 +218,7 @@
       MaybeFlush;
     end;
     
    -Procedure TXmlRegistry.SetRootKey(Value : String);
    +Procedure TXmlRegistry.SetRootKey(Value : UnicodeString);
     
     begin
       FRootKey:=NormalizeKey(Value);
    @@ -228,7 +228,7 @@
       FCurrentElement:=Nil;
     end;
     
    -Function TXmlRegistry.DeleteKey(KeyPath : String) : Boolean;
    +Function TXmlRegistry.DeleteKey(KeyPath : UnicodeString) : Boolean;
     
     Var
       N : TDomElement;
    @@ -244,10 +244,10 @@
        end;
     end;
     
    -Function TXmlRegistry.CreateKey(KeyPath : String) : Boolean;
    +Function TXmlRegistry.CreateKey(KeyPath : UnicodeString) : Boolean;
     
     Var
    -  SubKey : String;
    +  SubKey : UnicodeString;
       P : Integer;
       Node,Node2 : TDomElement;
     
    @@ -290,7 +290,7 @@
       MaybeFlush;
     end;
     
    -Function TXmlRegistry.DoGetValueData(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer; IsUnicode : Boolean) : Boolean;
    +Function TXmlRegistry.DoGetValueData(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer; IsUnicode : Boolean) : Boolean;
     
     Type
       PCardinal = ^Cardinal;
    @@ -305,22 +305,27 @@
       D : DWord;
       
     begin
    +  //writeln('TXmlRegistry.DoGetValueData: Name=',Name,' IsUnicode=',IsUnicode);
       Node:=FindValueKey(Name);
       Result:=Node<>Nil;
       If Result then
         begin
    +    //writeln('TXmlRegistry.DoGetValueData: Node<>nil');
         DataNode:=Node.FirstChild;
         HasData:=Assigned(DataNode) and (DataNode.NodeType=TEXT_NODE);
    -    ND:=StrToIntDef(Node[Stype],0);
    +    //writeln('TXmlRegistry.DoGetValueData: HasData=',hasdata);
    +    ND:=StrToIntDef(String(Node[Stype]),0);
    +    //writeln('TXmlRegistry.DoGetValueData: ND=',ND);
         Result:=ND<=Ord(High(TDataType));
         If Result then
           begin
           DataType:=TDataType(ND);
    +      //writeln('TXmlRegistry.DoGetValueData: DataType=',DataType);
           NS:=0; // Initialize, for optional nodes.
           Case DataType of
             dtDWORD : begin   // DataNode is required
                       NS:=SizeOf(Cardinal);
    -                  Result:=HasData and TryStrToDWord(DataNode.NodeValue,D) and (DataSize>=NS);
    +                  Result:=HasData and TryStrToDWord(String(DataNode.NodeValue),D) and (DataSize>=NS);
                       if Result then
                         PCardinal(@Data)^:=D;
                       end;
    @@ -329,7 +334,7 @@
                          begin
                          if not IsUnicode then
                            begin
    -                       S:=UTF8Encode(DataNode.NodeValue); // Convert to ansistring
    +                       S:=DataNode.NodeValue; // Convert to ansistring
                            NS:=Length(S);
                            Result:=(DataSize>=NS);
                            if Result then
    @@ -350,8 +355,10 @@
                        if HasData then
                          begin
                          BL:=Length(DataNode.NodeValue);
    +                     //writeln('TXmlRegistry.DoGetValueData: BL=',BL);
                          NS:=BL div 2;
                          Result:=DataSize>=NS;
    +                     //writeln('TXmlRegistry.DoGetValueData: Result=',Result);
                          If Result then
                            // No need to check for -1, We checked NS before calling.
                            NS:=HexToBuf(DataNode.NodeValue,Data,BL);
    @@ -363,7 +370,7 @@
         end;
     end;
     
    -Function TXmlRegistry.DoSetValueData(Name : String; DataType : TDataType; Const Data; DataSize : Integer; IsUnicode : Boolean) : Boolean;
    +Function TXmlRegistry.DoSetValueData(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer; IsUnicode : Boolean) : Boolean;
     
     Type
       PCardinal = ^Cardinal;
    @@ -374,6 +381,7 @@
       SW : UnicodeString;
     
     begin
    +  writeln('TXmlRegistry.DoSetValueData A: Name=',Name,', DataType=',DataType,', DataSize=',DataSize,', IsUnicode=',IsUnicode);
       Node:=FindValueKey(Name);
       If Node=Nil then
         Node:=CreateValueKey(Name);
    @@ -380,20 +388,20 @@
       Result:=(Node<>Nil);
       If Result then
         begin
    -    Node[SType]:=IntToStr(Ord(DataType));
    +    Node[SType]:=UnicodeString(IntToStr(Ord(DataType)));
         DataNode:=Node.FirstChild;
     
         Case DataType of
    -      dtDWORD : SW:=IntToStr(PCardinal(@Data)^);
    +      dtDWORD : SW:=UnicodeString(IntToStr(PCardinal(@Data)^));
           dtString : begin
                      if IsUnicode then
                        SW:=UnicodeString(PUnicodeChar(@Data))
                      else
                        SW:=UnicodeString(PAnsiChar(@Data));
    -                   //S:=UTF8Encode(SW);
    +                   //S:=SW;
                      end;
    -      dtBinary : SW:=BufToHex(Data,DataSize);
    -      dtStrings : SW:=BufToHex(Data,DataSize);
    +      dtBinary : SW:=UnicodeString(BufToHex(Data,DataSize));
    +      dtStrings : SW:=UnicodeString(BufToHex(Data,DataSize));
         else
           sw:='';
         end;
    @@ -416,29 +424,29 @@
         end;
     end;
     
    -Function TXmlRegistry.SetValueData(Name : String; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
    +Function TXmlRegistry.SetValueData(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
     
     begin
       Result:=DoSetValueData(Name,DataType,Data,DataSize,False);
     end;
     
    -Function TXmlRegistry.GetValueData(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
    +Function TXmlRegistry.GetValueData(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
     
     begin
       Result:=DoGetValueData(Name,DataType,Data,DataSize,False);
     end;
     
    -function TXmlRegistry.GetValueDataUnicode(Name: String; out DataType: TDataType; Var Data; Var DataSize: Integer): Boolean;
    +function TXmlRegistry.GetValueDataUnicode(Name: UnicodeString; out DataType: TDataType; Var Data; Var DataSize: Integer): Boolean;
     begin
       Result:=DoGetValueData(Name,DataType,Data,DataSize,True);
     end;
     
    -function TXmlRegistry.SetValueDataUnicode(Name: String; DataType: TDataType; const Data; DataSize: Integer): Boolean;
    +function TXmlRegistry.SetValueDataUnicode(Name: UnicodeString; DataType: TDataType; const Data; DataSize: Integer): Boolean;
     begin
       Result:=DoSetValueData(Name,DataType,Data,DataSize,True)
     end;
     
    -Function TXmlRegistry.FindSubKey (S : String; N : TDomElement) : TDomElement;
    +Function TXmlRegistry.FindSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
     
     Var
       Node : TDOMNode;
    @@ -451,7 +459,7 @@
         While (Result=Nil) and (Assigned(Node)) do
           begin
           If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SKey) then
    -        If CompareText(TDomElement(Node)[SName],S)=0 then
    +        If UnicodeCompareText(TDomElement(Node)[SName],S)=0 then
               Result:=TDomElement(Node);
           Node:=Node.NextSibling;
           end;
    @@ -458,7 +466,7 @@
         end;
     end;
     
    -Function TXmlRegistry.CreateSubKey (S : String; N : TDomElement) : TDomElement;
    +Function TXmlRegistry.CreateSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
     
     begin
       Result:=FDocument.CreateElement(SKey);
    @@ -468,7 +476,7 @@
       FDirty:=True;
     end;
     
    -Function  TXmlRegistry.FindValueKey (S : String) : TDomElement;
    +Function  TXmlRegistry.FindValueKey (S : UnicodeString) : TDomElement;
     
     Var
       Node : TDOMNode;
    @@ -481,7 +489,7 @@
         While (Result=Nil) and (Assigned(Node)) do
           begin
           If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SValue) then
    -        If CompareText(TDomElement(Node)[SName],S)=0 then
    +        If UnicodeCompareText(TDomElement(Node)[SName],S)=0 then
               Result:=TDomElement(Node);
           Node:=Node.NextSibling;
           end;
    @@ -488,7 +496,7 @@
         end;
     end;
     
    -Function  TXmlRegistry.CreateValueKey (S : String) : TDomElement;
    +Function  TXmlRegistry.CreateValueKey (S : UnicodeString) : TDomElement;
     
     begin
       If Assigned(FCurrentElement) then
    @@ -581,38 +589,47 @@
         end;
     end;
     
    -Function TXMLRegistry.hexToBuf(Const Str : String; Var Buf; Var Len : Integer ) : Integer;
    +Function TXMLRegistry.HexToBuf(Const Str : UnicodeString; Var Buf; Var Len : Integer ) : Integer;
     
     Var
       NLeN,I : Integer;
       P : PByte;
    -  S : String;
    +  S : UnicodeString;
       B : Byte;
       Code : Integer;
     
     begin
    +  writeln('TXMLRegistry.HexToBuf A: Str=',Str,', Len=',Len);
       Result:=0;
       P:=@Buf;
    +  //writeln('TXMLRegistry.HexToBuf B: (p=nil)=',p=nil);
       NLen:= Length(Str) div 2;
    +  //writeln('TXMLRegistry.HexToBuf C: NLen=',NLen,', SizeOf(TDateTime)=',SizeOf(TDateTime));
       If (NLen>Len) then
         begin
         Len:=NLen;
         Exit(-1);
         end;
    -  For I:=0 to Len-1 do
    +  For I:=0 to NLen-1 do
         begin
    +    write('TXMLRegistry.HexToBuf: i=',i);
         S:='$'+Copy(Str,(I*2)+1,2);
    +    write(', S=',S);
         Val(S,B,Code);
    +    writeln(', Code=',Code);
         If Code<>0 then
    -      begin
    -      Inc(Result);
    -      B:=0;
    +      begin    //This means invalid data in the registry, why continue and increment result? Why not Exit(-1)?
    +      //Inc(Result);   //the whole function only worked because this was called as often as when Code=0, so by change
    +      //B:=0;          //it causes AV's
    +      Exit(-1);
           end;
    +    Inc(Result);
         P[I]:=B;
         end;
    +  writeln('TXMLRegistry.HexToBuf End: Result=',Result);
     end;
     
    -Function TXMLRegistry.DeleteValue(S : String) : Boolean;
    +Function TXMLRegistry.DeleteValue(S : UnicodeString) : Boolean;
     
     Var
       N : TDomElement;
    @@ -628,31 +645,31 @@
         end;
     end;
     
    -Function TXMLRegistry.GetValueSize(Name : String) : Integer;
    +Function TXMLRegistry.GetValueSize(Name : UnicodeString) : Integer;
     
     Var
       Info : TDataInfo;
     
     begin
    -  If GetValueInfo(Name,Info) then
    +  If GetValueInfo(Name,Info,True) then
         Result:=Info.DataSize
       else
         Result:=-1;
     end;
     
    -Function TXMLRegistry.GetValueType(Name : String) : TDataType;
    +Function TXMLRegistry.GetValueType(Name : UnicodeString) : TDataType;
     
     Var
       Info : TDataInfo;
     
     begin
    -  If GetValueInfo(Name,Info) then
    +  If GetValueInfo(Name,Info,True) then
         Result:=Info.DataType
       else
         Result:=dtUnknown;
     end;
     
    -function TXmlRegistry.GetValueInfo(Name: String; out Info: TDataInfo; AsUnicode: Boolean): Boolean;
    +function TXmlRegistry.GetValueInfo(Name: UnicodeString; out Info: TDataInfo; AsUnicode: Boolean): Boolean;
     
     Var
       N  : TDomElement;
    @@ -671,7 +688,7 @@
             L:=Length(DN.NodeValue)*SizeOf(UnicodeChar)
           else
             begin
    -        S := UTF8Encode(DN.NodeValue);
    +        S := DN.NodeValue;
             L:=Length(S);
             end
           end
    @@ -679,7 +696,7 @@
           L:=0;
         With Info do
           begin
    -      DataType:=TDataType(StrToIntDef(N[SType],0));
    +      DataType:=TDataType(StrToIntDef(String(N[SType]),0));
           Case DataType of
             dtUnknown : DataSize:=0;
             dtDword   : Datasize:=SizeOf(Cardinal);
    @@ -724,10 +741,10 @@
                   ValueLen:=L;
                 DataNode:=TDomElement(Node).FirstChild;
                 If (DataNode<>Nil) and (DataNode is TDomText) then
    -              Case TDataType(StrToIntDef(TDomElement(Node)[SType],0)) of
    +              Case TDataType(StrToIntDef(String(TDomElement(Node)[SType]),0)) of
                     dtUnknown : L:=0;
                     dtDWord   : L:=4;
    -                DtString  : L:=Length(UTF8Encode(DataNode.NodeValue));
    +                DtString  : L:=Length(String(DataNode.NodeValue));
                     dtBinary  : L:=Length(DataNode.NodeValue) div 2;
                   end
                 else
    @@ -782,13 +799,13 @@
         end;
     end;
     
    -Function TXMLRegistry.KeyExists(KeyPath : String) : Boolean;
    +Function TXMLRegistry.KeyExists(KeyPath : UnicodeString) : Boolean;
     
     begin
       Result:=FindKey(KeyPath)<>Nil;
     end;
     
    -Function TXMLRegistry.RenameValue(Const OldName,NewName : String) : Boolean;
    +Function TXMLRegistry.RenameValue(Const OldName,NewName : UnicodeString) : Boolean;
     
     Var
       N : TDomElement;
    @@ -804,10 +821,10 @@
         end;
     end;
     
    -Function TXMLRegistry.FindKey (S : String) : TDomElement;
    +Function TXMLRegistry.FindKey (S : UnicodeString) : TDomElement;
     
     Var
    -  SubKey : String;
    +  SubKey : UnicodeString;
       P : Integer;
       Node : TDomElement;
     
    @@ -840,7 +857,7 @@
       Until (Result=Nil) or (Length(S)=0);
     end;
     
    -Function  TXmlRegistry.ValueExists(ValueName : String) : Boolean;
    +Function  TXmlRegistry.ValueExists(ValueName : UnicodeString) : Boolean;
     
     begin
       Result:=FindValueKey(ValueName)<>Nil;
    Index: packages/fcl-registry/src/xregreg.inc
    ===================================================================
    --- packages/fcl-registry/src/xregreg.inc	(revision 41667)
    +++ packages/fcl-registry/src/xregreg.inc	(working copy)
    @@ -47,7 +47,7 @@
         Class Var XMLRegistryCache: Tlist;
         Class procedure FreeXMLRegistryCache;
       public
    -    constructor Create(AFileName : String);
    +    constructor Create(AFileName : UnicodeString);
         Class Function GetXMLRegistry(aFileName: string): TXMLRegistry;
         Class Procedure FreeXMLRegistry(XMLRegistry: TXMLRegistry);
         procedure IncRefCount;
    @@ -97,7 +97,7 @@
     
     { TXMLRegistryInstance }
     
    -constructor TXMLRegistryInstance.Create(AFileName: String);
    +constructor TXMLRegistryInstance.Create(AFileName: UnicodeString);
     begin
       inherited;
       FRefCount := 1;
    @@ -116,7 +116,9 @@
     procedure TRegistry.SysRegCreate;
     var s : string;
     begin
    +  FStringSizeIncludesNull:=False;
       s:=includetrailingpathdelimiter(GetAppConfigDir(GlobalXMLFile));
    +s:='.\';//**********UNDO THIS
       ForceDirectories(s);
       FSysData:=TXMLRegistryInstance.GetXMLRegistry(s+XFileName);
       TXmlRegistry(FSysData).AutoFlush:=False;
    @@ -130,24 +132,24 @@
       TXMLRegistryInstance.FreeXMLRegistry(TXMLRegistry(FSysData));
     end;
     
    -function TRegistry.SysCreateKey(const Key: String): Boolean;
    +function TRegistry.SysCreateKey(Key: UnicodeString): Boolean;
     
     begin
       Result:=TXmlRegistry(FSysData).CreateKey(Key);
     end;
     
    -function TRegistry.DeleteKey(const Key: string): Boolean;
    +function TRegistry.DeleteKey(const Key: UnicodeString): Boolean;
     
     begin
       Result:=TXMLRegistry(FSysData).DeleteKey(Key);
     end;
     
    -function TRegistry.DeleteValue(const Name: string): Boolean;
    +function TRegistry.DeleteValue(const Name: UnicodeString): Boolean;
     begin
       Result:=TXmlRegistry(FSysData).DeleteValue(Name);
     end;
     
    -function TRegistry.SysGetData(const Name: String; Buffer: Pointer;
    +function TRegistry.SysGetData(const Name: UnicodeString; Buffer: Pointer;
               BufSize: Integer; Out RegData: TRegDataType): Integer;
     
     Var
    @@ -160,7 +162,7 @@
         Result:=-1;
     end;
     
    -function TRegistry.GetDataInfo(const ValueName: string; out Value: TRegDataInfo): Boolean;
    +function TRegistry.GetDataInfo(const ValueName: UnicodeString; out Value: TRegDataInfo): Boolean;
     
     Var
       Info : TDataInfo;
    @@ -181,7 +183,7 @@
           end;
     end;
     
    -function TRegistry.GetKey(const Key: string): HKEY;
    +function TRegistry.GetKey(Key: UnicodeString): HKEY;
     begin
       Result := 0;
     end;
    @@ -205,17 +207,17 @@
           end;
     end;
     
    -function TRegistry.KeyExists(const Key: string): Boolean;
    +function TRegistry.KeyExists(const Key: UnicodeString): Boolean;
     begin
       Result:=TXmlRegistry(FSysData).KeyExists(Key);
     end;
     
    -function TRegistry.LoadKey(const Key, FileName: string): Boolean;
    +function TRegistry.LoadKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.OpenKey(const Key: string; CanCreate: Boolean): Boolean;
    +function TRegistry.OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
     
     begin
       Result:=TXmlRegistry(FSysData).SetKey(Key,CanCreate);
    @@ -222,43 +224,43 @@
       FCurrentKey:=1;
     end;
     
    -function TRegistry.OpenKeyReadOnly(const Key: string): Boolean;
    +function TRegistry.OpenKeyReadOnly(const Key: UnicodeString): Boolean;
     
     begin
       Result:=TXmlRegistry(FSysData).SetKey(Key,False);
     end;
     
    -function TRegistry.RegistryConnect(const UNCName: string): Boolean;
    +function TRegistry.RegistryConnect(const UNCName: UnicodeString): Boolean;
     begin
       Result := True;
     end;
     
    -function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
    +function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.RestoreKey(const Key, FileName: string): Boolean;
    +function TRegistry.RestoreKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.SaveKey(const Key, FileName: string): Boolean;
    +function TRegistry.SaveKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.UnLoadKey(const Key: string): Boolean;
    +function TRegistry.UnLoadKey(const Key: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.ValueExists(const Name: string): Boolean;
    +function TRegistry.ValueExists(const Name: UnicodeString): Boolean;
     begin
       Result := TXmlRegistry(FSysData).ValueExists(Name);
     end;
     
    -procedure TRegistry.ChangeKey(Value: HKey; const Path: string);
    +procedure TRegistry.ChangeKey(Value: HKey; const Path: UnicodeString);
     begin
     
     end;
    @@ -274,7 +276,7 @@
     end;
     
     
    -function TRegistry.SysPutData(const Name: string; Buffer: Pointer;
    +function TRegistry.SysPutData(const Name: UnicodeString; Buffer: Pointer;
       BufSize: Integer; RegData: TRegDataType): Boolean;
     
     Var
    @@ -281,11 +283,13 @@
       DataType : TDataType;
     
     begin
    +  //writeln('TRegistry.SysPutData: Name=',Name,', RegData=',RegData,', BufSize=',BufSize);
       DataType:=RegDataTypeToXmlDataType(RegData);
    +
       Result:=TXMLRegistry(FSysData).SetValueDataUnicode(Name,DataType,Buffer^,BufSize);
     end;
     
    -procedure TRegistry.RenameValue(const OldName, NewName: string);
    +procedure TRegistry.RenameValue(const OldName, NewName: UnicodeString);
     begin
       TXMLRegistry(FSysData).RenameValue(OldName,NewName);
     end;
    
  • registry.unicode.part4.diff (64,132 bytes)
    Index: packages/fcl-registry/src/regdef.inc
    ===================================================================
    --- packages/fcl-registry/src/regdef.inc	(revision 41667)
    +++ packages/fcl-registry/src/regdef.inc	(working copy)
    @@ -2,7 +2,7 @@
       HKEY = THandle;
       PHKEY = ^HKEY;
       
    -{$ifdef windows}
    +{$if defined(windows) and not defined(XMLREG)}
     
     { Direct mapping to constants in Windows unit }
     
    Index: packages/fcl-registry/src/registry.pp
    ===================================================================
    --- packages/fcl-registry/src/registry.pp	(revision 41667)
    +++ packages/fcl-registry/src/registry.pp	(working copy)
    @@ -39,6 +39,8 @@
         DataSize: Integer;
       end;
     
    +  TUnicodeStringArray = Array of UnicodeString;
    +
     { ---------------------------------------------------------------------
         TRegistry
       ---------------------------------------------------------------------}
    @@ -54,22 +56,31 @@
         fCurrentKey: HKEY;
         fRootKey: HKEY;
         fLazyWrite: Boolean;
    -    fCurrentPath: string;
    +    fCurrentPath: UnicodeString;
         function GetLastErrorMsg: string;
    +    function RegMultiSzDataToUnicodeStringArray(U: UnicodeString): TUnicodeStringArray;
    +    function ListToArray(List: TStrings; IsUtf8: Boolean): TUnicodeStringArray;
    +    procedure ArrayToList(const Arr: TUnicodeStringArray; List: TStrings; ForceUtf8: Boolean);
         procedure SetRootKey(Value: HKEY);
         Procedure SysRegCreate;
         Procedure SysRegFree;
    -    Function  SysGetData(const Name: String; Buffer: Pointer; BufSize: Integer; Out RegData: TRegDataType): Integer;
    -    Function  SysPutData(const Name: string; Buffer: Pointer; BufSize: Integer; RegData: TRegDataType) : Boolean;
    -    Function  SysCreateKey(const Key: String): Boolean;
    +    Function  SysGetData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; Out RegData: TRegDataType): Integer;
    +    Function  SysPutData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; RegData: TRegDataType) : Boolean;
    +    Function  SysCreateKey(Key: UnicodeString): Boolean;
       protected
         function GetBaseKey(Relative: Boolean): HKey;
    -    function GetData(const Name: string; Buffer: Pointer;
    +    function GetData(const Name: UnicodeString; Buffer: Pointer;
                       BufSize: Integer; Out RegData: TRegDataType): Integer;
    -    function GetKey(const Key: string): HKEY;
    -    procedure ChangeKey(Value: HKey; const Path: string);
    -    procedure PutData(const Name: string; Buffer: Pointer;
    +    function GetData(const Name: String; Buffer: Pointer;
    +                  BufSize: Integer; Out RegData: TRegDataType): Integer;
    +    function GetKey(Key: UnicodeString): HKEY;
    +    function GetKey(Key: String): HKEY;
    +    procedure ChangeKey(Value: HKey; const Path: UnicodeString);
    +    procedure ChangeKey(Value: HKey; const Path: String);
    +    procedure PutData(const Name: UnicodeString; Buffer: Pointer;
                       BufSize: Integer; RegData: TRegDataType);
    +    procedure PutData(const Name: String; Buffer: Pointer;
    +                  BufSize: Integer; RegData: TRegDataType);
         procedure SetCurrentKey(Value: HKEY);
       public
         constructor Create; overload;
    @@ -76,58 +87,106 @@
         constructor Create(aaccess:longword); overload;
         destructor Destroy; override;
     
    -    function CreateKey(const Key: string): Boolean;
    -    function DeleteKey(const Key: string): Boolean;
    -    function DeleteValue(const Name: string): Boolean;
    -    function GetDataInfo(const ValueName: string; Out Value: TRegDataInfo): Boolean;
    -    function GetDataSize(const ValueName: string): Integer;
    -    function GetDataType(const ValueName: string): TRegDataType;
    +    function CreateKey(const Key: UnicodeString): Boolean;
    +    function CreateKey(const Key: String): Boolean;
    +    function DeleteKey(const Key: UnicodeString): Boolean;
    +    function DeleteKey(const Key: String): Boolean;
    +    function DeleteValue(const Name: UnicodeString): Boolean;
    +    function DeleteValue(const Name: String): Boolean;
    +    function GetDataInfo(const ValueName: UnicodeString; Out Value: TRegDataInfo): Boolean;
    +    function GetDataInfo(const ValueName: String; Out Value: TRegDataInfo): Boolean;
    +    function GetDataSize(const ValueName: UnicodeString): Integer;
    +    function GetDataSize(const ValueName: String): Integer;
    +    function GetDataType(const ValueName: UnicodeString): TRegDataType;
    +    function GetDataType(const ValueName: String): TRegDataType;
         function GetKeyInfo(Out Value: TRegKeyInfo): Boolean;
         function HasSubKeys: Boolean;
    -    function KeyExists(const Key: string): Boolean;
    -    function LoadKey(const Key, FileName: string): Boolean;
    -    function OpenKey(const Key: string; CanCreate: Boolean): Boolean;
    -    function OpenKeyReadOnly(const Key: string): Boolean;
    -    function ReadCurrency(const Name: string): Currency;
    -    function ReadBinaryData(const Name: string; var Buffer; BufSize: Integer): Integer;
    -    function ReadBool(const Name: string): Boolean;
    -    function ReadDate(const Name: string): TDateTime;
    -    function ReadDateTime(const Name: string): TDateTime;
    -    function ReadFloat(const Name: string): Double;
    -    function ReadInteger(const Name: string): Integer;
    -    function ReadInt64(const Name: string): Int64;
    -    function ReadString(const Name: string): string;
    -    procedure ReadStringList(const Name: string; AList: TStrings);
    -    function ReadTime(const Name: string): TDateTime;
    -    function RegistryConnect(const UNCName: string): Boolean;
    -    function ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
    -    function RestoreKey(const Key, FileName: string): Boolean;
    -    function SaveKey(const Key, FileName: string): Boolean;
    -    function UnLoadKey(const Key: string): Boolean;
    -    function ValueExists(const Name: string): Boolean;
    +    function KeyExists(const Key: UnicodeString): Boolean;
    +    function KeyExists(const Key: String): Boolean;
    +    function LoadKey(const Key, FileName: UnicodeString): Boolean;
    +    function LoadKey(const Key, FileName: String): Boolean;
    +    function OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
    +    function OpenKey(const Key: String; CanCreate: Boolean): Boolean;
    +    function OpenKeyReadOnly(const Key: UnicodeString): Boolean;
    +    function OpenKeyReadOnly(const Key: String): Boolean;
    +    function ReadCurrency(const Name: UnicodeString): Currency;
    +    function ReadCurrency(const Name: String): Currency;
    +    function ReadBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer): Integer;
    +    function ReadBinaryData(const Name: String; var Buffer; BufSize: Integer): Integer;
    +    function ReadBool(const Name: UnicodeString): Boolean;
    +    function ReadBool(const Name: String): Boolean;
    +    function ReadDate(const Name: UnicodeString): TDateTime;
    +    function ReadDate(const Name: String): TDateTime;
    +    function ReadDateTime(const Name: UnicodeString): TDateTime;
    +    function ReadDateTime(const Name: String): TDateTime;
    +    function ReadFloat(const Name: UnicodeString): Double;
    +    function ReadFloat(const Name: String): Double;
    +    function ReadInteger(const Name: UnicodeString): Integer;
    +    function ReadInteger(const Name: String): Integer;
    +    function ReadInt64(const Name: UnicodeString): Int64;
    +    function ReadInt64(const Name: String): Int64;
    +    function ReadString(const Name: UnicodeString): UnicodeString;
    +    function ReadString(const Name: String): string;
    +    procedure ReadStringList(const Name: UnicodeString; AList: TStrings; ForceUtf8: Boolean=False);
    +    procedure ReadStringList(const Name: String; AList: TStrings);
    +    function ReadStringArray(const Name: UnicodeString): TUnicodeStringArray;
    +    function ReadStringArray(const Name: String): TStringArray;
    +    function ReadTime(const Name: UnicodeString): TDateTime;
    +    function ReadTime(const Name: String): TDateTime;
    +    function RegistryConnect(const UNCName: UnicodeString): Boolean;
    +    function RegistryConnect(const UNCName: String): Boolean;
    +    function ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
    +    function ReplaceKey(const Key, FileName, BackUpFileName: String): Boolean;
    +    function RestoreKey(const Key, FileName: UnicodeString): Boolean;
    +    function RestoreKey(const Key, FileName: String): Boolean;
    +    function SaveKey(const Key, FileName: UnicodeString): Boolean;
    +    function SaveKey(const Key, FileName: String): Boolean;
    +    function UnLoadKey(const Key: UnicodeString): Boolean;
    +    function UnLoadKey(const Key: String): Boolean;
    +    function ValueExists(const Name: UnicodeString): Boolean;
    +    function ValueExists(const Name: String): Boolean;
     
         procedure CloseKey;
         procedure CloseKey(key:HKEY);
         procedure GetKeyNames(Strings: TStrings);
    +    //ToDo
    +    //function GetKeyNames: TUnicodeStringArray;
         procedure GetValueNames(Strings: TStrings);
    -    procedure MoveKey(const OldName, NewName: string; Delete: Boolean);
    -    procedure RenameValue(const OldName, NewName: string);
    -    procedure WriteCurrency(const Name: string; Value: Currency);
    -    procedure WriteBinaryData(const Name: string; var Buffer; BufSize: Integer);
    -    procedure WriteBool(const Name: string; Value: Boolean);
    -    procedure WriteDate(const Name: string; Value: TDateTime);
    -    procedure WriteDateTime(const Name: string; Value: TDateTime);
    -    procedure WriteFloat(const Name: string; Value: Double);
    -    procedure WriteInteger(const Name: string; Value: Integer);
    -    procedure WriteInt64(const Name: string; Value: Int64);
    -    procedure WriteString(const Name, Value: string);
    -    procedure WriteExpandString(const Name, Value: string);
    -    procedure WriteStringList(const Name: string; List: TStrings);
    -    procedure WriteTime(const Name: string; Value: TDateTime);
    +    //ToDo
    +    //function GetValueNames: TUnicodeStringArray;
    +    procedure MoveKey(const OldName, NewName: UnicodeString; Delete: Boolean);
    +    procedure MoveKey(const OldName, NewName: String; Delete: Boolean);
    +    procedure RenameValue(const OldName, NewName: UnicodeString);
    +    procedure RenameValue(const OldName, NewName: String);
    +    procedure WriteCurrency(const Name: UnicodeString; Value: Currency);
    +    procedure WriteCurrency(const Name: String; Value: Currency);
    +    procedure WriteBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer);
    +    procedure WriteBinaryData(const Name: String; var Buffer; BufSize: Integer);
    +    procedure WriteBool(const Name: UnicodeString; Value: Boolean);
    +    procedure WriteBool(const Name: String; Value: Boolean);
    +    procedure WriteDate(const Name: UnicodeString; Value: TDateTime);
    +    procedure WriteDate(const Name: String; Value: TDateTime);
    +    procedure WriteDateTime(const Name: UnicodeString; Value: TDateTime);
    +    procedure WriteDateTime(const Name: String; Value: TDateTime);
    +    procedure WriteFloat(const Name: UnicodeString; Value: Double);
    +    procedure WriteFloat(const Name: String; Value: Double);
    +    procedure WriteInteger(const Name: UnicodeString; Value: Integer);
    +    procedure WriteInteger(const Name: String; Value: Integer);
    +    procedure WriteInt64(const Name: UnicodeString; Value: Int64);
    +    procedure WriteInt64(const Name: String; Value: Int64);
    +    procedure WriteString(const Name, Value: UnicodeString);
    +    procedure WriteString(const Name, Value: String);
    +    procedure WriteExpandString(const Name, Value: UnicodeString);
    +    procedure WriteExpandString(const Name, Value: String);
    +    procedure WriteStringList(const Name: UnicodeString; List: TStrings; IsUtf8: Boolean=False);
    +    procedure WriteStringArray(const Name: UnicodeString; const Arr: TUnicodeStringArray);
    +    procedure WriteStringArray(const Name: String; const Arr: TStringArray);
    +    procedure WriteTime(const Name: UnicodeString; Value: TDateTime);
    +    procedure WriteTime(const Name: String; Value: TDateTime);
     
         property Access: LongWord read fAccess write fAccess;
         property CurrentKey: HKEY read fCurrentKey;
    -    property CurrentPath: string read fCurrentPath;
    +    property CurrentPath: UnicodeString read fCurrentPath;
         property LazyWrite: Boolean read fLazyWrite write fLazyWrite;
         property RootKey: HKEY read fRootKey write SetRootKey;
         Property StringSizeIncludesNull : Boolean read FStringSizeIncludesNull;
    @@ -235,6 +294,16 @@
         Generic, implementation-independent code.
       ---------------------------------------------------------------------}
     
    +{$ifdef DebugRegistry}
    +function DbgS(const S: UnicodeString): String;
    +var
    +  C: WideChar;
    +begin
    +  Result := '';
    +  for C in S do Result := Result + IntToHex(Word(C),4) + #32;
    +  Result := TrimRight(Result);
    +end;
    +{$endif}
     
     constructor TRegistry.Create;
     
    @@ -261,7 +330,7 @@
       inherited Destroy;
     end;
     
    -function TRegistry.CreateKey(const Key: string): Boolean;
    +function TRegistry.CreateKey(const Key: UnicodeString): Boolean;
     
     begin
       Result:=SysCreateKey(Key);
    @@ -269,6 +338,27 @@
         Raise ERegistryException.CreateFmt(SRegCreateFailed, [Key]);
     end;
     
    +function TRegistry.CreateKey(const Key: String): Boolean;
    +begin
    +  Result:=CreateKey(UnicodeString(Key));
    +end;
    +
    +function TRegistry.DeleteKey(const Key: String): Boolean;
    +begin
    +  Result:=DeleteKey(UnicodeString(Key));
    +end;
    +
    +function TRegistry.DeleteValue(const Name: String): Boolean;
    +begin
    +  Result:=DeleteValue(UnicodeString(Name));
    +end;
    +
    +function TRegistry.GetDataInfo(const ValueName: String; out Value: TRegDataInfo
    +  ): Boolean;
    +begin
    +  Result:=GetDataInfo(UnicodeString(ValueName), Value);
    +end;
    +
     function TRegistry.GetBaseKey(Relative: Boolean): HKey;
     begin
       If Relative and (CurrentKey<>0) Then
    @@ -277,7 +367,7 @@
         Result := RootKey;
     end;
     
    -function TRegistry.GetData(const Name: string; Buffer: Pointer; BufSize: Integer; out RegData: TRegDataType): Integer;
    +function TRegistry.GetData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; out RegData: TRegDataType): Integer;
     begin
       Result:=SysGetData(Name,Buffer,BufSize,RegData);
       If (Result=-1) then
    @@ -284,7 +374,24 @@
         Raise ERegistryException.CreateFmt(SRegGetDataFailed, [Name]);
     end;
     
    -procedure TRegistry.PutData(const Name: string; Buffer: Pointer;
    +function TRegistry.GetData(const Name: String; Buffer: Pointer;
    +  BufSize: Integer; out RegData: TRegDataType): Integer;
    +begin
    +  Result:=GetData(UnicodeString(Name), Buffer, BufSize, RegData);
    +end;
    +
    +function TRegistry.GetKey(Key: String): HKEY;
    +begin
    +  Result:=GetKey(UnicodeString(Key));
    +end;
    +
    +procedure TRegistry.ChangeKey(Value: HKey; const Path: String);
    +begin
    +  ChangeKey(Value, UnicodeString(Path));
    +end;
    +
    +
    +procedure TRegistry.PutData(const Name: UnicodeString; Buffer: Pointer;
       BufSize: Integer; RegData: TRegDataType);
     
     begin
    @@ -292,9 +399,15 @@
         Raise ERegistryException.CreateFmt(SRegSetDataFailed, [Name]);
     end;
     
    +procedure TRegistry.PutData(const Name: String; Buffer: Pointer;
    +  BufSize: Integer; RegData: TRegDataType);
    +begin
    +  PutData(UnicodeString(Name), Buffer, BufSize, RegData);
    +end;
     
    -function TRegistry.GetDataSize(const ValueName: string): Integer;
     
    +function TRegistry.GetDataSize(const ValueName: UnicodeString): Integer;
    +
     Var
       Info: TRegDataInfo;
     
    @@ -305,8 +418,13 @@
         Result := -1;
     end;
     
    -function TRegistry.GetDataType(const ValueName: string): TRegDataType;
    +function TRegistry.GetDataSize(const ValueName: String): Integer;
    +begin
    +  Result:=GetDataSize(UnicodeString(ValueName));
    +end;
     
    +function TRegistry.GetDataType(const ValueName: UnicodeString): TRegDataType;
    +
     Var
       Info: TRegDataInfo;
     
    @@ -315,6 +433,32 @@
       Result:=Info.RegData;
     end;
     
    +function TRegistry.GetDataType(const ValueName: String): TRegDataType;
    +begin
    +  Result:=GetDataType(UnicodeString(ValueName));
    +end;
    +
    +
    +function TRegistry.KeyExists(const Key: String): Boolean;
    +begin
    +  Result:=KeyExists(UnicodeString(Key));
    +end;
    +
    +function TRegistry.LoadKey(const Key, FileName: String): Boolean;
    +begin
    +  Result:=LoadKey(UnicodeString(Key), UnicodeString(FileName));
    +end;
    +
    +function TRegistry.OpenKey(const Key: String; CanCreate: Boolean): Boolean;
    +begin
    +  Result:=OpenKey(UnicodeString(Key), CanCreate);
    +end;
    +
    +function TRegistry.OpenKeyReadOnly(const Key: String): Boolean;
    +begin
    +  Result:=OpenKeyReadOnly(UnicodeString(Key));
    +end;
    +
     function TRegistry.HasSubKeys: Boolean;
     
     Var
    @@ -326,7 +470,7 @@
         Result:=(Info.NumSubKeys>0);
     end;
     
    -function TRegistry.ReadBinaryData(const Name: string; var Buffer; BufSize: Integer): Integer;
    +function TRegistry.ReadBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer): Integer;
     
     Var
       RegDataType: TRegDataType;
    @@ -337,8 +481,14 @@
         Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
     end;
     
    -function TRegistry.ReadInteger(const Name: string): Integer;
    +function TRegistry.ReadBinaryData(const Name: String; var Buffer;
    +  BufSize: Integer): Integer;
    +begin
    +  Result:=ReadBinaryData(UnicodeString(Name), Buffer, BufSize);
    +end;
     
    +function TRegistry.ReadInteger(const Name: UnicodeString): Integer;
    +
     Var
       RegDataType: TRegDataType;
     
    @@ -348,8 +498,13 @@
         Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
     end;
     
    -function TRegistry.ReadInt64(const Name: string): Int64;
    +function TRegistry.ReadInteger(const Name: String): Integer;
    +begin
    +  Result:=ReadInteger(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadInt64(const Name: UnicodeString): Int64;
    +
     Var
       RegDataType: TRegDataType;
     
    @@ -359,21 +514,36 @@
         Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
     end;
     
    -function TRegistry.ReadBool(const Name: string): Boolean;
    +function TRegistry.ReadInt64(const Name: String): Int64;
    +begin
    +  Result:=ReadInt64(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadBool(const Name: UnicodeString): Boolean;
    +
     begin
       Result:=ReadInteger(Name)<>0;
     end;
     
    -function TRegistry.ReadCurrency(const Name: string): Currency;
    +function TRegistry.ReadBool(const Name: String): Boolean;
    +begin
    +  Result:=ReadBool(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadCurrency(const Name: UnicodeString): Currency;
    +
     begin
       Result:=Default(Currency);
       ReadBinaryData(Name, Result, SizeOf(Currency));
     end;
     
    -function TRegistry.ReadDate(const Name: string): TDateTime;
    +function TRegistry.ReadCurrency(const Name: String): Currency;
    +begin
    +  Result:=ReadCurrency(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadDate(const Name: UnicodeString): TDateTime;
    +
     begin
       Result:=Default(TDateTime);
       ReadBinaryData(Name, Result, SizeOf(TDateTime));
    @@ -380,22 +550,37 @@
       Result:=Trunc(Result);
     end;
     
    -function TRegistry.ReadDateTime(const Name: string): TDateTime;
    +function TRegistry.ReadDate(const Name: String): TDateTime;
    +begin
    +  Result:=ReadDate(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadDateTime(const Name: UnicodeString): TDateTime;
    +
     begin
       Result:=Default(TDateTime);
       ReadBinaryData(Name, Result, SizeOf(TDateTime));
     end;
     
    -function TRegistry.ReadFloat(const Name: string): Double;
    +function TRegistry.ReadDateTime(const Name: String): TDateTime;
    +begin
    +  Result:=ReadDateTime(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadFloat(const Name: UnicodeString): Double;
    +
     begin
       Result:=Default(Double);
       ReadBinaryData(Name,Result,SizeOf(Double));
     end;
     
    -function TRegistry.ReadString(const Name: string): string;
    +function TRegistry.ReadFloat(const Name: String): Double;
    +begin
    +  Result:=ReadFloat(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadString(const Name: UnicodeString): UnicodeString;
    +
     Var
       Info : TRegDataInfo;
       ReadDataSize: Integer;
    @@ -421,47 +606,142 @@
           if StringSizeIncludesNull and
              (u[Length(u)] = WideChar(0)) then
             SetLength(u,Length(u)-1);
    -      Result:=UTF8Encode(u);
    +      Result:=u;
         end;
       end;
     end;
     
    -procedure TRegistry.ReadStringList(const Name: string; AList: TStrings);
    +function TRegistry.ReadString(const Name: String): string;
    +begin
    +  Result:=ReadString(UnicodeString(Name));
    +end;
     
    +
    +procedure TRegistry.ReadStringList(const Name: UnicodeString; AList: TStrings; ForceUtf8: Boolean=False);
    +
     Var
       Info : TRegDataInfo;
    -  ReadDataSize: Integer;
    -  Data: string;
    +  ReadDataSize, i: Integer;
    +  Data: UnicodeString;
    +  UArr: TUnicodeStringArray;
     
     begin
    -  AList.Clear;
    +  UArr := ReadStringArray(Name);
    +  ArrayToList(UArr, AList, ForceUtf8);
    +end;
    +
    +procedure TRegistry.ReadStringList(const Name: String; AList: TStrings);
    +begin
    +  ReadStringList(UnicodeString(Name), AList);
    +end;
    +
    +function TRegistry.RegMultiSzDataToUnicodeStringArray(U: UnicodeString): TUnicodeStringArray;
    +var
    +  Len, i, p: Integer;
    +  Sub: UnicodeString;
    +begin
    +  Result := nil;
    +  if (U = '') then Exit;
    +  Len := 1;
    +  for i := 1 to Length(U) do if (U[i] = #0) then Inc(Len);
    +  SetLength(Result, Len);
    +  i := 0;
    +
    +  while (U <> '') and (i < Length(Result)) do
    +  begin
    +    p := Pos(#0, U);
    +    if (p = 0) then p := Length(U) + 1;
    +    Sub := Copy(U, 1, p - 1);
    +    Result[i] := Sub;
    +    System.Delete(U, 1, p);
    +    Inc(i);
    +  end;
    +end;
    +
    +function TRegistry.ListToArray(List: TStrings; IsUtf8: Boolean): TUnicodeStringArray;
    +var
    +  i, curr, Len: Integer;
    +  u: UnicodeString;
    +begin
    +  Result := nil;
    +  Len := List.Count;
    +  SetLength(Result, Len);
    +  //REG_MULTI_SZ data cannot contain empty strings
    +  curr := 0;
    +  for i := 0 to List.Count - 1 do
    +  begin
    +    if IsUtf8 then
    +      u := Utf8Decode(List[i])
    +    else
    +      u := List[i];
    +    if (u>'') then
    +    begin
    +      Result[curr] := u;
    +      inc(curr);
    +    end
    +    else
    +      Dec(Len);
    +  end;
    +  if (Len <> List.Count) then SetLength(Result, Len);
    +end;
    +
    +procedure TRegistry.ArrayToList(const Arr: TUnicodeStringArray; List: TStrings; ForceUtf8: Boolean);
    +var
    +  i: Integer;
    +begin
    +  List.Clear;
    +  for i := Low(Arr) to High(Arr) do
    +  begin
    +    if ForceUtf8 then
    +      List.Add(Utf8Encode(Arr[i]))
    +    else
    +      List.Add(String(Arr[i]));
    +  end;
    +end;
    +
    +function TRegistry.ReadStringArray(const Name: UnicodeString): TUnicodeStringArray;
    +Var
    +  Info : TRegDataInfo;
    +  ReadDataSize, i: Integer;
    +  Data: UnicodeString;
    +
    +begin
    +  Result := nil;
       GetDataInfo(Name,Info);
    +  //writeln('TRegistry.ReadStringArray: datasize=',info.datasize);
       if info.datasize>0 then
         begin
          If Not (Info.RegData in [rdMultiString]) then
            Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
          SetLength(Data,Info.DataSize);
    -     ReadDataSize := GetData(Name,PChar(Data),Info.DataSize,Info.RegData);
    +     ReadDataSize := GetData(Name,PWideChar(Data),Info.DataSize,Info.RegData) div SizeOf(WideChar);
    +     //writeln('TRegistry.ReadStringArray: ReadDataSize=',ReadDataSize);
          if ReadDataSize > 0 then
          begin
    -       // If the data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type,
    -       // the size includes any terminating null character or characters
    -       // unless the data was stored without them! (RegQueryValueEx @ MSDN)
    -       if StringSizeIncludesNull then begin
    -         if Data[ReadDataSize] = #0 then
    -           Dec(ReadDataSize);
    -         if Data[ReadDataSize] = #0 then
    -           Dec(ReadDataSize);
    -       end;
    +       // Windows returns the data with or without trailing zero's, so just strip all trailing null characters
    +        while (Data[ReadDataSize] = #0) do Dec(ReadDataSize);
            SetLength(Data, ReadDataSize);
    -       Data := StringReplace(Data, #0, LineEnding, [rfReplaceAll]);
    -       AList.Text := Data;
    +       //writeln('Data=',dbgs(data));
    +       //Data := UnicodeStringReplace(Data, #0, AList.LineBreak, [rfReplaceAll]);
    +       //AList.Text := Data;
    +       Result := RegMultiSzDataToUnicodeStringArray(Data);
          end
        end
     end;
     
    -function TRegistry.ReadTime(const Name: string): TDateTime;
    +function TRegistry.ReadStringArray(const Name: String): TStringArray;
    +var
    +  UArr: TUnicodeStringArray;
    +  i: Integer;
    +begin
    +  Result := nil;
    +  UArr := ReadStringArray(UnicodeString(Name));
    +  SetLength(Result, Length(UArr));
    +  for i := Low(UArr) to High(UArr) do Result[i] := UArr[i];
    +end;
     
    +function TRegistry.ReadTime(const Name: UnicodeString): TDateTime;
    +
     begin
       Result:=Default(TDateTime);
       ReadBinaryData(Name, Result, SizeOf(TDateTime));
    @@ -468,85 +748,214 @@
       Result:=Frac(Result);
     end;
     
    -procedure TRegistry.WriteBinaryData(const Name: string; var Buffer; BufSize: Integer);
    +function TRegistry.ReadTime(const Name: String): TDateTime;
     begin
    +  Result:=ReadTime(UnicodeString(Name));
    +end;
    +
    +function TRegistry.RegistryConnect(const UNCName: String): Boolean;
    +begin
    +  Result:=RegistryConnect(UnicodeString(UNCName));
    +end;
    +
    +function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: String): Boolean;
    +begin
    +  Result:=ReplaceKey(UnicodeString(Key), UnicodeString(FileName), UnicodeString(BackUpFileName))
    +end;
    +
    +function TRegistry.RestoreKey(const Key, FileName: String): Boolean;
    +begin
    +  Result:=RestoreKey(UnicodeString(Key), UnicodeString(FileName));
    +end;
    +
    +function TRegistry.SaveKey(const Key, FileName: String): Boolean;
    +begin
    +  Result:=SaveKey(UnicodeString(Key), UnicodeString(FileName));
    +end;
    +
    +function TRegistry.UnLoadKey(const Key: String): Boolean;
    +begin
    +  Result:=UnloadKey(UnicodeString(Key));
    +end;
    +
    +function TRegistry.ValueExists(const Name: String): Boolean;
    +begin
    +  Result:=ValueExists(UnicodeString(Name));
    +end;
    +
    +procedure TRegistry.WriteBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer);
    +begin
       PutData(Name, @Buffer, BufSize, rdBinary);
     end;
     
    -procedure TRegistry.WriteBool(const Name: string; Value: Boolean);
    +procedure TRegistry.WriteBinaryData(const Name: String; var Buffer;
    +  BufSize: Integer);
    +begin
    +  WriteBinaryData(UnicodeString(Name), Buffer, BufSize);
    +end;
     
    +procedure TRegistry.WriteBool(const Name: UnicodeString; Value: Boolean);
    +
     begin
       WriteInteger(Name,Ord(Value));
     end;
     
    -procedure TRegistry.WriteCurrency(const Name: string; Value: Currency);
    +procedure TRegistry.WriteBool(const Name: String; Value: Boolean);
     begin
    +  WriteBool(UnicodeString(Name), Value);
    +end;
    +
    +procedure TRegistry.WriteCurrency(const Name: UnicodeString; Value: Currency);
    +begin
       WriteBinaryData(Name, Value, SizeOf(Currency));
     end;
     
    -procedure TRegistry.WriteDate(const Name: string; Value: TDateTime);
    +procedure TRegistry.WriteCurrency(const Name: String; Value: Currency);
     begin
    +  WriteCurrency(UnicodeString(Name), Value);
    +end;
    +
    +procedure TRegistry.WriteDate(const Name: UnicodeString; Value: TDateTime);
    +begin
       WriteBinarydata(Name, Value, SizeOf(TDateTime));
     end;
     
    -procedure TRegistry.WriteTime(const Name: string; Value: TDateTime);
    +procedure TRegistry.WriteDate(const Name: String; Value: TDateTime);
     begin
    +  WriteDate(UnicodeString(Name), Value);
    +end;
    +
    +procedure TRegistry.WriteTime(const Name: UnicodeString; Value: TDateTime);
    +begin
       WriteBinaryData(Name, Value, SizeOf(TDateTime));
     end;
     
    -procedure TRegistry.WriteDateTime(const Name: string; Value: TDateTime);
    +procedure TRegistry.WriteTime(const Name: String; Value: TDateTime);
     begin
    +  WriteTime(UnicodeString(Name), Value);
    +end;
    +
    +procedure TRegistry.WriteDateTime(const Name: UnicodeString; Value: TDateTime);
    +begin
       WriteBinaryData(Name, Value, SizeOf(TDateTime));
     end;
     
    -procedure TRegistry.WriteExpandString(const Name, Value: string);
    -var
    -  u: UnicodeString;
    +procedure TRegistry.WriteDateTime(const Name: String; Value: TDateTime);
    +begin
    +  WriteDateTime(UnicodeString(Name), Value);
    +end;
     
    +procedure TRegistry.WriteExpandString(const Name, Value: UnicodeString);
     begin
    -  u:=Value;
    -  PutData(Name, PWideChar(u), ByteLength(u), rdExpandString);
    +  PutData(Name, PWideChar(Value), ByteLength(Value), rdExpandString);
     end;
     
    -procedure TRegistry.WriteStringList(const Name: string; List: TStrings);
    +procedure TRegistry.WriteExpandString(const Name, Value: String);
    +begin
    +  WriteExpandString(UnicodeString(Name), UnicodeString(Value));
    +end;
     
    +
    +procedure TRegistry.WriteStringList(const Name: UnicodeString; List: TStrings; IsUtf8: Boolean=False);
    +
     Var
    -  Data: string;
    +  UArr: TUnicodeStringArray;
    +begin
    +  UArr := ListToArray(List, IsUtf8);
    +  WriteStringArray(Name, UArr);
    +end;
     
    +procedure TRegistry.WriteStringArray(const Name: UnicodeString; const Arr: TUnicodeStringArray);
    +Var
    +  Data: UnicodeString;
    +  u: UnicodeString;
    +  i: Integer;
     begin
    -  Data := StringReplace(List.Text, LineEnding, #0, [rfReplaceAll]) + #0#0;
    -  PutData(Name, PChar(Data), Length(Data),rdMultiString);
    +  Data := '';
    +  //REG_MULTI_SZ data cannot contain empty strings
    +  for i := Low(Arr) to High(Arr) do
    +  begin
    +    u := Arr[i];
    +    if (u>'') then
    +    begin
    +      if (Data>'') then
    +        Data := Data + #0 + u
    +      else
    +        Data := Data + u;
    +    end;
    +  end;
    +  if StringSizeIncludesNull then
    +    Data := Data + #0#0;
    +  //writeln('Data=',Dbgs(Data));
    +  PutData(Name, PWideChar(Data), ByteLength(Data), rdMultiString);
     end;
     
    -procedure TRegistry.WriteFloat(const Name: string; Value: Double);
    +procedure TRegistry.WriteStringArray(const Name: String; const Arr: TStringArray);
    +var
    +  UArr: TUnicodeStringArray;
    +  i: Integer;
     begin
    +  UArr := nil;
    +  SetLength(UArr, Length(Arr));
    +  for i := Low(Arr) to High(Arr) do UArr[i] := Arr[i];
    +  WriteStringArray(UnicodeString(Name), UArr);
    +end;
    +
    +procedure TRegistry.WriteFloat(const Name: UnicodeString; Value: Double);
    +begin
       WriteBinaryData(Name, Value, SizeOf(Double));
     end;
     
    -procedure TRegistry.WriteInteger(const Name: string; Value: Integer);
    +procedure TRegistry.WriteFloat(const Name: String; Value: Double);
     begin
    +  WriteFloat(UnicodeString(Name), Value);
    +end;
    +
    +procedure TRegistry.WriteInteger(const Name: UnicodeString; Value: Integer);
    +begin
       PutData(Name, @Value, SizeOf(Integer), rdInteger);
     end;
     
    -procedure TRegistry.WriteInt64(const Name: string; Value: Int64);
    +procedure TRegistry.WriteInteger(const Name: String; Value: Integer);
     begin
    +  WriteInteger(UnicodeString(Name), Value);
    +end;
    +
    +procedure TRegistry.WriteInt64(const Name: UnicodeString; Value: Int64);
    +begin
       PutData(Name, @Value, SizeOf(Int64), rdInt64);
     end;
     
    -procedure TRegistry.WriteString(const Name, Value: string);
    -var
    -  u: UnicodeString;
    +procedure TRegistry.WriteInt64(const Name: String; Value: Int64);
    +begin
    +  WriteInt64(UnicodeString(Name), Value);
    +end;
     
    +procedure TRegistry.WriteString(const Name, Value: UnicodeString);
     begin
    -  u:=Value;
    -  PutData(Name, PWideChar(u), ByteLength(u), rdString);
    +  PutData(Name, PWideChar(Value), ByteLength(Value), rdString);
     end;
     
    -procedure TRegistry.MoveKey(const OldName, NewName: string; Delete: Boolean);
    +procedure TRegistry.WriteString(const Name, Value: String);
     begin
    +  WriteString(UnicodeString(Name), UnicodeString(Value));
    +end;
     
    +procedure TRegistry.MoveKey(const OldName, NewName: UnicodeString; Delete: Boolean);
    +begin
    +
     end;
     
    +procedure TRegistry.MoveKey(const OldName, NewName: String; Delete: Boolean);
    +begin
    +  MoveKey(UnicodeString(OldName), UnicodeString(NewName), Delete);
    +end;
    +
    +procedure TRegistry.RenameValue(const OldName, NewName: String);
    +begin
    +  RenameValue(UnicodeString(OldName), UnicodeString(NewName));
    +end;
    +
     { ---------------------------------------------------------------------
         Include TRegIniFile implementation
       ---------------------------------------------------------------------}
    @@ -583,7 +992,7 @@
       Value: TStream): Integer;
     begin
       result:=-1; // unimplemented
    - // 
    + //
     end;
     
     function TRegistryIniFile.ReadDate(const Section, Name: string;
    Index: packages/fcl-registry/src/winreg.inc
    ===================================================================
    --- packages/fcl-registry/src/winreg.inc	(revision 41667)
    +++ packages/fcl-registry/src/winreg.inc	(working copy)
    @@ -1,7 +1,7 @@
     Const
       RegDataWords : Array [TRegDataType] of DWORD
                    = (REG_NONE,REG_SZ,REG_EXPAND_SZ,REG_BINARY,REG_DWORD,REG_DWORD_BIG_ENDIAN,
    -                  REG_LINK,REG_MULTI_SZ,REG_RESOURCE_LIST,REG_FULL_RESOURCE_DESCRIPTOR,REG_RESOURCE_REQUIREMENTS_LIST,REG_QWORD);
    +                  REG_LINK,REG_MULTI_SZ,REG_RESOURCE_LIST,REG_FULL_RESOURCE_DESCRIPTOR,REG_RESOURCE_REQUIREMENTS_LIST,11{REG_QWORD}); //*****UNDO THIS!
     
     type
       TWinRegData = record
    @@ -28,7 +28,7 @@
       Dispose(PWinRegData(FSysData));
     end;
     
    -Function PrepKey(Const S : String) : String;
    +Function PrepKey(Const S : UnicodeString) : UnicodeString;
     
     begin
       Result := S;
    @@ -36,7 +36,7 @@
         System.Delete(Result, 1, 1);
     end;
     
    -Function RelativeKey(Const S : String) : Boolean;
    +Function RelativeKey(Const S : UnicodeString) : Boolean;
     
     begin
       Result:=(S='') or (S[1]<>'\')
    @@ -43,7 +43,7 @@
     end;
     
     
    -function TRegistry.sysCreateKey(const Key: String): Boolean;
    +function TRegistry.sysCreateKey(Key: UnicodeString): Boolean;
     Var
       u: UnicodeString;
       Disposition: Dword;
    @@ -52,9 +52,9 @@
     
     begin
       SecurityAttributes := Nil;
    -  u:=PrepKey(Key);
    +  Key:=PrepKey(Key);
       FLastError:=RegCreateKeyExW(GetBaseKey(RelativeKey(Key)),
    -                              PWideChar(u),
    +                              PWideChar(Key),
                                   0,
                                   '',
                                   REG_OPTION_NON_VOLATILE,
    @@ -66,7 +66,7 @@
       RegCloseKey(Handle);
     end;
     
    -function TRegistry.DeleteKey(const Key: String): Boolean;
    +function TRegistry.DeleteKey(const Key: UnicodeString): Boolean;
     
     Var
       u: UnicodeString;
    @@ -76,21 +76,21 @@
       Result:=FLastError=ERROR_SUCCESS;
     end;
     
    -function TRegistry.DeleteValue(const Name: String): Boolean;
    +
    +function TRegistry.DeleteValue(const Name: UnicodeString): Boolean;
     begin
    -  FLastError:= RegDeleteValueW(fCurrentKey, PWideChar(UnicodeString(Name)));
    +  FLastError:= RegDeleteValueW(fCurrentKey, PWideChar(Name));
       Result:=FLastError=ERROR_SUCCESS;
     end;
     
    -function TRegistry.SysGetData(const Name: String; Buffer: Pointer;
    +
    +function TRegistry.SysGetData(const Name: UnicodeString; Buffer: Pointer;
               BufSize: Integer; Out RegData: TRegDataType): Integer;
     Var
    -  u: UnicodeString;
       RD : DWord;
     
     begin
    -  u := Name;
    -  FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(u),Nil,
    +  FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(Name),Nil,
                           @RD,Buffer,lpdword(@BufSize));
       if (FLastError<>ERROR_SUCCESS) Then
         Result:=-1
    @@ -103,17 +103,15 @@
         end;
     end;
     
    -function TRegistry.GetDataInfo(const ValueName: String; out Value: TRegDataInfo): Boolean;
    +function TRegistry.GetDataInfo(const ValueName: UnicodeString; out Value: TRegDataInfo): Boolean;
     
     Var
    -  u: UnicodeString;
       RD : DWord;
     
     begin
    -  u:=ValueName;
       With Value do
         begin
    -    FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(u),Nil,lpdword(@RegData),Nil,lpdword(@DataSize));
    +    FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(ValueName),Nil,lpdword(@RegData),Nil,lpdword(@DataSize));
         Result:=FLastError=ERROR_SUCCESS;
         if Result then
           begin
    @@ -131,24 +129,18 @@
     end;
     
     
    -function TRegistry.GetKey(const Key: String): HKEY;
    +function TRegistry.GetKey(Key: UnicodeString): HKEY;
     var
    -  S : string;
    -{$ifndef WinCE}
    -  u : UnicodeString;
    -{$endif}
       Rel : Boolean;
     begin
       Result:=0;
    -  S:=Key;
    -  Rel:=RelativeKey(S);
    +  Rel:=RelativeKey(Key);
       if not(Rel) then
    -    Delete(S,1,1);
    +    Delete(Key,1,1);
     {$ifdef WinCE}
    -  FLastError:=RegOpenKeyEx(GetBaseKey(Rel),PWideChar(WideString(S)),0,FAccess,Result);
    +  FLastError:=RegOpenKeyEx(GetBaseKey(Rel),PWideChar(Key),0,FAccess,Result);
     {$else WinCE}
    -  u:=UnicodeString(S);
    -  FLastError:=RegOpenKeyExW(GetBaseKey(Rel),PWideChar(u),0,FAccess,Result);
    +  FLastError:=RegOpenKeyExW(GetBaseKey(Rel),PWideChar(Key),0,FAccess,Result);
     {$endif WinCE}
     end;
     
    @@ -174,7 +166,7 @@
     end;
     
     
    -function TRegistry.KeyExists(const Key: string): Boolean;
    +function TRegistry.KeyExists(const Key: UnicodeString): Boolean;
     var
       KeyHandle : HKEY;
       OldAccess : LONG;
    @@ -196,20 +188,20 @@
     end;
     
     
    -function TRegistry.LoadKey(const Key, FileName: string): Boolean;
    +function TRegistry.LoadKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
     
    -function TRegistry.OpenKey(const Key: string; CanCreate: Boolean): Boolean;
     
    +function TRegistry.OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
    +
     Var
    -  u: UnicodeString;
    +  u, S: UnicodeString;
       Handle: HKEY;
       Disposition: Integer;
       SecurityAttributes: Pointer; //LPSECURITY_ATTRIBUTES;
    -  S: string;
     begin
       SecurityAttributes := Nil;
       u:=PrepKey(Key);
    @@ -232,13 +224,14 @@
         if RelativeKey(Key) then
           S:=CurrentPath + Key
         else
    -      S:=UTF8Encode(u);
    +      S:=u;
         ChangeKey(Handle, S);
       end;
     end;
     
    -function TRegistry.OpenKeyReadOnly(const Key: string): Boolean;
     
    +function TRegistry.OpenKeyReadOnly(const Key: UnicodeString): Boolean;
    +
     Var
       OldAccess: LongWord;
     begin
    @@ -251,7 +244,8 @@
       end;
     end;
     
    -function TRegistry.RegistryConnect(const UNCName: string): Boolean;
    +
    +function TRegistry.RegistryConnect(const UNCName: UnicodeString): Boolean;
     {$ifndef WinCE}
     var
       newroot: HKEY;
    @@ -260,7 +254,7 @@
     {$ifdef WinCE}
       Result:=False;
     {$else}
    -  FLastError:=RegConnectRegistryW(PWideChar(UnicodeString(UNCName)),RootKey,newroot);
    +  FLastError:=RegConnectRegistryW(PWideChar(UNCName),RootKey,newroot);
       Result:=FLastError=ERROR_SUCCESS;
       if Result then begin
         RootKey:=newroot;
    @@ -269,28 +263,33 @@
     {$endif}
     end;
     
    -function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
    +
    +function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.RestoreKey(const Key, FileName: string): Boolean;
    +
    +function TRegistry.RestoreKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.SaveKey(const Key, FileName: string): Boolean;
    +
    +function TRegistry.SaveKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.UnLoadKey(const Key: string): Boolean;
    +
    +function TRegistry.UnLoadKey(const Key: UnicodeString): Boolean;
     begin
       Result := false;
     end;
     
    -function TRegistry.ValueExists(const Name: string): Boolean;
     
    +function TRegistry.ValueExists(const Name: UnicodeString): Boolean;
    +
     var
       Info : TRegDataInfo;
     
    @@ -298,6 +297,7 @@
       Result:=GetDataInfo(Name,Info);
     end;
     
    +
     procedure TRegistry.CloseKey;
     begin
       If (CurrentKey<>0) then
    @@ -316,7 +316,7 @@
       RegCloseKey(key);
     end;
     
    -procedure TRegistry.ChangeKey(Value: HKey; const Path: String);
    +procedure TRegistry.ChangeKey(Value: HKey; const Path: UnicodeString);
     begin
       CloseKey;
       FCurrentKey:=Value;
    @@ -323,6 +323,7 @@
       FCurrentPath:=Path;
     end;
     
    +
     procedure TRegistry.GetKeyNames(Strings: TStrings);
     
     var
    @@ -410,12 +411,11 @@
     end;
     
     
    -Function TRegistry.SysPutData(const Name: string; Buffer: Pointer;
    +Function TRegistry.SysPutData(const Name: UnicodeString; Buffer: Pointer;
       BufSize: Integer; RegData: TRegDataType) : Boolean;
     
     
     Var
    -  u: UnicodeString;
       RegDataType: DWORD;
       B : Pchar;
       S : String;
    @@ -422,12 +422,11 @@
     
     begin
       RegDataType:=RegDataWords[RegData];
    -  u:=UnicodeString(Name);
    -  FLastError:=RegSetValueExW(fCurrentKey,PWideChar(u),0,RegDataType,Buffer,BufSize);
    +  FLastError:=RegSetValueExW(fCurrentKey,PWideChar(Name),0,RegDataType,Buffer,BufSize);
       Result:=FLastError=ERROR_SUCCESS;
     end;
     
    -procedure TRegistry.RenameValue(const OldName, NewName: string);
    +procedure TRegistry.RenameValue(const OldName, NewName: UnicodeString);
     
     var
       L: Integer;
    Index: packages/fcl-registry/src/xmlreg.pp
    ===================================================================
    --- packages/fcl-registry/src/xmlreg.pp	(revision 41667)
    +++ packages/fcl-registry/src/xmlreg.pp	(working copy)
    @@ -32,54 +32,54 @@
       Private
         FAutoFlush,
         FDirty : Boolean;
    -    FFileName : String;
    -    FRootKey : String;
    +    FFileName : UnicodeString;
    +    FRootKey : UnicodeString;
         FDocument : TXMLDocument;
         FCurrentElement : TDomElement;
    -    FCurrentKey : String;
    -    Procedure SetFileName(Value : String);
    +    FCurrentKey : UnicodeString;
    +    Procedure SetFileName(Value : UnicodeString);
       Protected
    -    function DoGetValueData(Name: String; out DataType: TDataType; Var Data; Var DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
    -    function DoSetValueData(Name: String; DataType: TDataType; const Data; DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
    +    function DoGetValueData(Name: UnicodeString; out DataType: TDataType; Var Data; Var DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
    +    function DoSetValueData(Name: UnicodeString; DataType: TDataType; const Data; DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
         Procedure LoadFromStream(S : TStream);
    -    Function  NormalizeKey(KeyPath : String) : String;
    +    Function  NormalizeKey(KeyPath : UnicodeString) : UnicodeString;
         Procedure CreateEmptyDoc;
    -    Function  FindKey (S : String) : TDomElement;
    -    Function  FindSubKey (S : String; N : TDomElement) : TDomElement;
    -    Function  CreateSubKey (S : String; N : TDomElement) : TDomElement;
    -    Function  FindValueKey (S : String) : TDomElement;
    -    Function  CreateValueKey (S : String) : TDomElement;
    +    Function  FindKey (S : UnicodeString) : TDomElement;
    +    Function  FindSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
    +    Function  CreateSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
    +    Function  FindValueKey (S : UnicodeString) : TDomElement;
    +    Function  CreateValueKey (S : UnicodeString) : TDomElement;
         Function  BufToHex(Const Buf; Len : Integer) : String;
    -    Function  hexToBuf(Const Str : String; Var Buf; Var Len : Integer ) : Integer;
    +    Function  HexToBuf(Const Str : UnicodeString; Var Buf; Var Len : Integer ) : Integer;
         Procedure MaybeFlush;
         Property  Document : TXMLDocument Read FDocument;
         Property  Dirty : Boolean Read FDirty write FDirty;
       Public
    -    Constructor Create(AFileName : String);
    +    Constructor Create(AFileName : UnicodeString);
         Destructor  Destroy;override;
    -    Function  SetKey(KeyPath : String; AllowCreate : Boolean) : Boolean ;
    -    Procedure SetRootKey(Value : String);
    -    Function  DeleteKey(KeyPath : String) : Boolean;
    -    Function  CreateKey(KeyPath : String) : Boolean;
    -    Function  GetValueSize(Name : String) : Integer;
    -    Function  GetValueType(Name : String) : TDataType;
    -    Function  GetValueInfo(Name : String; Out Info : TDataInfo; AsUnicode : Boolean = False) : Boolean;
    +    Function  SetKey(KeyPath : UnicodeString; AllowCreate : Boolean) : Boolean ;
    +    Procedure SetRootKey(Value : UnicodeString);
    +    Function  DeleteKey(KeyPath : UnicodeString) : Boolean;
    +    Function  CreateKey(KeyPath : UnicodeString) : Boolean;
    +    Function  GetValueSize(Name : UnicodeString) : Integer;
    +    Function  GetValueType(Name : UnicodeString) : TDataType;
    +    Function  GetValueInfo(Name : UnicodeString; Out Info : TDataInfo; AsUnicode : Boolean = False) : Boolean;
         Function  GetKeyInfo(Out Info : TKeyInfo) : Boolean;
         Function  EnumSubKeys(List : TStrings) : Integer;
         Function  EnumValues(List : TStrings) : Integer;
    -    Function  KeyExists(KeyPath : String) : Boolean;
    -    Function  ValueExists(ValueName : String) : Boolean;
    -    Function  RenameValue(Const OldName,NewName : String) : Boolean;
    -    Function  DeleteValue(S : String) : Boolean;
    +    Function  KeyExists(KeyPath : UnicodeString) : Boolean;
    +    Function  ValueExists(ValueName : UnicodeString) : Boolean;
    +    Function  RenameValue(Const OldName,NewName : UnicodeString) : Boolean;
    +    Function  DeleteValue(S : UnicodeString) : Boolean;
         Procedure Flush;
         Procedure Load;
    -    Function GetValueData(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
    -    Function SetValueData(Name : String; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
    +    Function GetValueData(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
    +    Function SetValueData(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
         // These interpret the Data buffer as unicode data
    -    Function GetValueDataUnicode(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
    -    Function SetValueDataUnicode(Name : String; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
    -    Property FileName : String Read FFileName Write SetFileName;
    -    Property RootKey : String Read FRootKey Write SetRootkey;
    +    Function GetValueDataUnicode(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
    +    Function SetValueDataUnicode(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
    +    Property FileName : UnicodeString Read FFileName Write SetFileName;
    +    Property RootKey : UnicodeString Read FRootKey Write SetRootkey;
         Property AutoFlush : Boolean Read FAutoFlush Write FAutoFlush;
       end;
     
    @@ -96,7 +96,7 @@
     Implementation
     
     
    -Constructor TXmlRegistry.Create(AFileName : String);
    +Constructor TXmlRegistry.Create(AFileName : UnicodeString);
     
     begin
       FFileName:=AFileName;
    @@ -113,7 +113,7 @@
       inherited Destroy;
     end;
     
    -Procedure TXmlRegistry.SetFileName(Value : String);
    +Procedure TXmlRegistry.SetFileName(Value : UnicodeString);
     
     begin
       If Value<>FFileName then
    @@ -143,13 +143,13 @@
       end;
     end;
     
    -Function TXmlRegistry.NormalizeKey(KeyPath : String) : String;
    +Function TXmlRegistry.NormalizeKey(KeyPath : UnicodeString) : UnicodeString;
     
     Var
       L : Integer;
     
     begin
    -  Result:=StringReplace(KeyPath,'\','/',[rfReplaceAll]);
    +  Result:=UnicodeStringReplace(KeyPath,'\','/',[rfReplaceAll]);
       L:=Length(Result);
       If (L>0) and (Result[L]<>'/') then
         Result:=Result+'/';
    @@ -157,10 +157,10 @@
         Result:='/' + Result;
     end;
     
    -Function TXmlRegistry.SetKey(KeyPath : String; AllowCreate : Boolean) : boolean;
    +Function TXmlRegistry.SetKey(KeyPath : UnicodeString; AllowCreate : Boolean) : boolean;
     
     Var
    -  SubKey,ResultKey : String;
    +  SubKey,ResultKey : UnicodeString;
       P : Integer;
       Node,Node2 : TDomElement;
     
    @@ -218,7 +218,7 @@
       MaybeFlush;
     end;
     
    -Procedure TXmlRegistry.SetRootKey(Value : String);
    +Procedure TXmlRegistry.SetRootKey(Value : UnicodeString);
     
     begin
       FRootKey:=NormalizeKey(Value);
    @@ -228,7 +228,7 @@
       FCurrentElement:=Nil;
     end;
     
    -Function TXmlRegistry.DeleteKey(KeyPath : String) : Boolean;
    +Function TXmlRegistry.DeleteKey(KeyPath : UnicodeString) : Boolean;
     
     Var
       N : TDomElement;
    @@ -244,10 +244,10 @@
        end;
     end;
     
    -Function TXmlRegistry.CreateKey(KeyPath : String) : Boolean;
    +Function TXmlRegistry.CreateKey(KeyPath : UnicodeString) : Boolean;
     
     Var
    -  SubKey : String;
    +  SubKey : UnicodeString;
       P : Integer;
       Node,Node2 : TDomElement;
     
    @@ -290,7 +290,7 @@
       MaybeFlush;
     end;
     
    -Function TXmlRegistry.DoGetValueData(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer; IsUnicode : Boolean) : Boolean;
    +Function TXmlRegistry.DoGetValueData(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer; IsUnicode : Boolean) : Boolean;
     
     Type
       PCardinal = ^Cardinal;
    @@ -305,22 +305,27 @@
       D : DWord;
       
     begin
    +  //writeln('TXmlRegistry.DoGetValueData: Name=',Name,' IsUnicode=',IsUnicode);
       Node:=FindValueKey(Name);
       Result:=Node<>Nil;
       If Result then
         begin
    +    //writeln('TXmlRegistry.DoGetValueData: Node<>nil');
         DataNode:=Node.FirstChild;
         HasData:=Assigned(DataNode) and (DataNode.NodeType=TEXT_NODE);
    -    ND:=StrToIntDef(Node[Stype],0);
    +    //writeln('TXmlRegistry.DoGetValueData: HasData=',hasdata);
    +    ND:=StrToIntDef(String(Node[Stype]),0);
    +    //writeln('TXmlRegistry.DoGetValueData: ND=',ND);
         Result:=ND<=Ord(High(TDataType));
         If Result then
           begin
           DataType:=TDataType(ND);
    +      //writeln('TXmlRegistry.DoGetValueData: DataType=',DataType);
           NS:=0; // Initialize, for optional nodes.
           Case DataType of
             dtDWORD : begin   // DataNode is required
                       NS:=SizeOf(Cardinal);
    -                  Result:=HasData and TryStrToDWord(DataNode.NodeValue,D) and (DataSize>=NS);
    +                  Result:=HasData and TryStrToDWord(String(DataNode.NodeValue),D) and (DataSize>=NS);
                       if Result then
                         PCardinal(@Data)^:=D;
                       end;
    @@ -329,7 +334,7 @@
                          begin
                          if not IsUnicode then
                            begin
    -                       S:=UTF8Encode(DataNode.NodeValue); // Convert to ansistring
    +                       S:=DataNode.NodeValue; // Convert to ansistring
                            NS:=Length(S);
                            Result:=(DataSize>=NS);
                            if Result then
    @@ -350,8 +355,10 @@
                        if HasData then
                          begin
                          BL:=Length(DataNode.NodeValue);
    +                     //writeln('TXmlRegistry.DoGetValueData: BL=',BL);
                          NS:=BL div 2;
                          Result:=DataSize>=NS;
    +                     //writeln('TXmlRegistry.DoGetValueData: Result=',Result);
                          If Result then
                            // No need to check for -1, We checked NS before calling.
                            NS:=HexToBuf(DataNode.NodeValue,Data,BL);
    @@ -363,7 +370,7 @@
         end;
     end;
     
    -Function TXmlRegistry.DoSetValueData(Name : String; DataType : TDataType; Const Data; DataSize : Integer; IsUnicode : Boolean) : Boolean;
    +Function TXmlRegistry.DoSetValueData(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer; IsUnicode : Boolean) : Boolean;
     
     Type
       PCardinal = ^Cardinal;
    @@ -374,6 +381,7 @@
       SW : UnicodeString;
     
     begin
    +  //writeln('TXmlRegistry.DoSetValueData A: Name=',Name,', DataType=',DataType,', DataSize=',DataSize,', IsUnicode=',IsUnicode);
       Node:=FindValueKey(Name);
       If Node=Nil then
         Node:=CreateValueKey(Name);
    @@ -380,20 +388,20 @@
       Result:=(Node<>Nil);
       If Result then
         begin
    -    Node[SType]:=IntToStr(Ord(DataType));
    +    Node[SType]:=UnicodeString(IntToStr(Ord(DataType)));
         DataNode:=Node.FirstChild;
     
         Case DataType of
    -      dtDWORD : SW:=IntToStr(PCardinal(@Data)^);
    +      dtDWORD : SW:=UnicodeString(IntToStr(PCardinal(@Data)^));
           dtString : begin
                      if IsUnicode then
                        SW:=UnicodeString(PUnicodeChar(@Data))
                      else
                        SW:=UnicodeString(PAnsiChar(@Data));
    -                   //S:=UTF8Encode(SW);
    +                   //S:=SW;
                      end;
    -      dtBinary : SW:=BufToHex(Data,DataSize);
    -      dtStrings : SW:=BufToHex(Data,DataSize);
    +      dtBinary : SW:=UnicodeString(BufToHex(Data,DataSize));
    +      dtStrings : SW:=UnicodeString(BufToHex(Data,DataSize));
         else
           sw:='';
         end;
    @@ -416,29 +424,29 @@
         end;
     end;
     
    -Function TXmlRegistry.SetValueData(Name : String; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
    +Function TXmlRegistry.SetValueData(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
     
     begin
       Result:=DoSetValueData(Name,DataType,Data,DataSize,False);
     end;
     
    -Function TXmlRegistry.GetValueData(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
    +Function TXmlRegistry.GetValueData(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
     
     begin
       Result:=DoGetValueData(Name,DataType,Data,DataSize,False);
     end;
     
    -function TXmlRegistry.GetValueDataUnicode(Name: String; out DataType: TDataType; Var Data; Var DataSize: Integer): Boolean;
    +function TXmlRegistry.GetValueDataUnicode(Name: UnicodeString; out DataType: TDataType; Var Data; Var DataSize: Integer): Boolean;
     begin
       Result:=DoGetValueData(Name,DataType,Data,DataSize,True);
     end;
     
    -function TXmlRegistry.SetValueDataUnicode(Name: String; DataType: TDataType; const Data; DataSize: Integer): Boolean;
    +function TXmlRegistry.SetValueDataUnicode(Name: UnicodeString; DataType: TDataType; const Data; DataSize: Integer): Boolean;
     begin
       Result:=DoSetValueData(Name,DataType,Data,DataSize,True)
     end;
     
    -Function TXmlRegistry.FindSubKey (S : String; N : TDomElement) : TDomElement;
    +Function TXmlRegistry.FindSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
     
     Var
       Node : TDOMNode;
    @@ -451,7 +459,7 @@
         While (Result=Nil) and (Assigned(Node)) do
           begin
           If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SKey) then
    -        If CompareText(TDomElement(Node)[SName],S)=0 then
    +        If UnicodeCompareText(TDomElement(Node)[SName],S)=0 then
               Result:=TDomElement(Node);
           Node:=Node.NextSibling;
           end;
    @@ -458,7 +466,7 @@
         end;
     end;
     
    -Function TXmlRegistry.CreateSubKey (S : String; N : TDomElement) : TDomElement;
    +Function TXmlRegistry.CreateSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
     
     begin
       Result:=FDocument.CreateElement(SKey);
    @@ -468,7 +476,7 @@
       FDirty:=True;
     end;
     
    -Function  TXmlRegistry.FindValueKey (S : String) : TDomElement;
    +Function  TXmlRegistry.FindValueKey (S : UnicodeString) : TDomElement;
     
     Var
       Node : TDOMNode;
    @@ -481,7 +489,7 @@
         While (Result=Nil) and (Assigned(Node)) do
           begin
           If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SValue) then
    -        If CompareText(TDomElement(Node)[SName],S)=0 then
    +        If UnicodeCompareText(TDomElement(Node)[SName],S)=0 then
               Result:=TDomElement(Node);
           Node:=Node.NextSibling;
           end;
    @@ -488,7 +496,7 @@
         end;
     end;
     
    -Function  TXmlRegistry.CreateValueKey (S : String) : TDomElement;
    +Function  TXmlRegistry.CreateValueKey (S : UnicodeString) : TDomElement;
     
     begin
       If Assigned(FCurrentElement) then
    @@ -581,38 +589,47 @@
         end;
     end;
     
    -Function TXMLRegistry.hexToBuf(Const Str : String; Var Buf; Var Len : Integer ) : Integer;
    +Function TXMLRegistry.HexToBuf(Const Str : UnicodeString; Var Buf; Var Len : Integer ) : Integer;
     
     Var
       NLeN,I : Integer;
       P : PByte;
    -  S : String;
    +  S : UnicodeString;
       B : Byte;
       Code : Integer;
     
     begin
    +  //writeln('TXMLRegistry.HexToBuf A: Str=',Str,', Len=',Len);
       Result:=0;
       P:=@Buf;
    +  //writeln('TXMLRegistry.HexToBuf B: (p=nil)=',p=nil);
       NLen:= Length(Str) div 2;
    +  //writeln('TXMLRegistry.HexToBuf C: NLen=',NLen,', SizeOf(TDateTime)=',SizeOf(TDateTime));
       If (NLen>Len) then
         begin
         Len:=NLen;
         Exit(-1);
         end;
    -  For I:=0 to Len-1 do
    +  For I:=0 to NLen-1 do
         begin
    +    //write('TXMLRegistry.HexToBuf: i=',i);
         S:='$'+Copy(Str,(I*2)+1,2);
    +    //write(', S=',S);
         Val(S,B,Code);
    +    //writeln(', Code=',Code);
         If Code<>0 then
    -      begin
    -      Inc(Result);
    -      B:=0;
    +      begin    //This means invalid data in the registry, why continue and increment result? Why not Exit(-1)?
    +      //Inc(Result);   //the whole function only worked because this was called as often as when Code=0, so by change
    +      //B:=0;          //it causes AV's
    +      Exit(-1);
           end;
    +    Inc(Result);
         P[I]:=B;
         end;
    +  //writeln('TXMLRegistry.HexToBuf End: Result=',Result);
     end;
     
    -Function TXMLRegistry.DeleteValue(S : String) : Boolean;
    +Function TXMLRegistry.DeleteValue(S : UnicodeString) : Boolean;
     
     Var
       N : TDomElement;
    @@ -628,31 +645,31 @@
         end;
     end;
     
    -Function TXMLRegistry.GetValueSize(Name : String) : Integer;
    +Function TXMLRegistry.GetValueSize(Name : UnicodeString) : Integer;
     
     Var
       Info : TDataInfo;
     
     begin
    -  If GetValueInfo(Name,Info) then
    +  If GetValueInfo(Name,Info,True) then
         Result:=Info.DataSize
       else
         Result:=-1;
     end;
     
    -Function TXMLRegistry.GetValueType(Name : String) : TDataType;
    +Function TXMLRegistry.GetValueType(Name : UnicodeString) : TDataType;
     
     Var
       Info : TDataInfo;
     
     begin
    -  If GetValueInfo(Name,Info) then
    +  If GetValueInfo(Name,Info,True) then
         Result:=Info.DataType
       else
         Result:=dtUnknown;
     end;
     
    -function TXmlRegistry.GetValueInfo(Name: String; out Info: TDataInfo; AsUnicode: Boolean): Boolean;
    +function TXmlRegistry.GetValueInfo(Name: UnicodeString; out Info: TDataInfo; AsUnicode: Boolean): Boolean;
     
     Var
       N  : TDomElement;
    @@ -671,7 +688,7 @@
             L:=Length(DN.NodeValue)*SizeOf(UnicodeChar)
           else
             begin
    -        S := UTF8Encode(DN.NodeValue);
    +        S := DN.NodeValue;
             L:=Length(S);
             end
           end
    @@ -679,7 +696,7 @@
           L:=0;
         With Info do
           begin
    -      DataType:=TDataType(StrToIntDef(N[SType],0));
    +      DataType:=TDataType(StrToIntDef(String(N[SType]),0));
           Case DataType of
             dtUnknown : DataSize:=0;
             dtDword   : Datasize:=SizeOf(Cardinal);
    @@ -724,10 +741,10 @@
                   ValueLen:=L;
                 DataNode:=TDomElement(Node).FirstChild;
                 If (DataNode<>Nil) and (DataNode is TDomText) then
    -              Case TDataType(StrToIntDef(TDomElement(Node)[SType],0)) of
    +              Case TDataType(StrToIntDef(String(TDomElement(Node)[SType]),0)) of
                     dtUnknown : L:=0;
                     dtDWord   : L:=4;
    -                DtString  : L:=Length(UTF8Encode(DataNode.NodeValue));
    +                DtString  : L:=Length(String(DataNode.NodeValue));
                     dtBinary  : L:=Length(DataNode.NodeValue) div 2;
                   end
                 else
    @@ -782,13 +799,13 @@
         end;
     end;
     
    -Function TXMLRegistry.KeyExists(KeyPath : String) : Boolean;
    +Function TXMLRegistry.KeyExists(KeyPath : UnicodeString) : Boolean;
     
     begin
       Result:=FindKey(KeyPath)<>Nil;
     end;
     
    -Function TXMLRegistry.RenameValue(Const OldName,NewName : String) : Boolean;
    +Function TXMLRegistry.RenameValue(Const OldName,NewName : UnicodeString) : Boolean;
     
     Var
       N : TDomElement;
    @@ -804,10 +821,10 @@
         end;
     end;
     
    -Function TXMLRegistry.FindKey (S : String) : TDomElement;
    +Function TXMLRegistry.FindKey (S : UnicodeString) : TDomElement;
     
     Var
    -  SubKey : String;
    +  SubKey : UnicodeString;
       P : Integer;
       Node : TDomElement;
     
    @@ -840,7 +857,7 @@
       Until (Result=Nil) or (Length(S)=0);
     end;
     
    -Function  TXmlRegistry.ValueExists(ValueName : String) : Boolean;
    +Function  TXmlRegistry.ValueExists(ValueName : UnicodeString) : Boolean;
     
     begin
       Result:=FindValueKey(ValueName)<>Nil;
    Index: packages/fcl-registry/src/xregreg.inc
    ===================================================================
    --- packages/fcl-registry/src/xregreg.inc	(revision 41667)
    +++ packages/fcl-registry/src/xregreg.inc	(working copy)
    @@ -47,7 +47,7 @@
         Class Var XMLRegistryCache: Tlist;
         Class procedure FreeXMLRegistryCache;
       public
    -    constructor Create(AFileName : String);
    +    constructor Create(AFileName : UnicodeString);
         Class Function GetXMLRegistry(aFileName: string): TXMLRegistry;
         Class Procedure FreeXMLRegistry(XMLRegistry: TXMLRegistry);
         procedure IncRefCount;
    @@ -97,7 +97,7 @@
     
     { TXMLRegistryInstance }
     
    -constructor TXMLRegistryInstance.Create(AFileName: String);
    +constructor TXMLRegistryInstance.Create(AFileName: UnicodeString);
     begin
       inherited;
       FRefCount := 1;
    @@ -116,7 +116,11 @@
     procedure TRegistry.SysRegCreate;
     var s : string;
     begin
    +  FStringSizeIncludesNull:=False;
       s:=includetrailingpathdelimiter(GetAppConfigDir(GlobalXMLFile));
    +  {$ifdef XMLRegfile_in_CurDir}
    +  s:='.' + PathDelim;
    +  {$endif}
       ForceDirectories(s);
       FSysData:=TXMLRegistryInstance.GetXMLRegistry(s+XFileName);
       TXmlRegistry(FSysData).AutoFlush:=False;
    @@ -130,24 +134,24 @@
       TXMLRegistryInstance.FreeXMLRegistry(TXMLRegistry(FSysData));
     end;
     
    -function TRegistry.SysCreateKey(const Key: String): Boolean;
    +function TRegistry.SysCreateKey(Key: UnicodeString): Boolean;
     
     begin
       Result:=TXmlRegistry(FSysData).CreateKey(Key);
     end;
     
    -function TRegistry.DeleteKey(const Key: string): Boolean;
    +function TRegistry.DeleteKey(const Key: UnicodeString): Boolean;
     
     begin
       Result:=TXMLRegistry(FSysData).DeleteKey(Key);
     end;
     
    -function TRegistry.DeleteValue(const Name: string): Boolean;
    +function TRegistry.DeleteValue(const Name: UnicodeString): Boolean;
     begin
       Result:=TXmlRegistry(FSysData).DeleteValue(Name);
     end;
     
    -function TRegistry.SysGetData(const Name: String; Buffer: Pointer;
    +function TRegistry.SysGetData(const Name: UnicodeString; Buffer: Pointer;
               BufSize: Integer; Out RegData: TRegDataType): Integer;
     
     Var
    @@ -160,7 +164,7 @@
         Result:=-1;
     end;
     
    -function TRegistry.GetDataInfo(const ValueName: string; out Value: TRegDataInfo): Boolean;
    +function TRegistry.GetDataInfo(const ValueName: UnicodeString; out Value: TRegDataInfo): Boolean;
     
     Var
       Info : TDataInfo;
    @@ -181,7 +185,7 @@
           end;
     end;
     
    -function TRegistry.GetKey(const Key: string): HKEY;
    +function TRegistry.GetKey(Key: UnicodeString): HKEY;
     begin
       Result := 0;
     end;
    @@ -205,17 +209,17 @@
           end;
     end;
     
    -function TRegistry.KeyExists(const Key: string): Boolean;
    +function TRegistry.KeyExists(const Key: UnicodeString): Boolean;
     begin
       Result:=TXmlRegistry(FSysData).KeyExists(Key);
     end;
     
    -function TRegistry.LoadKey(const Key, FileName: string): Boolean;
    +function TRegistry.LoadKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.OpenKey(const Key: string; CanCreate: Boolean): Boolean;
    +function TRegistry.OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
     
     begin
       Result:=TXmlRegistry(FSysData).SetKey(Key,CanCreate);
    @@ -222,43 +226,43 @@
       FCurrentKey:=1;
     end;
     
    -function TRegistry.OpenKeyReadOnly(const Key: string): Boolean;
    +function TRegistry.OpenKeyReadOnly(const Key: UnicodeString): Boolean;
     
     begin
       Result:=TXmlRegistry(FSysData).SetKey(Key,False);
     end;
     
    -function TRegistry.RegistryConnect(const UNCName: string): Boolean;
    +function TRegistry.RegistryConnect(const UNCName: UnicodeString): Boolean;
     begin
       Result := True;
     end;
     
    -function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
    +function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.RestoreKey(const Key, FileName: string): Boolean;
    +function TRegistry.RestoreKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.SaveKey(const Key, FileName: string): Boolean;
    +function TRegistry.SaveKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.UnLoadKey(const Key: string): Boolean;
    +function TRegistry.UnLoadKey(const Key: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.ValueExists(const Name: string): Boolean;
    +function TRegistry.ValueExists(const Name: UnicodeString): Boolean;
     begin
       Result := TXmlRegistry(FSysData).ValueExists(Name);
     end;
     
    -procedure TRegistry.ChangeKey(Value: HKey; const Path: string);
    +procedure TRegistry.ChangeKey(Value: HKey; const Path: UnicodeString);
     begin
     
     end;
    @@ -274,7 +278,7 @@
     end;
     
     
    -function TRegistry.SysPutData(const Name: string; Buffer: Pointer;
    +function TRegistry.SysPutData(const Name: UnicodeString; Buffer: Pointer;
       BufSize: Integer; RegData: TRegDataType): Boolean;
     
     Var
    @@ -281,15 +285,18 @@
       DataType : TDataType;
     
     begin
    +  //writeln('TRegistry.SysPutData: Name=',Name,', RegData=',RegData,', BufSize=',BufSize);
       DataType:=RegDataTypeToXmlDataType(RegData);
    +
       Result:=TXMLRegistry(FSysData).SetValueDataUnicode(Name,DataType,Buffer^,BufSize);
     end;
     
    -procedure TRegistry.RenameValue(const OldName, NewName: string);
    +procedure TRegistry.RenameValue(const OldName, NewName: UnicodeString);
     begin
       TXMLRegistry(FSysData).RenameValue(OldName,NewName);
     end;
     
    +
     procedure TRegistry.SetCurrentKey(Value: HKEY);
     begin
       fCurrentKey := Value;
    
  • registry.unicode.part5.diff (67,948 bytes)
    Index: packages/fcl-registry/src/regdef.inc
    ===================================================================
    --- packages/fcl-registry/src/regdef.inc	(revision 41667)
    +++ packages/fcl-registry/src/regdef.inc	(working copy)
    @@ -2,7 +2,7 @@
       HKEY = THandle;
       PHKEY = ^HKEY;
       
    -{$ifdef windows}
    +{$if defined(windows) and not defined(XMLREG)}
     
     { Direct mapping to constants in Windows unit }
     
    Index: packages/fcl-registry/src/registry.pp
    ===================================================================
    --- packages/fcl-registry/src/registry.pp	(revision 41667)
    +++ packages/fcl-registry/src/registry.pp	(working copy)
    @@ -39,6 +39,8 @@
         DataSize: Integer;
       end;
     
    +  TUnicodeStringArray = Array of UnicodeString;
    +
     { ---------------------------------------------------------------------
         TRegistry
       ---------------------------------------------------------------------}
    @@ -54,22 +56,31 @@
         fCurrentKey: HKEY;
         fRootKey: HKEY;
         fLazyWrite: Boolean;
    -    fCurrentPath: string;
    +    fCurrentPath: UnicodeString;
         function GetLastErrorMsg: string;
    +    function RegMultiSzDataToUnicodeStringArray(U: UnicodeString): TUnicodeStringArray;
    +    function ListToArray(List: TStrings; IsUtf8: Boolean): TUnicodeStringArray;
    +    procedure ArrayToList(const Arr: TUnicodeStringArray; List: TStrings; ForceUtf8: Boolean);
         procedure SetRootKey(Value: HKEY);
         Procedure SysRegCreate;
         Procedure SysRegFree;
    -    Function  SysGetData(const Name: String; Buffer: Pointer; BufSize: Integer; Out RegData: TRegDataType): Integer;
    -    Function  SysPutData(const Name: string; Buffer: Pointer; BufSize: Integer; RegData: TRegDataType) : Boolean;
    -    Function  SysCreateKey(const Key: String): Boolean;
    +    Function  SysGetData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; Out RegData: TRegDataType): Integer;
    +    Function  SysPutData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; RegData: TRegDataType) : Boolean;
    +    Function  SysCreateKey(Key: UnicodeString): Boolean;
       protected
         function GetBaseKey(Relative: Boolean): HKey;
    -    function GetData(const Name: string; Buffer: Pointer;
    +    function GetData(const Name: UnicodeString; Buffer: Pointer;
                       BufSize: Integer; Out RegData: TRegDataType): Integer;
    -    function GetKey(const Key: string): HKEY;
    -    procedure ChangeKey(Value: HKey; const Path: string);
    -    procedure PutData(const Name: string; Buffer: Pointer;
    +    function GetData(const Name: String; Buffer: Pointer;
    +                  BufSize: Integer; Out RegData: TRegDataType): Integer;
    +    function GetKey(Key: UnicodeString): HKEY;
    +    function GetKey(Key: String): HKEY;
    +    procedure ChangeKey(Value: HKey; const Path: UnicodeString);
    +    procedure ChangeKey(Value: HKey; const Path: String);
    +    procedure PutData(const Name: UnicodeString; Buffer: Pointer;
                       BufSize: Integer; RegData: TRegDataType);
    +    procedure PutData(const Name: String; Buffer: Pointer;
    +                  BufSize: Integer; RegData: TRegDataType);
         procedure SetCurrentKey(Value: HKEY);
       public
         constructor Create; overload;
    @@ -76,58 +87,105 @@
         constructor Create(aaccess:longword); overload;
         destructor Destroy; override;
     
    -    function CreateKey(const Key: string): Boolean;
    -    function DeleteKey(const Key: string): Boolean;
    -    function DeleteValue(const Name: string): Boolean;
    -    function GetDataInfo(const ValueName: string; Out Value: TRegDataInfo): Boolean;
    -    function GetDataSize(const ValueName: string): Integer;
    -    function GetDataType(const ValueName: string): TRegDataType;
    +    function CreateKey(const Key: UnicodeString): Boolean;
    +    function CreateKey(const Key: String): Boolean;
    +    function DeleteKey(const Key: UnicodeString): Boolean;
    +    function DeleteKey(const Key: String): Boolean;
    +    function DeleteValue(const Name: UnicodeString): Boolean;
    +    function DeleteValue(const Name: String): Boolean;
    +    function GetDataInfo(const ValueName: UnicodeString; Out Value: TRegDataInfo): Boolean;
    +    function GetDataInfo(const ValueName: String; Out Value: TRegDataInfo): Boolean;
    +    function GetDataSize(const ValueName: UnicodeString): Integer;
    +    function GetDataSize(const ValueName: String): Integer;
    +    function GetDataType(const ValueName: UnicodeString): TRegDataType;
    +    function GetDataType(const ValueName: String): TRegDataType;
         function GetKeyInfo(Out Value: TRegKeyInfo): Boolean;
         function HasSubKeys: Boolean;
    -    function KeyExists(const Key: string): Boolean;
    -    function LoadKey(const Key, FileName: string): Boolean;
    -    function OpenKey(const Key: string; CanCreate: Boolean): Boolean;
    -    function OpenKeyReadOnly(const Key: string): Boolean;
    -    function ReadCurrency(const Name: string): Currency;
    -    function ReadBinaryData(const Name: string; var Buffer; BufSize: Integer): Integer;
    -    function ReadBool(const Name: string): Boolean;
    -    function ReadDate(const Name: string): TDateTime;
    -    function ReadDateTime(const Name: string): TDateTime;
    -    function ReadFloat(const Name: string): Double;
    -    function ReadInteger(const Name: string): Integer;
    -    function ReadInt64(const Name: string): Int64;
    -    function ReadString(const Name: string): string;
    -    procedure ReadStringList(const Name: string; AList: TStrings);
    -    function ReadTime(const Name: string): TDateTime;
    -    function RegistryConnect(const UNCName: string): Boolean;
    -    function ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
    -    function RestoreKey(const Key, FileName: string): Boolean;
    -    function SaveKey(const Key, FileName: string): Boolean;
    -    function UnLoadKey(const Key: string): Boolean;
    -    function ValueExists(const Name: string): Boolean;
    +    function KeyExists(const Key: UnicodeString): Boolean;
    +    function KeyExists(const Key: String): Boolean;
    +    function LoadKey(const Key, FileName: UnicodeString): Boolean;
    +    function LoadKey(const Key, FileName: String): Boolean;
    +    function OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
    +    function OpenKey(const Key: String; CanCreate: Boolean): Boolean;
    +    function OpenKeyReadOnly(const Key: UnicodeString): Boolean;
    +    function OpenKeyReadOnly(const Key: String): Boolean;
    +    function ReadCurrency(const Name: UnicodeString): Currency;
    +    function ReadCurrency(const Name: String): Currency;
    +    function ReadBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer): Integer;
    +    function ReadBinaryData(const Name: String; var Buffer; BufSize: Integer): Integer;
    +    function ReadBool(const Name: UnicodeString): Boolean;
    +    function ReadBool(const Name: String): Boolean;
    +    function ReadDate(const Name: UnicodeString): TDateTime;
    +    function ReadDate(const Name: String): TDateTime;
    +    function ReadDateTime(const Name: UnicodeString): TDateTime;
    +    function ReadDateTime(const Name: String): TDateTime;
    +    function ReadFloat(const Name: UnicodeString): Double;
    +    function ReadFloat(const Name: String): Double;
    +    function ReadInteger(const Name: UnicodeString): Integer;
    +    function ReadInteger(const Name: String): Integer;
    +    function ReadInt64(const Name: UnicodeString): Int64;
    +    function ReadInt64(const Name: String): Int64;
    +    function ReadString(const Name: UnicodeString): UnicodeString;
    +    function ReadString(const Name: String): string;
    +    procedure ReadStringList(const Name: UnicodeString; AList: TStrings; ForceUtf8: Boolean=False);
    +    procedure ReadStringList(const Name: String; AList: TStrings);
    +    function ReadStringArray(const Name: UnicodeString): TUnicodeStringArray;
    +    function ReadStringArray(const Name: String): TStringArray;
    +    function ReadTime(const Name: UnicodeString): TDateTime;
    +    function ReadTime(const Name: String): TDateTime;
    +    function RegistryConnect(const UNCName: UnicodeString): Boolean;
    +    function RegistryConnect(const UNCName: String): Boolean;
    +    function ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
    +    function ReplaceKey(const Key, FileName, BackUpFileName: String): Boolean;
    +    function RestoreKey(const Key, FileName: UnicodeString): Boolean;
    +    function RestoreKey(const Key, FileName: String): Boolean;
    +    function SaveKey(const Key, FileName: UnicodeString): Boolean;
    +    function SaveKey(const Key, FileName: String): Boolean;
    +    function UnLoadKey(const Key: UnicodeString): Boolean;
    +    function UnLoadKey(const Key: String): Boolean;
    +    function ValueExists(const Name: UnicodeString): Boolean;
    +    function ValueExists(const Name: String): Boolean;
     
         procedure CloseKey;
         procedure CloseKey(key:HKEY);
         procedure GetKeyNames(Strings: TStrings);
    +    function GetKeyNames: TUnicodeStringArray;
         procedure GetValueNames(Strings: TStrings);
    -    procedure MoveKey(const OldName, NewName: string; Delete: Boolean);
    -    procedure RenameValue(const OldName, NewName: string);
    -    procedure WriteCurrency(const Name: string; Value: Currency);
    -    procedure WriteBinaryData(const Name: string; var Buffer; BufSize: Integer);
    -    procedure WriteBool(const Name: string; Value: Boolean);
    -    procedure WriteDate(const Name: string; Value: TDateTime);
    -    procedure WriteDateTime(const Name: string; Value: TDateTime);
    -    procedure WriteFloat(const Name: string; Value: Double);
    -    procedure WriteInteger(const Name: string; Value: Integer);
    -    procedure WriteInt64(const Name: string; Value: Int64);
    -    procedure WriteString(const Name, Value: string);
    -    procedure WriteExpandString(const Name, Value: string);
    -    procedure WriteStringList(const Name: string; List: TStrings);
    -    procedure WriteTime(const Name: string; Value: TDateTime);
    +    //ToDo
    +    function GetValueNames: TUnicodeStringArray;
    +    procedure MoveKey(const OldName, NewName: UnicodeString; Delete: Boolean);
    +    procedure MoveKey(const OldName, NewName: String; Delete: Boolean);
    +    procedure RenameValue(const OldName, NewName: UnicodeString);
    +    procedure RenameValue(const OldName, NewName: String);
    +    procedure WriteCurrency(const Name: UnicodeString; Value: Currency);
    +    procedure WriteCurrency(const Name: String; Value: Currency);
    +    procedure WriteBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer);
    +    procedure WriteBinaryData(const Name: String; var Buffer; BufSize: Integer);
    +    procedure WriteBool(const Name: UnicodeString; Value: Boolean);
    +    procedure WriteBool(const Name: String; Value: Boolean);
    +    procedure WriteDate(const Name: UnicodeString; Value: TDateTime);
    +    procedure WriteDate(const Name: String; Value: TDateTime);
    +    procedure WriteDateTime(const Name: UnicodeString; Value: TDateTime);
    +    procedure WriteDateTime(const Name: String; Value: TDateTime);
    +    procedure WriteFloat(const Name: UnicodeString; Value: Double);
    +    procedure WriteFloat(const Name: String; Value: Double);
    +    procedure WriteInteger(const Name: UnicodeString; Value: Integer);
    +    procedure WriteInteger(const Name: String; Value: Integer);
    +    procedure WriteInt64(const Name: UnicodeString; Value: Int64);
    +    procedure WriteInt64(const Name: String; Value: Int64);
    +    procedure WriteString(const Name, Value: UnicodeString);
    +    procedure WriteString(const Name, Value: String);
    +    procedure WriteExpandString(const Name, Value: UnicodeString);
    +    procedure WriteExpandString(const Name, Value: String);
    +    procedure WriteStringList(const Name: UnicodeString; List: TStrings; IsUtf8: Boolean=False);
    +    procedure WriteStringArray(const Name: UnicodeString; const Arr: TUnicodeStringArray);
    +    procedure WriteStringArray(const Name: String; const Arr: TStringArray);
    +    procedure WriteTime(const Name: UnicodeString; Value: TDateTime);
    +    procedure WriteTime(const Name: String; Value: TDateTime);
     
         property Access: LongWord read fAccess write fAccess;
         property CurrentKey: HKEY read fCurrentKey;
    -    property CurrentPath: string read fCurrentPath;
    +    property CurrentPath: UnicodeString read fCurrentPath;
         property LazyWrite: Boolean read fLazyWrite write fLazyWrite;
         property RootKey: HKEY read fRootKey write SetRootKey;
         Property StringSizeIncludesNull : Boolean read FStringSizeIncludesNull;
    @@ -235,6 +293,16 @@
         Generic, implementation-independent code.
       ---------------------------------------------------------------------}
     
    +{$ifdef DebugRegistry}
    +function DbgS(const S: UnicodeString): String;
    +var
    +  C: WideChar;
    +begin
    +  Result := '';
    +  for C in S do Result := Result + IntToHex(Word(C),4) + #32;
    +  Result := TrimRight(Result);
    +end;
    +{$endif}
     
     constructor TRegistry.Create;
     
    @@ -261,7 +329,7 @@
       inherited Destroy;
     end;
     
    -function TRegistry.CreateKey(const Key: string): Boolean;
    +function TRegistry.CreateKey(const Key: UnicodeString): Boolean;
     
     begin
       Result:=SysCreateKey(Key);
    @@ -269,6 +337,27 @@
         Raise ERegistryException.CreateFmt(SRegCreateFailed, [Key]);
     end;
     
    +function TRegistry.CreateKey(const Key: String): Boolean;
    +begin
    +  Result:=CreateKey(UnicodeString(Key));
    +end;
    +
    +function TRegistry.DeleteKey(const Key: String): Boolean;
    +begin
    +  Result:=DeleteKey(UnicodeString(Key));
    +end;
    +
    +function TRegistry.DeleteValue(const Name: String): Boolean;
    +begin
    +  Result:=DeleteValue(UnicodeString(Name));
    +end;
    +
    +function TRegistry.GetDataInfo(const ValueName: String; out Value: TRegDataInfo
    +  ): Boolean;
    +begin
    +  Result:=GetDataInfo(UnicodeString(ValueName), Value);
    +end;
    +
     function TRegistry.GetBaseKey(Relative: Boolean): HKey;
     begin
       If Relative and (CurrentKey<>0) Then
    @@ -277,7 +366,7 @@
         Result := RootKey;
     end;
     
    -function TRegistry.GetData(const Name: string; Buffer: Pointer; BufSize: Integer; out RegData: TRegDataType): Integer;
    +function TRegistry.GetData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; out RegData: TRegDataType): Integer;
     begin
       Result:=SysGetData(Name,Buffer,BufSize,RegData);
       If (Result=-1) then
    @@ -284,7 +373,24 @@
         Raise ERegistryException.CreateFmt(SRegGetDataFailed, [Name]);
     end;
     
    -procedure TRegistry.PutData(const Name: string; Buffer: Pointer;
    +function TRegistry.GetData(const Name: String; Buffer: Pointer;
    +  BufSize: Integer; out RegData: TRegDataType): Integer;
    +begin
    +  Result:=GetData(UnicodeString(Name), Buffer, BufSize, RegData);
    +end;
    +
    +function TRegistry.GetKey(Key: String): HKEY;
    +begin
    +  Result:=GetKey(UnicodeString(Key));
    +end;
    +
    +procedure TRegistry.ChangeKey(Value: HKey; const Path: String);
    +begin
    +  ChangeKey(Value, UnicodeString(Path));
    +end;
    +
    +
    +procedure TRegistry.PutData(const Name: UnicodeString; Buffer: Pointer;
       BufSize: Integer; RegData: TRegDataType);
     
     begin
    @@ -292,9 +398,15 @@
         Raise ERegistryException.CreateFmt(SRegSetDataFailed, [Name]);
     end;
     
    +procedure TRegistry.PutData(const Name: String; Buffer: Pointer;
    +  BufSize: Integer; RegData: TRegDataType);
    +begin
    +  PutData(UnicodeString(Name), Buffer, BufSize, RegData);
    +end;
     
    -function TRegistry.GetDataSize(const ValueName: string): Integer;
     
    +function TRegistry.GetDataSize(const ValueName: UnicodeString): Integer;
    +
     Var
       Info: TRegDataInfo;
     
    @@ -305,8 +417,13 @@
         Result := -1;
     end;
     
    -function TRegistry.GetDataType(const ValueName: string): TRegDataType;
    +function TRegistry.GetDataSize(const ValueName: String): Integer;
    +begin
    +  Result:=GetDataSize(UnicodeString(ValueName));
    +end;
     
    +function TRegistry.GetDataType(const ValueName: UnicodeString): TRegDataType;
    +
     Var
       Info: TRegDataInfo;
     
    @@ -315,6 +432,32 @@
       Result:=Info.RegData;
     end;
     
    +function TRegistry.GetDataType(const ValueName: String): TRegDataType;
    +begin
    +  Result:=GetDataType(UnicodeString(ValueName));
    +end;
    +
    +
    +function TRegistry.KeyExists(const Key: String): Boolean;
    +begin
    +  Result:=KeyExists(UnicodeString(Key));
    +end;
    +
    +function TRegistry.LoadKey(const Key, FileName: String): Boolean;
    +begin
    +  Result:=LoadKey(UnicodeString(Key), UnicodeString(FileName));
    +end;
    +
    +function TRegistry.OpenKey(const Key: String; CanCreate: Boolean): Boolean;
    +begin
    +  Result:=OpenKey(UnicodeString(Key), CanCreate);
    +end;
    +
    +function TRegistry.OpenKeyReadOnly(const Key: String): Boolean;
    +begin
    +  Result:=OpenKeyReadOnly(UnicodeString(Key));
    +end;
    +
     function TRegistry.HasSubKeys: Boolean;
     
     Var
    @@ -326,7 +469,7 @@
         Result:=(Info.NumSubKeys>0);
     end;
     
    -function TRegistry.ReadBinaryData(const Name: string; var Buffer; BufSize: Integer): Integer;
    +function TRegistry.ReadBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer): Integer;
     
     Var
       RegDataType: TRegDataType;
    @@ -337,8 +480,14 @@
         Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
     end;
     
    -function TRegistry.ReadInteger(const Name: string): Integer;
    +function TRegistry.ReadBinaryData(const Name: String; var Buffer;
    +  BufSize: Integer): Integer;
    +begin
    +  Result:=ReadBinaryData(UnicodeString(Name), Buffer, BufSize);
    +end;
     
    +function TRegistry.ReadInteger(const Name: UnicodeString): Integer;
    +
     Var
       RegDataType: TRegDataType;
     
    @@ -348,8 +497,13 @@
         Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
     end;
     
    -function TRegistry.ReadInt64(const Name: string): Int64;
    +function TRegistry.ReadInteger(const Name: String): Integer;
    +begin
    +  Result:=ReadInteger(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadInt64(const Name: UnicodeString): Int64;
    +
     Var
       RegDataType: TRegDataType;
     
    @@ -359,21 +513,36 @@
         Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
     end;
     
    -function TRegistry.ReadBool(const Name: string): Boolean;
    +function TRegistry.ReadInt64(const Name: String): Int64;
    +begin
    +  Result:=ReadInt64(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadBool(const Name: UnicodeString): Boolean;
    +
     begin
       Result:=ReadInteger(Name)<>0;
     end;
     
    -function TRegistry.ReadCurrency(const Name: string): Currency;
    +function TRegistry.ReadBool(const Name: String): Boolean;
    +begin
    +  Result:=ReadBool(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadCurrency(const Name: UnicodeString): Currency;
    +
     begin
       Result:=Default(Currency);
       ReadBinaryData(Name, Result, SizeOf(Currency));
     end;
     
    -function TRegistry.ReadDate(const Name: string): TDateTime;
    +function TRegistry.ReadCurrency(const Name: String): Currency;
    +begin
    +  Result:=ReadCurrency(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadDate(const Name: UnicodeString): TDateTime;
    +
     begin
       Result:=Default(TDateTime);
       ReadBinaryData(Name, Result, SizeOf(TDateTime));
    @@ -380,22 +549,37 @@
       Result:=Trunc(Result);
     end;
     
    -function TRegistry.ReadDateTime(const Name: string): TDateTime;
    +function TRegistry.ReadDate(const Name: String): TDateTime;
    +begin
    +  Result:=ReadDate(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadDateTime(const Name: UnicodeString): TDateTime;
    +
     begin
       Result:=Default(TDateTime);
       ReadBinaryData(Name, Result, SizeOf(TDateTime));
     end;
     
    -function TRegistry.ReadFloat(const Name: string): Double;
    +function TRegistry.ReadDateTime(const Name: String): TDateTime;
    +begin
    +  Result:=ReadDateTime(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadFloat(const Name: UnicodeString): Double;
    +
     begin
       Result:=Default(Double);
       ReadBinaryData(Name,Result,SizeOf(Double));
     end;
     
    -function TRegistry.ReadString(const Name: string): string;
    +function TRegistry.ReadFloat(const Name: String): Double;
    +begin
    +  Result:=ReadFloat(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadString(const Name: UnicodeString): UnicodeString;
    +
     Var
       Info : TRegDataInfo;
       ReadDataSize: Integer;
    @@ -421,47 +605,139 @@
           if StringSizeIncludesNull and
              (u[Length(u)] = WideChar(0)) then
             SetLength(u,Length(u)-1);
    -      Result:=UTF8Encode(u);
    +      Result:=u;
         end;
       end;
     end;
     
    -procedure TRegistry.ReadStringList(const Name: string; AList: TStrings);
    +function TRegistry.ReadString(const Name: String): string;
    +begin
    +  Result:=ReadString(UnicodeString(Name));
    +end;
     
    +
    +procedure TRegistry.ReadStringList(const Name: UnicodeString; AList: TStrings; ForceUtf8: Boolean=False);
    +
     Var
    +  UArr: TUnicodeStringArray;
    +
    +begin
    +  UArr := ReadStringArray(Name);
    +  ArrayToList(UArr, AList, ForceUtf8);
    +end;
    +
    +procedure TRegistry.ReadStringList(const Name: String; AList: TStrings);
    +begin
    +  ReadStringList(UnicodeString(Name), AList);
    +end;
    +
    +function TRegistry.RegMultiSzDataToUnicodeStringArray(U: UnicodeString): TUnicodeStringArray;
    +var
    +  Len, i, p: Integer;
    +  Sub: UnicodeString;
    +begin
    +  Result := nil;
    +  if (U = '') then Exit;
    +  Len := 1;
    +  for i := 1 to Length(U) do if (U[i] = #0) then Inc(Len);
    +  SetLength(Result, Len);
    +  i := 0;
    +
    +  while (U <> '') and (i < Length(Result)) do
    +  begin
    +    p := Pos(#0, U);
    +    if (p = 0) then p := Length(U) + 1;
    +    Sub := Copy(U, 1, p - 1);
    +    Result[i] := Sub;
    +    System.Delete(U, 1, p);
    +    Inc(i);
    +  end;
    +end;
    +
    +function TRegistry.ListToArray(List: TStrings; IsUtf8: Boolean): TUnicodeStringArray;
    +var
    +  i, curr, Len: Integer;
    +  u: UnicodeString;
    +begin
    +  Result := nil;
    +  Len := List.Count;
    +  SetLength(Result, Len);
    +  //REG_MULTI_SZ data cannot contain empty strings
    +  curr := 0;
    +  for i := 0 to List.Count - 1 do
    +  begin
    +    if IsUtf8 then
    +      u := Utf8Decode(List[i])
    +    else
    +      u := List[i];
    +    if (u>'') then
    +    begin
    +      Result[curr] := u;
    +      inc(curr);
    +    end
    +    else
    +      Dec(Len);
    +  end;
    +  if (Len <> List.Count) then SetLength(Result, Len);
    +end;
    +
    +procedure TRegistry.ArrayToList(const Arr: TUnicodeStringArray; List: TStrings; ForceUtf8: Boolean);
    +var
    +  i: Integer;
    +begin
    +  List.Clear;
    +  for i := Low(Arr) to High(Arr) do
    +  begin
    +    if ForceUtf8 then
    +      List.Add(Utf8Encode(Arr[i]))
    +    else
    +      List.Add(String(Arr[i]));
    +  end;
    +end;
    +
    +function TRegistry.ReadStringArray(const Name: UnicodeString): TUnicodeStringArray;
    +Var
       Info : TRegDataInfo;
       ReadDataSize: Integer;
    -  Data: string;
    +  Data: UnicodeString;
     
     begin
    -  AList.Clear;
    +  Result := nil;
       GetDataInfo(Name,Info);
    +  //writeln('TRegistry.ReadStringArray: datasize=',info.datasize);
       if info.datasize>0 then
         begin
          If Not (Info.RegData in [rdMultiString]) then
            Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
          SetLength(Data,Info.DataSize);
    -     ReadDataSize := GetData(Name,PChar(Data),Info.DataSize,Info.RegData);
    +     ReadDataSize := GetData(Name,PWideChar(Data),Info.DataSize,Info.RegData) div SizeOf(WideChar);
    +     //writeln('TRegistry.ReadStringArray: ReadDataSize=',ReadDataSize);
          if ReadDataSize > 0 then
          begin
    -       // If the data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type,
    -       // the size includes any terminating null character or characters
    -       // unless the data was stored without them! (RegQueryValueEx @ MSDN)
    -       if StringSizeIncludesNull then begin
    -         if Data[ReadDataSize] = #0 then
    -           Dec(ReadDataSize);
    -         if Data[ReadDataSize] = #0 then
    -           Dec(ReadDataSize);
    -       end;
    +       // Windows returns the data with or without trailing zero's, so just strip all trailing null characters
    +        while (Data[ReadDataSize] = #0) do Dec(ReadDataSize);
            SetLength(Data, ReadDataSize);
    -       Data := StringReplace(Data, #0, LineEnding, [rfReplaceAll]);
    -       AList.Text := Data;
    +       //writeln('Data=',dbgs(data));
    +       //Data := UnicodeStringReplace(Data, #0, AList.LineBreak, [rfReplaceAll]);
    +       //AList.Text := Data;
    +       Result := RegMultiSzDataToUnicodeStringArray(Data);
          end
        end
     end;
     
    -function TRegistry.ReadTime(const Name: string): TDateTime;
    +function TRegistry.ReadStringArray(const Name: String): TStringArray;
    +var
    +  UArr: TUnicodeStringArray;
    +  i: Integer;
    +begin
    +  Result := nil;
    +  UArr := ReadStringArray(UnicodeString(Name));
    +  SetLength(Result, Length(UArr));
    +  for i := Low(UArr) to High(UArr) do Result[i] := UArr[i];
    +end;
     
    +function TRegistry.ReadTime(const Name: UnicodeString): TDateTime;
    +
     begin
       Result:=Default(TDateTime);
       ReadBinaryData(Name, Result, SizeOf(TDateTime));
    @@ -468,85 +744,230 @@
       Result:=Frac(Result);
     end;
     
    -procedure TRegistry.WriteBinaryData(const Name: string; var Buffer; BufSize: Integer);
    +function TRegistry.ReadTime(const Name: String): TDateTime;
     begin
    +  Result:=ReadTime(UnicodeString(Name));
    +end;
    +
    +function TRegistry.RegistryConnect(const UNCName: String): Boolean;
    +begin
    +  Result:=RegistryConnect(UnicodeString(UNCName));
    +end;
    +
    +function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: String): Boolean;
    +begin
    +  Result:=ReplaceKey(UnicodeString(Key), UnicodeString(FileName), UnicodeString(BackUpFileName))
    +end;
    +
    +function TRegistry.RestoreKey(const Key, FileName: String): Boolean;
    +begin
    +  Result:=RestoreKey(UnicodeString(Key), UnicodeString(FileName));
    +end;
    +
    +function TRegistry.SaveKey(const Key, FileName: String): Boolean;
    +begin
    +  Result:=SaveKey(UnicodeString(Key), UnicodeString(FileName));
    +end;
    +
    +function TRegistry.UnLoadKey(const Key: String): Boolean;
    +begin
    +  Result:=UnloadKey(UnicodeString(Key));
    +end;
    +
    +function TRegistry.ValueExists(const Name: String): Boolean;
    +begin
    +  Result:=ValueExists(UnicodeString(Name));
    +end;
    +
    +procedure TRegistry.WriteBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer);
    +begin
       PutData(Name, @Buffer, BufSize, rdBinary);
     end;
     
    -procedure TRegistry.WriteBool(const Name: string; Value: Boolean);
    +procedure TRegistry.WriteBinaryData(const Name: String; var Buffer;
    +  BufSize: Integer);
    +begin
    +  WriteBinaryData(UnicodeString(Name), Buffer, BufSize);
    +end;
     
    +procedure TRegistry.WriteBool(const Name: UnicodeString; Value: Boolean);
    +
     begin
       WriteInteger(Name,Ord(Value));
     end;
     
    -procedure TRegistry.WriteCurrency(const Name: string; Value: Currency);
    +procedure TRegistry.WriteBool(const Name: String; Value: Boolean);
     begin
    +  WriteBool(UnicodeString(Name), Value);
    +end;
    +
    +procedure TRegistry.WriteCurrency(const Name: UnicodeString; Value: Currency);
    +begin
       WriteBinaryData(Name, Value, SizeOf(Currency));
     end;
     
    -procedure TRegistry.WriteDate(const Name: string; Value: TDateTime);
    +procedure TRegistry.WriteCurrency(const Name: String; Value: Currency);
     begin
    +  WriteCurrency(UnicodeString(Name), Value);
    +end;
    +
    +procedure TRegistry.WriteDate(const Name: UnicodeString; Value: TDateTime);
    +begin
       WriteBinarydata(Name, Value, SizeOf(TDateTime));
     end;
     
    -procedure TRegistry.WriteTime(const Name: string; Value: TDateTime);
    +procedure TRegistry.WriteDate(const Name: String; Value: TDateTime);
     begin
    +  WriteDate(UnicodeString(Name), Value);
    +end;
    +
    +procedure TRegistry.WriteTime(const Name: UnicodeString; Value: TDateTime);
    +begin
       WriteBinaryData(Name, Value, SizeOf(TDateTime));
     end;
     
    -procedure TRegistry.WriteDateTime(const Name: string; Value: TDateTime);
    +procedure TRegistry.WriteTime(const Name: String; Value: TDateTime);
     begin
    +  WriteTime(UnicodeString(Name), Value);
    +end;
    +
    +procedure TRegistry.WriteDateTime(const Name: UnicodeString; Value: TDateTime);
    +begin
       WriteBinaryData(Name, Value, SizeOf(TDateTime));
     end;
     
    -procedure TRegistry.WriteExpandString(const Name, Value: string);
    -var
    -  u: UnicodeString;
    +procedure TRegistry.WriteDateTime(const Name: String; Value: TDateTime);
    +begin
    +  WriteDateTime(UnicodeString(Name), Value);
    +end;
     
    +procedure TRegistry.WriteExpandString(const Name, Value: UnicodeString);
     begin
    -  u:=Value;
    -  PutData(Name, PWideChar(u), ByteLength(u), rdExpandString);
    +  PutData(Name, PWideChar(Value), ByteLength(Value), rdExpandString);
     end;
     
    -procedure TRegistry.WriteStringList(const Name: string; List: TStrings);
    +procedure TRegistry.WriteExpandString(const Name, Value: String);
    +begin
    +  WriteExpandString(UnicodeString(Name), UnicodeString(Value));
    +end;
     
    +
    +procedure TRegistry.WriteStringList(const Name: UnicodeString; List: TStrings; IsUtf8: Boolean=False);
    +
     Var
    -  Data: string;
    +  UArr: TUnicodeStringArray;
    +begin
    +  UArr := ListToArray(List, IsUtf8);
    +  WriteStringArray(Name, UArr);
    +end;
     
    +procedure TRegistry.WriteStringArray(const Name: UnicodeString; const Arr: TUnicodeStringArray);
    +Var
    +  Data: UnicodeString;
    +  u: UnicodeString;
    +  i: Integer;
     begin
    -  Data := StringReplace(List.Text, LineEnding, #0, [rfReplaceAll]) + #0#0;
    -  PutData(Name, PChar(Data), Length(Data),rdMultiString);
    +  Data := '';
    +  //REG_MULTI_SZ data cannot contain empty strings
    +  for i := Low(Arr) to High(Arr) do
    +  begin
    +    u := Arr[i];
    +    if (u>'') then
    +    begin
    +      if (Data>'') then
    +        Data := Data + #0 + u
    +      else
    +        Data := Data + u;
    +    end;
    +  end;
    +  if StringSizeIncludesNull then
    +    Data := Data + #0#0;
    +  //writeln('Data=',Dbgs(Data));
    +  PutData(Name, PWideChar(Data), ByteLength(Data), rdMultiString);
     end;
     
    -procedure TRegistry.WriteFloat(const Name: string; Value: Double);
    +procedure TRegistry.WriteStringArray(const Name: String; const Arr: TStringArray);
    +var
    +  UArr: TUnicodeStringArray;
    +  i: Integer;
     begin
    +  UArr := nil;
    +  SetLength(UArr, Length(Arr));
    +  for i := Low(Arr) to High(Arr) do UArr[i] := Arr[i];
    +  WriteStringArray(UnicodeString(Name), UArr);
    +end;
    +
    +procedure TRegistry.WriteFloat(const Name: UnicodeString; Value: Double);
    +begin
       WriteBinaryData(Name, Value, SizeOf(Double));
     end;
     
    -procedure TRegistry.WriteInteger(const Name: string; Value: Integer);
    +procedure TRegistry.WriteFloat(const Name: String; Value: Double);
     begin
    +  WriteFloat(UnicodeString(Name), Value);
    +end;
    +
    +procedure TRegistry.WriteInteger(const Name: UnicodeString; Value: Integer);
    +begin
       PutData(Name, @Value, SizeOf(Integer), rdInteger);
     end;
     
    -procedure TRegistry.WriteInt64(const Name: string; Value: Int64);
    +procedure TRegistry.WriteInteger(const Name: String; Value: Integer);
     begin
    +  WriteInteger(UnicodeString(Name), Value);
    +end;
    +
    +procedure TRegistry.WriteInt64(const Name: UnicodeString; Value: Int64);
    +begin
       PutData(Name, @Value, SizeOf(Int64), rdInt64);
     end;
     
    -procedure TRegistry.WriteString(const Name, Value: string);
    +procedure TRegistry.WriteInt64(const Name: String; Value: Int64);
    +begin
    +  WriteInt64(UnicodeString(Name), Value);
    +end;
    +
    +procedure TRegistry.WriteString(const Name, Value: UnicodeString);
    +begin
    +  PutData(Name, PWideChar(Value), ByteLength(Value), rdString);
    +end;
    +
    +procedure TRegistry.WriteString(const Name, Value: String);
    +begin
    +  WriteString(UnicodeString(Name), UnicodeString(Value));
    +end;
    +
    +procedure TRegistry.GetKeyNames(Strings: TStrings);
     var
    -  u: UnicodeString;
    +  UArr: TUnicodeStringArray;
    +begin
    +  UArr := GetKeyNames;
    +  ArrayToList(UArr, Strings, True);
    +end;
     
    +procedure TRegistry.GetValueNames(Strings: TStrings);
    +var
    +  UArr: TUnicodeStringArray;
     begin
    -  u:=Value;
    -  PutData(Name, PWideChar(u), ByteLength(u), rdString);
    +  UArr := GetValueNames;
    +  ArrayToList(UArr, Strings, True);
     end;
     
    -procedure TRegistry.MoveKey(const OldName, NewName: string; Delete: Boolean);
    +procedure TRegistry.MoveKey(const OldName, NewName: UnicodeString; Delete: Boolean);
     begin
     
     end;
     
    +procedure TRegistry.MoveKey(const OldName, NewName: String; Delete: Boolean);
    +begin
    +  MoveKey(UnicodeString(OldName), UnicodeString(NewName), Delete);
    +end;
    +
    +procedure TRegistry.RenameValue(const OldName, NewName: String);
    +begin
    +  RenameValue(UnicodeString(OldName), UnicodeString(NewName));
    +end;
    +
     { ---------------------------------------------------------------------
         Include TRegIniFile implementation
       ---------------------------------------------------------------------}
    @@ -583,7 +1004,7 @@
       Value: TStream): Integer;
     begin
       result:=-1; // unimplemented
    - // 
    + //
     end;
     
     function TRegistryIniFile.ReadDate(const Section, Name: string;
    Index: packages/fcl-registry/src/winreg.inc
    ===================================================================
    --- packages/fcl-registry/src/winreg.inc	(revision 41667)
    +++ packages/fcl-registry/src/winreg.inc	(working copy)
    @@ -28,7 +28,7 @@
       Dispose(PWinRegData(FSysData));
     end;
     
    -Function PrepKey(Const S : String) : String;
    +Function PrepKey(Const S : UnicodeString) : UnicodeString;
     
     begin
       Result := S;
    @@ -36,7 +36,7 @@
         System.Delete(Result, 1, 1);
     end;
     
    -Function RelativeKey(Const S : String) : Boolean;
    +Function RelativeKey(Const S : UnicodeString) : Boolean;
     
     begin
       Result:=(S='') or (S[1]<>'\')
    @@ -43,9 +43,8 @@
     end;
     
     
    -function TRegistry.sysCreateKey(const Key: String): Boolean;
    +function TRegistry.sysCreateKey(Key: UnicodeString): Boolean;
     Var
    -  u: UnicodeString;
       Disposition: Dword;
       Handle: HKEY;
       SecurityAttributes: Pointer; //LPSECURITY_ATTRIBUTES;
    @@ -52,9 +51,9 @@
     
     begin
       SecurityAttributes := Nil;
    -  u:=PrepKey(Key);
    +  Key:=PrepKey(Key);
       FLastError:=RegCreateKeyExW(GetBaseKey(RelativeKey(Key)),
    -                              PWideChar(u),
    +                              PWideChar(Key),
                                   0,
                                   '',
                                   REG_OPTION_NON_VOLATILE,
    @@ -66,7 +65,7 @@
       RegCloseKey(Handle);
     end;
     
    -function TRegistry.DeleteKey(const Key: String): Boolean;
    +function TRegistry.DeleteKey(const Key: UnicodeString): Boolean;
     
     Var
       u: UnicodeString;
    @@ -76,21 +75,21 @@
       Result:=FLastError=ERROR_SUCCESS;
     end;
     
    -function TRegistry.DeleteValue(const Name: String): Boolean;
    +
    +function TRegistry.DeleteValue(const Name: UnicodeString): Boolean;
     begin
    -  FLastError:= RegDeleteValueW(fCurrentKey, PWideChar(UnicodeString(Name)));
    +  FLastError:= RegDeleteValueW(fCurrentKey, PWideChar(Name));
       Result:=FLastError=ERROR_SUCCESS;
     end;
     
    -function TRegistry.SysGetData(const Name: String; Buffer: Pointer;
    +
    +function TRegistry.SysGetData(const Name: UnicodeString; Buffer: Pointer;
               BufSize: Integer; Out RegData: TRegDataType): Integer;
     Var
    -  u: UnicodeString;
       RD : DWord;
     
     begin
    -  u := Name;
    -  FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(u),Nil,
    +  FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(Name),Nil,
                           @RD,Buffer,lpdword(@BufSize));
       if (FLastError<>ERROR_SUCCESS) Then
         Result:=-1
    @@ -103,17 +102,15 @@
         end;
     end;
     
    -function TRegistry.GetDataInfo(const ValueName: String; out Value: TRegDataInfo): Boolean;
    +function TRegistry.GetDataInfo(const ValueName: UnicodeString; out Value: TRegDataInfo): Boolean;
     
     Var
    -  u: UnicodeString;
       RD : DWord;
     
     begin
    -  u:=ValueName;
       With Value do
         begin
    -    FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(u),Nil,lpdword(@RegData),Nil,lpdword(@DataSize));
    +    FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(ValueName),Nil,lpdword(@RegData),Nil,lpdword(@DataSize));
         Result:=FLastError=ERROR_SUCCESS;
         if Result then
           begin
    @@ -131,24 +128,18 @@
     end;
     
     
    -function TRegistry.GetKey(const Key: String): HKEY;
    +function TRegistry.GetKey(Key: UnicodeString): HKEY;
     var
    -  S : string;
    -{$ifndef WinCE}
    -  u : UnicodeString;
    -{$endif}
       Rel : Boolean;
     begin
       Result:=0;
    -  S:=Key;
    -  Rel:=RelativeKey(S);
    +  Rel:=RelativeKey(Key);
       if not(Rel) then
    -    Delete(S,1,1);
    +    Delete(Key,1,1);
     {$ifdef WinCE}
    -  FLastError:=RegOpenKeyEx(GetBaseKey(Rel),PWideChar(WideString(S)),0,FAccess,Result);
    +  FLastError:=RegOpenKeyEx(GetBaseKey(Rel),PWideChar(Key),0,FAccess,Result);
     {$else WinCE}
    -  u:=UnicodeString(S);
    -  FLastError:=RegOpenKeyExW(GetBaseKey(Rel),PWideChar(u),0,FAccess,Result);
    +  FLastError:=RegOpenKeyExW(GetBaseKey(Rel),PWideChar(Key),0,FAccess,Result);
     {$endif WinCE}
     end;
     
    @@ -158,7 +149,7 @@
       winFileTime: Windows.FILETIME;
       sysTime: TSystemTime;
     begin
    -  FillChar(Value, SizeOf(Value), 0);
    +  Value := Default(TRegKeyInfo);
       With Value do
         begin
         FLastError:=RegQueryInfoKeyA(CurrentKey,nil,nil,nil,lpdword(@NumSubKeys),
    @@ -174,7 +165,7 @@
     end;
     
     
    -function TRegistry.KeyExists(const Key: string): Boolean;
    +function TRegistry.KeyExists(const Key: UnicodeString): Boolean;
     var
       KeyHandle : HKEY;
       OldAccess : LONG;
    @@ -196,20 +187,20 @@
     end;
     
     
    -function TRegistry.LoadKey(const Key, FileName: string): Boolean;
    +function TRegistry.LoadKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
     
    -function TRegistry.OpenKey(const Key: string; CanCreate: Boolean): Boolean;
     
    +function TRegistry.OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
    +
     Var
    -  u: UnicodeString;
    +  u, S: UnicodeString;
       Handle: HKEY;
       Disposition: Integer;
       SecurityAttributes: Pointer; //LPSECURITY_ATTRIBUTES;
    -  S: string;
     begin
       SecurityAttributes := Nil;
       u:=PrepKey(Key);
    @@ -232,13 +223,14 @@
         if RelativeKey(Key) then
           S:=CurrentPath + Key
         else
    -      S:=UTF8Encode(u);
    +      S:=u;
         ChangeKey(Handle, S);
       end;
     end;
     
    -function TRegistry.OpenKeyReadOnly(const Key: string): Boolean;
     
    +function TRegistry.OpenKeyReadOnly(const Key: UnicodeString): Boolean;
    +
     Var
       OldAccess: LongWord;
     begin
    @@ -251,7 +243,8 @@
       end;
     end;
     
    -function TRegistry.RegistryConnect(const UNCName: string): Boolean;
    +
    +function TRegistry.RegistryConnect(const UNCName: UnicodeString): Boolean;
     {$ifndef WinCE}
     var
       newroot: HKEY;
    @@ -260,7 +253,7 @@
     {$ifdef WinCE}
       Result:=False;
     {$else}
    -  FLastError:=RegConnectRegistryW(PWideChar(UnicodeString(UNCName)),RootKey,newroot);
    +  FLastError:=RegConnectRegistryW(PWideChar(UNCName),RootKey,newroot);
       Result:=FLastError=ERROR_SUCCESS;
       if Result then begin
         RootKey:=newroot;
    @@ -269,28 +262,33 @@
     {$endif}
     end;
     
    -function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
    +
    +function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.RestoreKey(const Key, FileName: string): Boolean;
    +
    +function TRegistry.RestoreKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.SaveKey(const Key, FileName: string): Boolean;
    +
    +function TRegistry.SaveKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.UnLoadKey(const Key: string): Boolean;
    +
    +function TRegistry.UnLoadKey(const Key: UnicodeString): Boolean;
     begin
       Result := false;
     end;
     
    -function TRegistry.ValueExists(const Name: string): Boolean;
     
    +function TRegistry.ValueExists(const Name: UnicodeString): Boolean;
    +
     var
       Info : TRegDataInfo;
     
    @@ -298,6 +296,7 @@
       Result:=GetDataInfo(Name,Info);
     end;
     
    +
     procedure TRegistry.CloseKey;
     begin
       If (CurrentKey<>0) then
    @@ -316,7 +315,7 @@
       RegCloseKey(key);
     end;
     
    -procedure TRegistry.ChangeKey(Value: HKey; const Path: String);
    +procedure TRegistry.ChangeKey(Value: HKey; const Path: UnicodeString);
     begin
       CloseKey;
       FCurrentKey:=Value;
    @@ -323,8 +322,9 @@
       FCurrentPath:=Path;
     end;
     
    -procedure TRegistry.GetKeyNames(Strings: TStrings);
     
    +function TRegistry.GetKeyNames: TUnicodeStringArray;
    +
     var
       Info:    TRegKeyInfo;
       dwLen:   DWORD;
    @@ -331,15 +331,17 @@
       lpName:  LPWSTR;
       dwIndex: DWORD;
       lResult: LONGINT;
    -  s:       string;
    +  u:       UnicodeString;
     
     begin
    -  Strings.Clear;
    +  Result:=nil;
       if GetKeyInfo(Info) then
       begin
         dwLen:=Info.MaxSubKeyLen+1;
         GetMem(lpName,dwLen*SizeOf(WideChar));
         try
    +      //writeln('TRegistry.GetKeyNames: Info.NumSubKeys=',Info.NumSubKeys);
    +      SetLength(Result, Info.NumSubKeys);
           for dwIndex:=0 to Info.NumSubKeys-1 do
           begin
             dwLen:=Info.MaxSubKeyLen+1;
    @@ -347,19 +349,13 @@
             if lResult<>ERROR_SUCCESS then
               raise ERegistryException.Create(SysErrorMessage(lResult));
             if dwLen=0 then
    -          s:=''
    +          u:=''
             else
             begin           // dwLen>0
    -          SetLength(s,dwLen*3);
    -          dwLen:=UnicodeToUTF8(PChar(s),Length(s)+1,lpName,dwLen);
    -          if dwLen<=1 then
    -            s:=''
    -          else          // dwLen>1
    -            SetLength(s,dwLen-1);
    +          u:=lpName;
             end;            // if dwLen=0
    -        Strings.Add(s);
    +        Result[dwIndex]:=u;
           end;              // for dwIndex:=0 ...
    -
         finally
           FreeMem(lpName);
         end;
    @@ -366,8 +362,9 @@
       end;
     end;
     
    -procedure TRegistry.GetValueNames(Strings: TStrings);
     
    +Function TRegistry.GetValueNames: TUnicodeStringArray;
    +
     var
       Info:    TRegKeyInfo;
       dwLen:   DWORD;
    @@ -374,15 +371,16 @@
       lpName:  LPWSTR;
       dwIndex: DWORD;
       lResult: LONGINT;
    -  s:       string;
    +  u:       UnicodeString;
     
     begin
    -   Strings.Clear;
    +  Result:=nil;
       if GetKeyInfo(Info) then
       begin
         dwLen:=Info.MaxValueLen+1;
         GetMem(lpName,dwLen*SizeOf(WideChar));
         try
    +      SetLength(Result, Info.NumValues);
           for dwIndex:=0 to Info.NumValues-1 do
           begin
             dwLen:=Info.MaxValueLen+1;
    @@ -390,17 +388,12 @@
             if lResult<>ERROR_SUCCESS then
               raise ERegistryException.Create(SysErrorMessage(lResult));
             if dwLen=0 then
    -          s:=''
    +          u:=''
             else
             begin           // dwLen>0
    -          SetLength(s,dwLen*3);
    -          dwLen:=UnicodeToUTF8(PChar(s),Length(s)+1,lpName,dwLen);
    -          if dwLen<=1 then
    -            s:=''
    -          else          // dwLen>1
    -            SetLength(s,dwLen-1);
    +          u:=lpName;
             end;            // if dwLen=0
    -        Strings.Add(s);
    +        Result[dwIndex]:=u;
           end;              // for dwIndex:=0 ...
     
         finally
    @@ -410,12 +403,11 @@
     end;
     
     
    -Function TRegistry.SysPutData(const Name: string; Buffer: Pointer;
    +Function TRegistry.SysPutData(const Name: UnicodeString; Buffer: Pointer;
       BufSize: Integer; RegData: TRegDataType) : Boolean;
     
     
     Var
    -  u: UnicodeString;
       RegDataType: DWORD;
       B : Pchar;
       S : String;
    @@ -422,12 +414,11 @@
     
     begin
       RegDataType:=RegDataWords[RegData];
    -  u:=UnicodeString(Name);
    -  FLastError:=RegSetValueExW(fCurrentKey,PWideChar(u),0,RegDataType,Buffer,BufSize);
    +  FLastError:=RegSetValueExW(fCurrentKey,PWideChar(Name),0,RegDataType,Buffer,BufSize);
       Result:=FLastError=ERROR_SUCCESS;
     end;
     
    -procedure TRegistry.RenameValue(const OldName, NewName: string);
    +procedure TRegistry.RenameValue(const OldName, NewName: UnicodeString);
     
     var
       L: Integer;
    Index: packages/fcl-registry/src/xmlreg.pp
    ===================================================================
    --- packages/fcl-registry/src/xmlreg.pp	(revision 41667)
    +++ packages/fcl-registry/src/xmlreg.pp	(working copy)
    @@ -25,6 +25,7 @@
         FTime     : TDateTime;
       end;
     
    +  TUnicodeStringArray = Array of UnicodeString;
     
       { TXmlRegistry }
     
    @@ -33,24 +34,24 @@
         FAutoFlush,
         FDirty : Boolean;
         FFileName : String;
    -    FRootKey : String;
    +    FRootKey : UnicodeString;
         FDocument : TXMLDocument;
         FCurrentElement : TDomElement;
    -    FCurrentKey : String;
    +    FCurrentKey : UnicodeString;
         Procedure SetFileName(Value : String);
       Protected
    -    function DoGetValueData(Name: String; out DataType: TDataType; Var Data; Var DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
    -    function DoSetValueData(Name: String; DataType: TDataType; const Data; DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
    +    function DoGetValueData(Name: UnicodeString; out DataType: TDataType; Var Data; Var DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
    +    function DoSetValueData(Name: UnicodeString; DataType: TDataType; const Data; DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
         Procedure LoadFromStream(S : TStream);
    -    Function  NormalizeKey(KeyPath : String) : String;
    +    Function  NormalizeKey(KeyPath : UnicodeString) : UnicodeString;
         Procedure CreateEmptyDoc;
    -    Function  FindKey (S : String) : TDomElement;
    -    Function  FindSubKey (S : String; N : TDomElement) : TDomElement;
    -    Function  CreateSubKey (S : String; N : TDomElement) : TDomElement;
    -    Function  FindValueKey (S : String) : TDomElement;
    -    Function  CreateValueKey (S : String) : TDomElement;
    +    Function  FindKey (S : UnicodeString) : TDomElement;
    +    Function  FindSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
    +    Function  CreateSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
    +    Function  FindValueKey (S : UnicodeString) : TDomElement;
    +    Function  CreateValueKey (S : UnicodeString) : TDomElement;
         Function  BufToHex(Const Buf; Len : Integer) : String;
    -    Function  hexToBuf(Const Str : String; Var Buf; Var Len : Integer ) : Integer;
    +    Function  HexToBuf(Const Str : UnicodeString; Var Buf; Var Len : Integer ) : Integer;
         Procedure MaybeFlush;
         Property  Document : TXMLDocument Read FDocument;
         Property  Dirty : Boolean Read FDirty write FDirty;
    @@ -57,29 +58,31 @@
       Public
         Constructor Create(AFileName : String);
         Destructor  Destroy;override;
    -    Function  SetKey(KeyPath : String; AllowCreate : Boolean) : Boolean ;
    -    Procedure SetRootKey(Value : String);
    -    Function  DeleteKey(KeyPath : String) : Boolean;
    -    Function  CreateKey(KeyPath : String) : Boolean;
    -    Function  GetValueSize(Name : String) : Integer;
    -    Function  GetValueType(Name : String) : TDataType;
    -    Function  GetValueInfo(Name : String; Out Info : TDataInfo; AsUnicode : Boolean = False) : Boolean;
    +    Function  SetKey(KeyPath : UnicodeString; AllowCreate : Boolean) : Boolean ;
    +    Procedure SetRootKey(Value : UnicodeString);
    +    Function  DeleteKey(KeyPath : UnicodeString) : Boolean;
    +    Function  CreateKey(KeyPath : UnicodeString) : Boolean;
    +    Function  GetValueSize(Name : UnicodeString) : Integer;
    +    Function  GetValueType(Name : UnicodeString) : TDataType;
    +    Function  GetValueInfo(Name : UnicodeString; Out Info : TDataInfo; AsUnicode : Boolean = False) : Boolean;
         Function  GetKeyInfo(Out Info : TKeyInfo) : Boolean;
         Function  EnumSubKeys(List : TStrings) : Integer;
    +    Function  EnumSubKeys: TUnicodeStringArray;
         Function  EnumValues(List : TStrings) : Integer;
    -    Function  KeyExists(KeyPath : String) : Boolean;
    -    Function  ValueExists(ValueName : String) : Boolean;
    -    Function  RenameValue(Const OldName,NewName : String) : Boolean;
    -    Function  DeleteValue(S : String) : Boolean;
    +    Function  EnumValues: TUnicodeStringArray;
    +    Function  KeyExists(KeyPath : UnicodeString) : Boolean;
    +    Function  ValueExists(ValueName : UnicodeString) : Boolean;
    +    Function  RenameValue(Const OldName,NewName : UnicodeString) : Boolean;
    +    Function  DeleteValue(S : UnicodeString) : Boolean;
         Procedure Flush;
         Procedure Load;
    -    Function GetValueData(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
    -    Function SetValueData(Name : String; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
    +    Function GetValueData(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
    +    Function SetValueData(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
         // These interpret the Data buffer as unicode data
    -    Function GetValueDataUnicode(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
    -    Function SetValueDataUnicode(Name : String; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
    +    Function GetValueDataUnicode(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
    +    Function SetValueDataUnicode(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
         Property FileName : String Read FFileName Write SetFileName;
    -    Property RootKey : String Read FRootKey Write SetRootkey;
    +    Property RootKey : UnicodeString Read FRootKey Write SetRootkey;
         Property AutoFlush : Boolean Read FAutoFlush Write FAutoFlush;
       end;
     
    @@ -143,13 +146,13 @@
       end;
     end;
     
    -Function TXmlRegistry.NormalizeKey(KeyPath : String) : String;
    +Function TXmlRegistry.NormalizeKey(KeyPath : UnicodeString) : UnicodeString;
     
     Var
       L : Integer;
     
     begin
    -  Result:=StringReplace(KeyPath,'\','/',[rfReplaceAll]);
    +  Result:=UnicodeStringReplace(KeyPath,'\','/',[rfReplaceAll]);
       L:=Length(Result);
       If (L>0) and (Result[L]<>'/') then
         Result:=Result+'/';
    @@ -157,10 +160,10 @@
         Result:='/' + Result;
     end;
     
    -Function TXmlRegistry.SetKey(KeyPath : String; AllowCreate : Boolean) : boolean;
    +Function TXmlRegistry.SetKey(KeyPath : UnicodeString; AllowCreate : Boolean) : boolean;
     
     Var
    -  SubKey,ResultKey : String;
    +  SubKey,ResultKey : UnicodeString;
       P : Integer;
       Node,Node2 : TDomElement;
     
    @@ -218,7 +221,7 @@
       MaybeFlush;
     end;
     
    -Procedure TXmlRegistry.SetRootKey(Value : String);
    +Procedure TXmlRegistry.SetRootKey(Value : UnicodeString);
     
     begin
       FRootKey:=NormalizeKey(Value);
    @@ -228,7 +231,7 @@
       FCurrentElement:=Nil;
     end;
     
    -Function TXmlRegistry.DeleteKey(KeyPath : String) : Boolean;
    +Function TXmlRegistry.DeleteKey(KeyPath : UnicodeString) : Boolean;
     
     Var
       N : TDomElement;
    @@ -244,10 +247,10 @@
        end;
     end;
     
    -Function TXmlRegistry.CreateKey(KeyPath : String) : Boolean;
    +Function TXmlRegistry.CreateKey(KeyPath : UnicodeString) : Boolean;
     
     Var
    -  SubKey : String;
    +  SubKey : UnicodeString;
       P : Integer;
       Node,Node2 : TDomElement;
     
    @@ -290,7 +293,7 @@
       MaybeFlush;
     end;
     
    -Function TXmlRegistry.DoGetValueData(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer; IsUnicode : Boolean) : Boolean;
    +Function TXmlRegistry.DoGetValueData(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer; IsUnicode : Boolean) : Boolean;
     
     Type
       PCardinal = ^Cardinal;
    @@ -305,22 +308,27 @@
       D : DWord;
       
     begin
    +  //writeln('TXmlRegistry.DoGetValueData: Name=',Name,' IsUnicode=',IsUnicode);
       Node:=FindValueKey(Name);
       Result:=Node<>Nil;
       If Result then
         begin
    +    //writeln('TXmlRegistry.DoGetValueData: Node<>nil');
         DataNode:=Node.FirstChild;
         HasData:=Assigned(DataNode) and (DataNode.NodeType=TEXT_NODE);
    -    ND:=StrToIntDef(Node[Stype],0);
    +    //writeln('TXmlRegistry.DoGetValueData: HasData=',hasdata);
    +    ND:=StrToIntDef(String(Node[Stype]),0);
    +    //writeln('TXmlRegistry.DoGetValueData: ND=',ND);
         Result:=ND<=Ord(High(TDataType));
         If Result then
           begin
           DataType:=TDataType(ND);
    +      //writeln('TXmlRegistry.DoGetValueData: DataType=',DataType);
           NS:=0; // Initialize, for optional nodes.
           Case DataType of
             dtDWORD : begin   // DataNode is required
                       NS:=SizeOf(Cardinal);
    -                  Result:=HasData and TryStrToDWord(DataNode.NodeValue,D) and (DataSize>=NS);
    +                  Result:=HasData and TryStrToDWord(String(DataNode.NodeValue),D) and (DataSize>=NS);
                       if Result then
                         PCardinal(@Data)^:=D;
                       end;
    @@ -329,7 +337,7 @@
                          begin
                          if not IsUnicode then
                            begin
    -                       S:=UTF8Encode(DataNode.NodeValue); // Convert to ansistring
    +                       S:=DataNode.NodeValue; // Convert to ansistring
                            NS:=Length(S);
                            Result:=(DataSize>=NS);
                            if Result then
    @@ -350,8 +358,10 @@
                        if HasData then
                          begin
                          BL:=Length(DataNode.NodeValue);
    +                     //writeln('TXmlRegistry.DoGetValueData: BL=',BL);
                          NS:=BL div 2;
                          Result:=DataSize>=NS;
    +                     //writeln('TXmlRegistry.DoGetValueData: Result=',Result);
                          If Result then
                            // No need to check for -1, We checked NS before calling.
                            NS:=HexToBuf(DataNode.NodeValue,Data,BL);
    @@ -363,7 +373,7 @@
         end;
     end;
     
    -Function TXmlRegistry.DoSetValueData(Name : String; DataType : TDataType; Const Data; DataSize : Integer; IsUnicode : Boolean) : Boolean;
    +Function TXmlRegistry.DoSetValueData(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer; IsUnicode : Boolean) : Boolean;
     
     Type
       PCardinal = ^Cardinal;
    @@ -374,6 +384,7 @@
       SW : UnicodeString;
     
     begin
    +  //writeln('TXmlRegistry.DoSetValueData A: Name=',Name,', DataType=',DataType,', DataSize=',DataSize,', IsUnicode=',IsUnicode);
       Node:=FindValueKey(Name);
       If Node=Nil then
         Node:=CreateValueKey(Name);
    @@ -380,20 +391,20 @@
       Result:=(Node<>Nil);
       If Result then
         begin
    -    Node[SType]:=IntToStr(Ord(DataType));
    +    Node[SType]:=UnicodeString(IntToStr(Ord(DataType)));
         DataNode:=Node.FirstChild;
     
         Case DataType of
    -      dtDWORD : SW:=IntToStr(PCardinal(@Data)^);
    +      dtDWORD : SW:=UnicodeString(IntToStr(PCardinal(@Data)^));
           dtString : begin
                      if IsUnicode then
                        SW:=UnicodeString(PUnicodeChar(@Data))
                      else
                        SW:=UnicodeString(PAnsiChar(@Data));
    -                   //S:=UTF8Encode(SW);
    +                   //S:=SW;
                      end;
    -      dtBinary : SW:=BufToHex(Data,DataSize);
    -      dtStrings : SW:=BufToHex(Data,DataSize);
    +      dtBinary : SW:=UnicodeString(BufToHex(Data,DataSize));
    +      dtStrings : SW:=UnicodeString(BufToHex(Data,DataSize));
         else
           sw:='';
         end;
    @@ -416,29 +427,29 @@
         end;
     end;
     
    -Function TXmlRegistry.SetValueData(Name : String; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
    +Function TXmlRegistry.SetValueData(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
     
     begin
       Result:=DoSetValueData(Name,DataType,Data,DataSize,False);
     end;
     
    -Function TXmlRegistry.GetValueData(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
    +Function TXmlRegistry.GetValueData(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
     
     begin
       Result:=DoGetValueData(Name,DataType,Data,DataSize,False);
     end;
     
    -function TXmlRegistry.GetValueDataUnicode(Name: String; out DataType: TDataType; Var Data; Var DataSize: Integer): Boolean;
    +function TXmlRegistry.GetValueDataUnicode(Name: UnicodeString; out DataType: TDataType; Var Data; Var DataSize: Integer): Boolean;
     begin
       Result:=DoGetValueData(Name,DataType,Data,DataSize,True);
     end;
     
    -function TXmlRegistry.SetValueDataUnicode(Name: String; DataType: TDataType; const Data; DataSize: Integer): Boolean;
    +function TXmlRegistry.SetValueDataUnicode(Name: UnicodeString; DataType: TDataType; const Data; DataSize: Integer): Boolean;
     begin
       Result:=DoSetValueData(Name,DataType,Data,DataSize,True)
     end;
     
    -Function TXmlRegistry.FindSubKey (S : String; N : TDomElement) : TDomElement;
    +Function TXmlRegistry.FindSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
     
     Var
       Node : TDOMNode;
    @@ -451,7 +462,7 @@
         While (Result=Nil) and (Assigned(Node)) do
           begin
           If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SKey) then
    -        If CompareText(TDomElement(Node)[SName],S)=0 then
    +        If UnicodeCompareText(TDomElement(Node)[SName],S)=0 then
               Result:=TDomElement(Node);
           Node:=Node.NextSibling;
           end;
    @@ -458,7 +469,7 @@
         end;
     end;
     
    -Function TXmlRegistry.CreateSubKey (S : String; N : TDomElement) : TDomElement;
    +Function TXmlRegistry.CreateSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
     
     begin
       Result:=FDocument.CreateElement(SKey);
    @@ -468,7 +479,7 @@
       FDirty:=True;
     end;
     
    -Function  TXmlRegistry.FindValueKey (S : String) : TDomElement;
    +Function  TXmlRegistry.FindValueKey (S : UnicodeString) : TDomElement;
     
     Var
       Node : TDOMNode;
    @@ -481,7 +492,7 @@
         While (Result=Nil) and (Assigned(Node)) do
           begin
           If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SValue) then
    -        If CompareText(TDomElement(Node)[SName],S)=0 then
    +        If UnicodeCompareText(TDomElement(Node)[SName],S)=0 then
               Result:=TDomElement(Node);
           Node:=Node.NextSibling;
           end;
    @@ -488,7 +499,7 @@
         end;
     end;
     
    -Function  TXmlRegistry.CreateValueKey (S : String) : TDomElement;
    +Function  TXmlRegistry.CreateValueKey (S : UnicodeString) : TDomElement;
     
     begin
       If Assigned(FCurrentElement) then
    @@ -581,38 +592,47 @@
         end;
     end;
     
    -Function TXMLRegistry.hexToBuf(Const Str : String; Var Buf; Var Len : Integer ) : Integer;
    +Function TXMLRegistry.HexToBuf(Const Str : UnicodeString; Var Buf; Var Len : Integer ) : Integer;
     
     Var
       NLeN,I : Integer;
       P : PByte;
    -  S : String;
    +  S : UnicodeString;
       B : Byte;
       Code : Integer;
     
     begin
    +  //writeln('TXMLRegistry.HexToBuf A: Str=',Str,', Len=',Len);
       Result:=0;
       P:=@Buf;
    +  //writeln('TXMLRegistry.HexToBuf B: (p=nil)=',p=nil);
       NLen:= Length(Str) div 2;
    +  //writeln('TXMLRegistry.HexToBuf C: NLen=',NLen,', SizeOf(TDateTime)=',SizeOf(TDateTime));
       If (NLen>Len) then
         begin
         Len:=NLen;
         Exit(-1);
         end;
    -  For I:=0 to Len-1 do
    +  For I:=0 to NLen-1 do
         begin
    +    //write('TXMLRegistry.HexToBuf: i=',i);
         S:='$'+Copy(Str,(I*2)+1,2);
    +    //write(', S=',S);
         Val(S,B,Code);
    +    //writeln(', Code=',Code);
         If Code<>0 then
    -      begin
    -      Inc(Result);
    -      B:=0;
    +      begin    //This means invalid data in the registry, why continue and increment result? Why not Exit(-1)?
    +      //Inc(Result);   //the whole function only worked because this was called as often as when Code=0, so by change
    +      //B:=0;          //it causes AV's
    +      Exit(-1);
           end;
    +    Inc(Result);
         P[I]:=B;
         end;
    +  //writeln('TXMLRegistry.HexToBuf End: Result=',Result);
     end;
     
    -Function TXMLRegistry.DeleteValue(S : String) : Boolean;
    +Function TXMLRegistry.DeleteValue(S : UnicodeString) : Boolean;
     
     Var
       N : TDomElement;
    @@ -628,31 +648,31 @@
         end;
     end;
     
    -Function TXMLRegistry.GetValueSize(Name : String) : Integer;
    +Function TXMLRegistry.GetValueSize(Name : UnicodeString) : Integer;
     
     Var
       Info : TDataInfo;
     
     begin
    -  If GetValueInfo(Name,Info) then
    +  If GetValueInfo(Name,Info,True) then
         Result:=Info.DataSize
       else
         Result:=-1;
     end;
     
    -Function TXMLRegistry.GetValueType(Name : String) : TDataType;
    +Function TXMLRegistry.GetValueType(Name : UnicodeString) : TDataType;
     
     Var
       Info : TDataInfo;
     
     begin
    -  If GetValueInfo(Name,Info) then
    +  If GetValueInfo(Name,Info,True) then
         Result:=Info.DataType
       else
         Result:=dtUnknown;
     end;
     
    -function TXmlRegistry.GetValueInfo(Name: String; out Info: TDataInfo; AsUnicode: Boolean): Boolean;
    +function TXmlRegistry.GetValueInfo(Name: UnicodeString; out Info: TDataInfo; AsUnicode: Boolean): Boolean;
     
     Var
       N  : TDomElement;
    @@ -671,7 +691,7 @@
             L:=Length(DN.NodeValue)*SizeOf(UnicodeChar)
           else
             begin
    -        S := UTF8Encode(DN.NodeValue);
    +        S := DN.NodeValue;
             L:=Length(S);
             end
           end
    @@ -679,7 +699,7 @@
           L:=0;
         With Info do
           begin
    -      DataType:=TDataType(StrToIntDef(N[SType],0));
    +      DataType:=TDataType(StrToIntDef(String(N[SType]),0));
           Case DataType of
             dtUnknown : DataSize:=0;
             dtDword   : Datasize:=SizeOf(Cardinal);
    @@ -724,10 +744,10 @@
                   ValueLen:=L;
                 DataNode:=TDomElement(Node).FirstChild;
                 If (DataNode<>Nil) and (DataNode is TDomText) then
    -              Case TDataType(StrToIntDef(TDomElement(Node)[SType],0)) of
    +              Case TDataType(StrToIntDef(String(TDomElement(Node)[SType]),0)) of
                     dtUnknown : L:=0;
                     dtDWord   : L:=4;
    -                DtString  : L:=Length(UTF8Encode(DataNode.NodeValue));
    +                DtString  : L:=Length(String(DataNode.NodeValue));
                     dtBinary  : L:=Length(DataNode.NodeValue) div 2;
                   end
                 else
    @@ -761,6 +781,28 @@
         end;
     end;
     
    +function TXmlRegistry.EnumSubKeys: TUnicodeStringArray;
    +
    +Var
    +  Node : TDOMNode;
    +
    +begin
    +  Result:=nil;
    +  If FCurrentElement<>Nil then
    +    begin
    +    Node:=FCurrentElement.FirstChild;
    +    While Assigned(Node) do
    +      begin
    +      If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SKey) then
    +        begin
    +        SetLength(Result, Length(Result)+1);
    +        Result[High(Result)]:=TDomElement(Node)[SName];
    +        end;
    +      Node:=Node.NextSibling;
    +      end;
    +    end;
    +end;
    +
     Function TXMLRegistry.EnumValues(List : TStrings) : Integer;
     
     Var
    @@ -775,7 +817,8 @@
         While Assigned(Node) do
           begin
           If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SValue) then
    -        List.Add(TDomElement(Node)[SName]);
    +        If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SValue) then
    +          List.Add(TDomElement(Node)[SName]);
           Node:=Node.NextSibling;
           end;
         Result:=List.Count;
    @@ -782,13 +825,36 @@
         end;
     end;
     
    -Function TXMLRegistry.KeyExists(KeyPath : String) : Boolean;
    +Function TXMLRegistry.EnumValues: TUnicodeStringArray;
     
    +Var
    +  Node : TDOMNode;
    +
     begin
    +  Result:=nil;
    +  If FCurrentElement<>Nil then
    +    begin
    +    Node:=FCurrentElement.FirstChild;
    +    While Assigned(Node) do
    +      begin
    +      If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SValue) then
    +        begin
    +        SetLength(Result, Length(Result)+1);
    +        Result[High(Result)]:=TDomElement(Node)[SName];
    +        end;
    +      Node:=Node.NextSibling;
    +      end;
    +    end;
    +end;
    +
    +
    +Function TXMLRegistry.KeyExists(KeyPath : UnicodeString) : Boolean;
    +
    +begin
       Result:=FindKey(KeyPath)<>Nil;
     end;
     
    -Function TXMLRegistry.RenameValue(Const OldName,NewName : String) : Boolean;
    +Function TXMLRegistry.RenameValue(Const OldName,NewName : UnicodeString) : Boolean;
     
     Var
       N : TDomElement;
    @@ -804,10 +870,10 @@
         end;
     end;
     
    -Function TXMLRegistry.FindKey (S : String) : TDomElement;
    +Function TXMLRegistry.FindKey (S : UnicodeString) : TDomElement;
     
     Var
    -  SubKey : String;
    +  SubKey : UnicodeString;
       P : Integer;
       Node : TDomElement;
     
    @@ -840,7 +906,7 @@
       Until (Result=Nil) or (Length(S)=0);
     end;
     
    -Function  TXmlRegistry.ValueExists(ValueName : String) : Boolean;
    +Function  TXmlRegistry.ValueExists(ValueName : UnicodeString) : Boolean;
     
     begin
       Result:=FindValueKey(ValueName)<>Nil;
    Index: packages/fcl-registry/src/xregreg.inc
    ===================================================================
    --- packages/fcl-registry/src/xregreg.inc	(revision 41667)
    +++ packages/fcl-registry/src/xregreg.inc	(working copy)
    @@ -116,7 +116,11 @@
     procedure TRegistry.SysRegCreate;
     var s : string;
     begin
    +  FStringSizeIncludesNull:=False;
       s:=includetrailingpathdelimiter(GetAppConfigDir(GlobalXMLFile));
    +  {$ifdef XMLRegfile_in_CurDir}
    +  s:='.' + PathDelim;
    +  {$endif}
       ForceDirectories(s);
       FSysData:=TXMLRegistryInstance.GetXMLRegistry(s+XFileName);
       TXmlRegistry(FSysData).AutoFlush:=False;
    @@ -130,24 +134,24 @@
       TXMLRegistryInstance.FreeXMLRegistry(TXMLRegistry(FSysData));
     end;
     
    -function TRegistry.SysCreateKey(const Key: String): Boolean;
    +function TRegistry.SysCreateKey(Key: UnicodeString): Boolean;
     
     begin
       Result:=TXmlRegistry(FSysData).CreateKey(Key);
     end;
     
    -function TRegistry.DeleteKey(const Key: string): Boolean;
    +function TRegistry.DeleteKey(const Key: UnicodeString): Boolean;
     
     begin
       Result:=TXMLRegistry(FSysData).DeleteKey(Key);
     end;
     
    -function TRegistry.DeleteValue(const Name: string): Boolean;
    +function TRegistry.DeleteValue(const Name: UnicodeString): Boolean;
     begin
       Result:=TXmlRegistry(FSysData).DeleteValue(Name);
     end;
     
    -function TRegistry.SysGetData(const Name: String; Buffer: Pointer;
    +function TRegistry.SysGetData(const Name: UnicodeString; Buffer: Pointer;
               BufSize: Integer; Out RegData: TRegDataType): Integer;
     
     Var
    @@ -160,7 +164,7 @@
         Result:=-1;
     end;
     
    -function TRegistry.GetDataInfo(const ValueName: string; out Value: TRegDataInfo): Boolean;
    +function TRegistry.GetDataInfo(const ValueName: UnicodeString; out Value: TRegDataInfo): Boolean;
     
     Var
       Info : TDataInfo;
    @@ -181,7 +185,7 @@
           end;
     end;
     
    -function TRegistry.GetKey(const Key: string): HKEY;
    +function TRegistry.GetKey(Key: UnicodeString): HKEY;
     begin
       Result := 0;
     end;
    @@ -205,17 +209,17 @@
           end;
     end;
     
    -function TRegistry.KeyExists(const Key: string): Boolean;
    +function TRegistry.KeyExists(const Key: UnicodeString): Boolean;
     begin
       Result:=TXmlRegistry(FSysData).KeyExists(Key);
     end;
     
    -function TRegistry.LoadKey(const Key, FileName: string): Boolean;
    +function TRegistry.LoadKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.OpenKey(const Key: string; CanCreate: Boolean): Boolean;
    +function TRegistry.OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
     
     begin
       Result:=TXmlRegistry(FSysData).SetKey(Key,CanCreate);
    @@ -222,59 +226,59 @@
       FCurrentKey:=1;
     end;
     
    -function TRegistry.OpenKeyReadOnly(const Key: string): Boolean;
    +function TRegistry.OpenKeyReadOnly(const Key: UnicodeString): Boolean;
     
     begin
       Result:=TXmlRegistry(FSysData).SetKey(Key,False);
     end;
     
    -function TRegistry.RegistryConnect(const UNCName: string): Boolean;
    +function TRegistry.RegistryConnect(const UNCName: UnicodeString): Boolean;
     begin
       Result := True;
     end;
     
    -function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
    +function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.RestoreKey(const Key, FileName: string): Boolean;
    +function TRegistry.RestoreKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.SaveKey(const Key, FileName: string): Boolean;
    +function TRegistry.SaveKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.UnLoadKey(const Key: string): Boolean;
    +function TRegistry.UnLoadKey(const Key: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.ValueExists(const Name: string): Boolean;
    +function TRegistry.ValueExists(const Name: UnicodeString): Boolean;
     begin
       Result := TXmlRegistry(FSysData).ValueExists(Name);
     end;
     
    -procedure TRegistry.ChangeKey(Value: HKey; const Path: string);
    +procedure TRegistry.ChangeKey(Value: HKey; const Path: UnicodeString);
     begin
     
     end;
     
    -procedure TRegistry.GetKeyNames(Strings: TStrings);
    +function TRegistry.GetKeyNames: TUnicodeStringArray;
     begin
    -  TXmlRegistry(FSysData).EnumSubKeys(Strings);
    +  Result:=TXmlRegistry(FSysData).EnumSubKeys;
     end;
     
    -procedure TRegistry.GetValueNames(Strings: TStrings);
    +function TRegistry.GetValueNames: TUnicodeStringArray;
     begin
    -  TXmlRegistry(FSysData).EnumValues(Strings);
    +  Result := TXmlRegistry(FSysData).EnumValues;
     end;
     
     
    -function TRegistry.SysPutData(const Name: string; Buffer: Pointer;
    +function TRegistry.SysPutData(const Name: UnicodeString; Buffer: Pointer;
       BufSize: Integer; RegData: TRegDataType): Boolean;
     
     Var
    @@ -281,15 +285,18 @@
       DataType : TDataType;
     
     begin
    +  //writeln('TRegistry.SysPutData: Name=',Name,', RegData=',RegData,', BufSize=',BufSize);
       DataType:=RegDataTypeToXmlDataType(RegData);
    +
       Result:=TXMLRegistry(FSysData).SetValueDataUnicode(Name,DataType,Buffer^,BufSize);
     end;
     
    -procedure TRegistry.RenameValue(const OldName, NewName: string);
    +procedure TRegistry.RenameValue(const OldName, NewName: UnicodeString);
     begin
       TXMLRegistry(FSysData).RenameValue(OldName,NewName);
     end;
     
    +
     procedure TRegistry.SetCurrentKey(Value: HKEY);
     begin
       fCurrentKey := Value;
    @@ -298,7 +305,7 @@
     procedure TRegistry.SetRootKey(Value: HKEY);
     
     Var
    -  S: String;
    +  S: UnicodeString;
     
     begin
       If (Value=HKEY_CLASSES_ROOT) then
    @@ -347,3 +354,5 @@
         TXMLRegistry(FSysData).SetRootKey(TXMLRegistry(FSysData).RootKey);
       end;
     end;
    +
    +
    
  • registry.unicode.part6.diff (68,376 bytes)
    Index: packages/fcl-registry/src/regdef.inc
    ===================================================================
    --- packages/fcl-registry/src/regdef.inc	(revision 41667)
    +++ packages/fcl-registry/src/regdef.inc	(working copy)
    @@ -2,7 +2,7 @@
       HKEY = THandle;
       PHKEY = ^HKEY;
       
    -{$ifdef windows}
    +{$if defined(windows) and not defined(XMLREG)}
     
     { Direct mapping to constants in Windows unit }
     
    Index: packages/fcl-registry/src/registry.pp
    ===================================================================
    --- packages/fcl-registry/src/registry.pp	(revision 41667)
    +++ packages/fcl-registry/src/registry.pp	(working copy)
    @@ -39,6 +39,8 @@
         DataSize: Integer;
       end;
     
    +  TUnicodeStringArray = Array of UnicodeString;
    +
     { ---------------------------------------------------------------------
         TRegistry
       ---------------------------------------------------------------------}
    @@ -54,22 +56,31 @@
         fCurrentKey: HKEY;
         fRootKey: HKEY;
         fLazyWrite: Boolean;
    -    fCurrentPath: string;
    +    fCurrentPath: UnicodeString;
         function GetLastErrorMsg: string;
    +    function RegMultiSzDataToUnicodeStringArray(U: UnicodeString): TUnicodeStringArray;
    +    function ListToArray(List: TStrings; IsUtf8: Boolean): TUnicodeStringArray;
    +    procedure ArrayToList(const Arr: TUnicodeStringArray; List: TStrings; ForceUtf8: Boolean);
         procedure SetRootKey(Value: HKEY);
         Procedure SysRegCreate;
         Procedure SysRegFree;
    -    Function  SysGetData(const Name: String; Buffer: Pointer; BufSize: Integer; Out RegData: TRegDataType): Integer;
    -    Function  SysPutData(const Name: string; Buffer: Pointer; BufSize: Integer; RegData: TRegDataType) : Boolean;
    -    Function  SysCreateKey(const Key: String): Boolean;
    +    Function  SysGetData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; Out RegData: TRegDataType): Integer;
    +    Function  SysPutData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; RegData: TRegDataType) : Boolean;
    +    Function  SysCreateKey(Key: UnicodeString): Boolean;
       protected
         function GetBaseKey(Relative: Boolean): HKey;
    -    function GetData(const Name: string; Buffer: Pointer;
    +    function GetData(const Name: UnicodeString; Buffer: Pointer;
                       BufSize: Integer; Out RegData: TRegDataType): Integer;
    -    function GetKey(const Key: string): HKEY;
    -    procedure ChangeKey(Value: HKey; const Path: string);
    -    procedure PutData(const Name: string; Buffer: Pointer;
    +    function GetData(const Name: String; Buffer: Pointer;
    +                  BufSize: Integer; Out RegData: TRegDataType): Integer;
    +    function GetKey(Key: UnicodeString): HKEY;
    +    function GetKey(Key: String): HKEY;
    +    procedure ChangeKey(Value: HKey; const Path: UnicodeString);
    +    procedure ChangeKey(Value: HKey; const Path: String);
    +    procedure PutData(const Name: UnicodeString; Buffer: Pointer;
                       BufSize: Integer; RegData: TRegDataType);
    +    procedure PutData(const Name: String; Buffer: Pointer;
    +                  BufSize: Integer; RegData: TRegDataType);
         procedure SetCurrentKey(Value: HKEY);
       public
         constructor Create; overload;
    @@ -76,58 +87,105 @@
         constructor Create(aaccess:longword); overload;
         destructor Destroy; override;
     
    -    function CreateKey(const Key: string): Boolean;
    -    function DeleteKey(const Key: string): Boolean;
    -    function DeleteValue(const Name: string): Boolean;
    -    function GetDataInfo(const ValueName: string; Out Value: TRegDataInfo): Boolean;
    -    function GetDataSize(const ValueName: string): Integer;
    -    function GetDataType(const ValueName: string): TRegDataType;
    +    function CreateKey(const Key: UnicodeString): Boolean;
    +    function CreateKey(const Key: String): Boolean;
    +    function DeleteKey(const Key: UnicodeString): Boolean;
    +    function DeleteKey(const Key: String): Boolean;
    +    function DeleteValue(const Name: UnicodeString): Boolean;
    +    function DeleteValue(const Name: String): Boolean;
    +    function GetDataInfo(const ValueName: UnicodeString; Out Value: TRegDataInfo): Boolean;
    +    function GetDataInfo(const ValueName: String; Out Value: TRegDataInfo): Boolean;
    +    function GetDataSize(const ValueName: UnicodeString): Integer;
    +    function GetDataSize(const ValueName: String): Integer;
    +    function GetDataType(const ValueName: UnicodeString): TRegDataType;
    +    function GetDataType(const ValueName: String): TRegDataType;
         function GetKeyInfo(Out Value: TRegKeyInfo): Boolean;
         function HasSubKeys: Boolean;
    -    function KeyExists(const Key: string): Boolean;
    -    function LoadKey(const Key, FileName: string): Boolean;
    -    function OpenKey(const Key: string; CanCreate: Boolean): Boolean;
    -    function OpenKeyReadOnly(const Key: string): Boolean;
    -    function ReadCurrency(const Name: string): Currency;
    -    function ReadBinaryData(const Name: string; var Buffer; BufSize: Integer): Integer;
    -    function ReadBool(const Name: string): Boolean;
    -    function ReadDate(const Name: string): TDateTime;
    -    function ReadDateTime(const Name: string): TDateTime;
    -    function ReadFloat(const Name: string): Double;
    -    function ReadInteger(const Name: string): Integer;
    -    function ReadInt64(const Name: string): Int64;
    -    function ReadString(const Name: string): string;
    -    procedure ReadStringList(const Name: string; AList: TStrings);
    -    function ReadTime(const Name: string): TDateTime;
    -    function RegistryConnect(const UNCName: string): Boolean;
    -    function ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
    -    function RestoreKey(const Key, FileName: string): Boolean;
    -    function SaveKey(const Key, FileName: string): Boolean;
    -    function UnLoadKey(const Key: string): Boolean;
    -    function ValueExists(const Name: string): Boolean;
    +    function KeyExists(const Key: UnicodeString): Boolean;
    +    function KeyExists(const Key: String): Boolean;
    +    function LoadKey(const Key, FileName: UnicodeString): Boolean;
    +    function LoadKey(const Key, FileName: String): Boolean;
    +    function OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
    +    function OpenKey(const Key: String; CanCreate: Boolean): Boolean;
    +    function OpenKeyReadOnly(const Key: UnicodeString): Boolean;
    +    function OpenKeyReadOnly(const Key: String): Boolean;
    +    function ReadCurrency(const Name: UnicodeString): Currency;
    +    function ReadCurrency(const Name: String): Currency;
    +    function ReadBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer): Integer;
    +    function ReadBinaryData(const Name: String; var Buffer; BufSize: Integer): Integer;
    +    function ReadBool(const Name: UnicodeString): Boolean;
    +    function ReadBool(const Name: String): Boolean;
    +    function ReadDate(const Name: UnicodeString): TDateTime;
    +    function ReadDate(const Name: String): TDateTime;
    +    function ReadDateTime(const Name: UnicodeString): TDateTime;
    +    function ReadDateTime(const Name: String): TDateTime;
    +    function ReadFloat(const Name: UnicodeString): Double;
    +    function ReadFloat(const Name: String): Double;
    +    function ReadInteger(const Name: UnicodeString): Integer;
    +    function ReadInteger(const Name: String): Integer;
    +    function ReadInt64(const Name: UnicodeString): Int64;
    +    function ReadInt64(const Name: String): Int64;
    +    function ReadString(const Name: UnicodeString): UnicodeString;
    +    function ReadString(const Name: String): string;
    +    procedure ReadStringList(const Name: UnicodeString; AList: TStrings; ForceUtf8: Boolean=False);
    +    procedure ReadStringList(const Name: String; AList: TStrings);
    +    function ReadStringArray(const Name: UnicodeString): TUnicodeStringArray;
    +    function ReadStringArray(const Name: String): TStringArray;
    +    function ReadTime(const Name: UnicodeString): TDateTime;
    +    function ReadTime(const Name: String): TDateTime;
    +    function RegistryConnect(const UNCName: UnicodeString): Boolean;
    +    function RegistryConnect(const UNCName: String): Boolean;
    +    function ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
    +    function ReplaceKey(const Key, FileName, BackUpFileName: String): Boolean;
    +    function RestoreKey(const Key, FileName: UnicodeString): Boolean;
    +    function RestoreKey(const Key, FileName: String): Boolean;
    +    function SaveKey(const Key, FileName: UnicodeString): Boolean;
    +    function SaveKey(const Key, FileName: String): Boolean;
    +    function UnLoadKey(const Key: UnicodeString): Boolean;
    +    function UnLoadKey(const Key: String): Boolean;
    +    function ValueExists(const Name: UnicodeString): Boolean;
    +    function ValueExists(const Name: String): Boolean;
     
         procedure CloseKey;
         procedure CloseKey(key:HKEY);
         procedure GetKeyNames(Strings: TStrings);
    +    function GetKeyNames: TUnicodeStringArray;
         procedure GetValueNames(Strings: TStrings);
    -    procedure MoveKey(const OldName, NewName: string; Delete: Boolean);
    -    procedure RenameValue(const OldName, NewName: string);
    -    procedure WriteCurrency(const Name: string; Value: Currency);
    -    procedure WriteBinaryData(const Name: string; var Buffer; BufSize: Integer);
    -    procedure WriteBool(const Name: string; Value: Boolean);
    -    procedure WriteDate(const Name: string; Value: TDateTime);
    -    procedure WriteDateTime(const Name: string; Value: TDateTime);
    -    procedure WriteFloat(const Name: string; Value: Double);
    -    procedure WriteInteger(const Name: string; Value: Integer);
    -    procedure WriteInt64(const Name: string; Value: Int64);
    -    procedure WriteString(const Name, Value: string);
    -    procedure WriteExpandString(const Name, Value: string);
    -    procedure WriteStringList(const Name: string; List: TStrings);
    -    procedure WriteTime(const Name: string; Value: TDateTime);
    +    //ToDo
    +    function GetValueNames: TUnicodeStringArray;
    +    procedure MoveKey(const OldName, NewName: UnicodeString; Delete: Boolean);
    +    procedure MoveKey(const OldName, NewName: String; Delete: Boolean);
    +    procedure RenameValue(const OldName, NewName: UnicodeString);
    +    procedure RenameValue(const OldName, NewName: String);
    +    procedure WriteCurrency(const Name: UnicodeString; Value: Currency);
    +    procedure WriteCurrency(const Name: String; Value: Currency);
    +    procedure WriteBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer);
    +    procedure WriteBinaryData(const Name: String; var Buffer; BufSize: Integer);
    +    procedure WriteBool(const Name: UnicodeString; Value: Boolean);
    +    procedure WriteBool(const Name: String; Value: Boolean);
    +    procedure WriteDate(const Name: UnicodeString; Value: TDateTime);
    +    procedure WriteDate(const Name: String; Value: TDateTime);
    +    procedure WriteDateTime(const Name: UnicodeString; Value: TDateTime);
    +    procedure WriteDateTime(const Name: String; Value: TDateTime);
    +    procedure WriteFloat(const Name: UnicodeString; Value: Double);
    +    procedure WriteFloat(const Name: String; Value: Double);
    +    procedure WriteInteger(const Name: UnicodeString; Value: Integer);
    +    procedure WriteInteger(const Name: String; Value: Integer);
    +    procedure WriteInt64(const Name: UnicodeString; Value: Int64);
    +    procedure WriteInt64(const Name: String; Value: Int64);
    +    procedure WriteString(const Name, Value: UnicodeString);
    +    procedure WriteString(const Name, Value: String);
    +    procedure WriteExpandString(const Name, Value: UnicodeString);
    +    procedure WriteExpandString(const Name, Value: String);
    +    procedure WriteStringList(const Name: UnicodeString; List: TStrings; IsUtf8: Boolean=False);
    +    procedure WriteStringArray(const Name: UnicodeString; const Arr: TUnicodeStringArray);
    +    procedure WriteStringArray(const Name: String; const Arr: TStringArray);
    +    procedure WriteTime(const Name: UnicodeString; Value: TDateTime);
    +    procedure WriteTime(const Name: String; Value: TDateTime);
     
         property Access: LongWord read fAccess write fAccess;
         property CurrentKey: HKEY read fCurrentKey;
    -    property CurrentPath: string read fCurrentPath;
    +    property CurrentPath: UnicodeString read fCurrentPath;
         property LazyWrite: Boolean read fLazyWrite write fLazyWrite;
         property RootKey: HKEY read fRootKey write SetRootKey;
         Property StringSizeIncludesNull : Boolean read FStringSizeIncludesNull;
    @@ -235,6 +293,16 @@
         Generic, implementation-independent code.
       ---------------------------------------------------------------------}
     
    +{$ifdef DebugRegistry}
    +function DbgS(const S: UnicodeString): String;
    +var
    +  C: WideChar;
    +begin
    +  Result := '';
    +  for C in S do Result := Result + IntToHex(Word(C),4) + #32;
    +  Result := TrimRight(Result);
    +end;
    +{$endif}
     
     constructor TRegistry.Create;
     
    @@ -261,7 +329,7 @@
       inherited Destroy;
     end;
     
    -function TRegistry.CreateKey(const Key: string): Boolean;
    +function TRegistry.CreateKey(const Key: UnicodeString): Boolean;
     
     begin
       Result:=SysCreateKey(Key);
    @@ -269,6 +337,27 @@
         Raise ERegistryException.CreateFmt(SRegCreateFailed, [Key]);
     end;
     
    +function TRegistry.CreateKey(const Key: String): Boolean;
    +begin
    +  Result:=CreateKey(UnicodeString(Key));
    +end;
    +
    +function TRegistry.DeleteKey(const Key: String): Boolean;
    +begin
    +  Result:=DeleteKey(UnicodeString(Key));
    +end;
    +
    +function TRegistry.DeleteValue(const Name: String): Boolean;
    +begin
    +  Result:=DeleteValue(UnicodeString(Name));
    +end;
    +
    +function TRegistry.GetDataInfo(const ValueName: String; out Value: TRegDataInfo
    +  ): Boolean;
    +begin
    +  Result:=GetDataInfo(UnicodeString(ValueName), Value);
    +end;
    +
     function TRegistry.GetBaseKey(Relative: Boolean): HKey;
     begin
       If Relative and (CurrentKey<>0) Then
    @@ -277,7 +366,7 @@
         Result := RootKey;
     end;
     
    -function TRegistry.GetData(const Name: string; Buffer: Pointer; BufSize: Integer; out RegData: TRegDataType): Integer;
    +function TRegistry.GetData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; out RegData: TRegDataType): Integer;
     begin
       Result:=SysGetData(Name,Buffer,BufSize,RegData);
       If (Result=-1) then
    @@ -284,7 +373,24 @@
         Raise ERegistryException.CreateFmt(SRegGetDataFailed, [Name]);
     end;
     
    -procedure TRegistry.PutData(const Name: string; Buffer: Pointer;
    +function TRegistry.GetData(const Name: String; Buffer: Pointer;
    +  BufSize: Integer; out RegData: TRegDataType): Integer;
    +begin
    +  Result:=GetData(UnicodeString(Name), Buffer, BufSize, RegData);
    +end;
    +
    +function TRegistry.GetKey(Key: String): HKEY;
    +begin
    +  Result:=GetKey(UnicodeString(Key));
    +end;
    +
    +procedure TRegistry.ChangeKey(Value: HKey; const Path: String);
    +begin
    +  ChangeKey(Value, UnicodeString(Path));
    +end;
    +
    +
    +procedure TRegistry.PutData(const Name: UnicodeString; Buffer: Pointer;
       BufSize: Integer; RegData: TRegDataType);
     
     begin
    @@ -292,9 +398,15 @@
         Raise ERegistryException.CreateFmt(SRegSetDataFailed, [Name]);
     end;
     
    +procedure TRegistry.PutData(const Name: String; Buffer: Pointer;
    +  BufSize: Integer; RegData: TRegDataType);
    +begin
    +  PutData(UnicodeString(Name), Buffer, BufSize, RegData);
    +end;
     
    -function TRegistry.GetDataSize(const ValueName: string): Integer;
     
    +function TRegistry.GetDataSize(const ValueName: UnicodeString): Integer;
    +
     Var
       Info: TRegDataInfo;
     
    @@ -305,8 +417,13 @@
         Result := -1;
     end;
     
    -function TRegistry.GetDataType(const ValueName: string): TRegDataType;
    +function TRegistry.GetDataSize(const ValueName: String): Integer;
    +begin
    +  Result:=GetDataSize(UnicodeString(ValueName));
    +end;
     
    +function TRegistry.GetDataType(const ValueName: UnicodeString): TRegDataType;
    +
     Var
       Info: TRegDataInfo;
     
    @@ -315,6 +432,32 @@
       Result:=Info.RegData;
     end;
     
    +function TRegistry.GetDataType(const ValueName: String): TRegDataType;
    +begin
    +  Result:=GetDataType(UnicodeString(ValueName));
    +end;
    +
    +
    +function TRegistry.KeyExists(const Key: String): Boolean;
    +begin
    +  Result:=KeyExists(UnicodeString(Key));
    +end;
    +
    +function TRegistry.LoadKey(const Key, FileName: String): Boolean;
    +begin
    +  Result:=LoadKey(UnicodeString(Key), UnicodeString(FileName));
    +end;
    +
    +function TRegistry.OpenKey(const Key: String; CanCreate: Boolean): Boolean;
    +begin
    +  Result:=OpenKey(UnicodeString(Key), CanCreate);
    +end;
    +
    +function TRegistry.OpenKeyReadOnly(const Key: String): Boolean;
    +begin
    +  Result:=OpenKeyReadOnly(UnicodeString(Key));
    +end;
    +
     function TRegistry.HasSubKeys: Boolean;
     
     Var
    @@ -326,7 +469,7 @@
         Result:=(Info.NumSubKeys>0);
     end;
     
    -function TRegistry.ReadBinaryData(const Name: string; var Buffer; BufSize: Integer): Integer;
    +function TRegistry.ReadBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer): Integer;
     
     Var
       RegDataType: TRegDataType;
    @@ -337,8 +480,14 @@
         Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
     end;
     
    -function TRegistry.ReadInteger(const Name: string): Integer;
    +function TRegistry.ReadBinaryData(const Name: String; var Buffer;
    +  BufSize: Integer): Integer;
    +begin
    +  Result:=ReadBinaryData(UnicodeString(Name), Buffer, BufSize);
    +end;
     
    +function TRegistry.ReadInteger(const Name: UnicodeString): Integer;
    +
     Var
       RegDataType: TRegDataType;
     
    @@ -348,8 +497,13 @@
         Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
     end;
     
    -function TRegistry.ReadInt64(const Name: string): Int64;
    +function TRegistry.ReadInteger(const Name: String): Integer;
    +begin
    +  Result:=ReadInteger(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadInt64(const Name: UnicodeString): Int64;
    +
     Var
       RegDataType: TRegDataType;
     
    @@ -359,21 +513,36 @@
         Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
     end;
     
    -function TRegistry.ReadBool(const Name: string): Boolean;
    +function TRegistry.ReadInt64(const Name: String): Int64;
    +begin
    +  Result:=ReadInt64(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadBool(const Name: UnicodeString): Boolean;
    +
     begin
       Result:=ReadInteger(Name)<>0;
     end;
     
    -function TRegistry.ReadCurrency(const Name: string): Currency;
    +function TRegistry.ReadBool(const Name: String): Boolean;
    +begin
    +  Result:=ReadBool(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadCurrency(const Name: UnicodeString): Currency;
    +
     begin
       Result:=Default(Currency);
       ReadBinaryData(Name, Result, SizeOf(Currency));
     end;
     
    -function TRegistry.ReadDate(const Name: string): TDateTime;
    +function TRegistry.ReadCurrency(const Name: String): Currency;
    +begin
    +  Result:=ReadCurrency(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadDate(const Name: UnicodeString): TDateTime;
    +
     begin
       Result:=Default(TDateTime);
       ReadBinaryData(Name, Result, SizeOf(TDateTime));
    @@ -380,22 +549,37 @@
       Result:=Trunc(Result);
     end;
     
    -function TRegistry.ReadDateTime(const Name: string): TDateTime;
    +function TRegistry.ReadDate(const Name: String): TDateTime;
    +begin
    +  Result:=ReadDate(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadDateTime(const Name: UnicodeString): TDateTime;
    +
     begin
       Result:=Default(TDateTime);
       ReadBinaryData(Name, Result, SizeOf(TDateTime));
     end;
     
    -function TRegistry.ReadFloat(const Name: string): Double;
    +function TRegistry.ReadDateTime(const Name: String): TDateTime;
    +begin
    +  Result:=ReadDateTime(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadFloat(const Name: UnicodeString): Double;
    +
     begin
       Result:=Default(Double);
       ReadBinaryData(Name,Result,SizeOf(Double));
     end;
     
    -function TRegistry.ReadString(const Name: string): string;
    +function TRegistry.ReadFloat(const Name: String): Double;
    +begin
    +  Result:=ReadFloat(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadString(const Name: UnicodeString): UnicodeString;
    +
     Var
       Info : TRegDataInfo;
       ReadDataSize: Integer;
    @@ -421,47 +605,139 @@
           if StringSizeIncludesNull and
              (u[Length(u)] = WideChar(0)) then
             SetLength(u,Length(u)-1);
    -      Result:=UTF8Encode(u);
    +      Result:=u;
         end;
       end;
     end;
     
    -procedure TRegistry.ReadStringList(const Name: string; AList: TStrings);
    +function TRegistry.ReadString(const Name: String): string;
    +begin
    +  Result:=ReadString(UnicodeString(Name));
    +end;
     
    +
    +procedure TRegistry.ReadStringList(const Name: UnicodeString; AList: TStrings; ForceUtf8: Boolean=False);
    +
     Var
    +  UArr: TUnicodeStringArray;
    +
    +begin
    +  UArr := ReadStringArray(Name);
    +  ArrayToList(UArr, AList, ForceUtf8);
    +end;
    +
    +procedure TRegistry.ReadStringList(const Name: String; AList: TStrings);
    +begin
    +  ReadStringList(UnicodeString(Name), AList);
    +end;
    +
    +function TRegistry.RegMultiSzDataToUnicodeStringArray(U: UnicodeString): TUnicodeStringArray;
    +var
    +  Len, i, p: Integer;
    +  Sub: UnicodeString;
    +begin
    +  Result := nil;
    +  if (U = '') then Exit;
    +  Len := 1;
    +  for i := 1 to Length(U) do if (U[i] = #0) then Inc(Len);
    +  SetLength(Result, Len);
    +  i := 0;
    +
    +  while (U <> '') and (i < Length(Result)) do
    +  begin
    +    p := Pos(#0, U);
    +    if (p = 0) then p := Length(U) + 1;
    +    Sub := Copy(U, 1, p - 1);
    +    Result[i] := Sub;
    +    System.Delete(U, 1, p);
    +    Inc(i);
    +  end;
    +end;
    +
    +function TRegistry.ListToArray(List: TStrings; IsUtf8: Boolean): TUnicodeStringArray;
    +var
    +  i, curr, Len: Integer;
    +  u: UnicodeString;
    +begin
    +  Result := nil;
    +  Len := List.Count;
    +  SetLength(Result, Len);
    +  //REG_MULTI_SZ data cannot contain empty strings
    +  curr := 0;
    +  for i := 0 to List.Count - 1 do
    +  begin
    +    if IsUtf8 then
    +      u := Utf8Decode(List[i])
    +    else
    +      u := List[i];
    +    if (u>'') then
    +    begin
    +      Result[curr] := u;
    +      inc(curr);
    +    end
    +    else
    +      Dec(Len);
    +  end;
    +  if (Len <> List.Count) then SetLength(Result, Len);
    +end;
    +
    +procedure TRegistry.ArrayToList(const Arr: TUnicodeStringArray; List: TStrings; ForceUtf8: Boolean);
    +var
    +  i: Integer;
    +begin
    +  List.Clear;
    +  for i := Low(Arr) to High(Arr) do
    +  begin
    +    if ForceUtf8 then
    +      List.Add(Utf8Encode(Arr[i]))
    +    else
    +      List.Add(String(Arr[i]));
    +  end;
    +end;
    +
    +function TRegistry.ReadStringArray(const Name: UnicodeString): TUnicodeStringArray;
    +Var
       Info : TRegDataInfo;
       ReadDataSize: Integer;
    -  Data: string;
    +  Data: UnicodeString;
     
     begin
    -  AList.Clear;
    +  Result := nil;
       GetDataInfo(Name,Info);
    +  //writeln('TRegistry.ReadStringArray: datasize=',info.datasize);
       if info.datasize>0 then
         begin
          If Not (Info.RegData in [rdMultiString]) then
            Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
          SetLength(Data,Info.DataSize);
    -     ReadDataSize := GetData(Name,PChar(Data),Info.DataSize,Info.RegData);
    +     ReadDataSize := GetData(Name,PWideChar(Data),Info.DataSize,Info.RegData) div SizeOf(WideChar);
    +     //writeln('TRegistry.ReadStringArray: ReadDataSize=',ReadDataSize);
          if ReadDataSize > 0 then
          begin
    -       // If the data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type,
    -       // the size includes any terminating null character or characters
    -       // unless the data was stored without them! (RegQueryValueEx @ MSDN)
    -       if StringSizeIncludesNull then begin
    -         if Data[ReadDataSize] = #0 then
    -           Dec(ReadDataSize);
    -         if Data[ReadDataSize] = #0 then
    -           Dec(ReadDataSize);
    -       end;
    +       // Windows returns the data with or without trailing zero's, so just strip all trailing null characters
    +        while (Data[ReadDataSize] = #0) do Dec(ReadDataSize);
            SetLength(Data, ReadDataSize);
    -       Data := StringReplace(Data, #0, LineEnding, [rfReplaceAll]);
    -       AList.Text := Data;
    +       //writeln('Data=',dbgs(data));
    +       //Data := UnicodeStringReplace(Data, #0, AList.LineBreak, [rfReplaceAll]);
    +       //AList.Text := Data;
    +       Result := RegMultiSzDataToUnicodeStringArray(Data);
          end
        end
     end;
     
    -function TRegistry.ReadTime(const Name: string): TDateTime;
    +function TRegistry.ReadStringArray(const Name: String): TStringArray;
    +var
    +  UArr: TUnicodeStringArray;
    +  i: Integer;
    +begin
    +  Result := nil;
    +  UArr := ReadStringArray(UnicodeString(Name));
    +  SetLength(Result, Length(UArr));
    +  for i := Low(UArr) to High(UArr) do Result[i] := UArr[i];
    +end;
     
    +function TRegistry.ReadTime(const Name: UnicodeString): TDateTime;
    +
     begin
       Result:=Default(TDateTime);
       ReadBinaryData(Name, Result, SizeOf(TDateTime));
    @@ -468,85 +744,230 @@
       Result:=Frac(Result);
     end;
     
    -procedure TRegistry.WriteBinaryData(const Name: string; var Buffer; BufSize: Integer);
    +function TRegistry.ReadTime(const Name: String): TDateTime;
     begin
    +  Result:=ReadTime(UnicodeString(Name));
    +end;
    +
    +function TRegistry.RegistryConnect(const UNCName: String): Boolean;
    +begin
    +  Result:=RegistryConnect(UnicodeString(UNCName));
    +end;
    +
    +function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: String): Boolean;
    +begin
    +  Result:=ReplaceKey(UnicodeString(Key), UnicodeString(FileName), UnicodeString(BackUpFileName))
    +end;
    +
    +function TRegistry.RestoreKey(const Key, FileName: String): Boolean;
    +begin
    +  Result:=RestoreKey(UnicodeString(Key), UnicodeString(FileName));
    +end;
    +
    +function TRegistry.SaveKey(const Key, FileName: String): Boolean;
    +begin
    +  Result:=SaveKey(UnicodeString(Key), UnicodeString(FileName));
    +end;
    +
    +function TRegistry.UnLoadKey(const Key: String): Boolean;
    +begin
    +  Result:=UnloadKey(UnicodeString(Key));
    +end;
    +
    +function TRegistry.ValueExists(const Name: String): Boolean;
    +begin
    +  Result:=ValueExists(UnicodeString(Name));
    +end;
    +
    +procedure TRegistry.WriteBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer);
    +begin
       PutData(Name, @Buffer, BufSize, rdBinary);
     end;
     
    -procedure TRegistry.WriteBool(const Name: string; Value: Boolean);
    +procedure TRegistry.WriteBinaryData(const Name: String; var Buffer;
    +  BufSize: Integer);
    +begin
    +  WriteBinaryData(UnicodeString(Name), Buffer, BufSize);
    +end;
     
    +procedure TRegistry.WriteBool(const Name: UnicodeString; Value: Boolean);
    +
     begin
       WriteInteger(Name,Ord(Value));
     end;
     
    -procedure TRegistry.WriteCurrency(const Name: string; Value: Currency);
    +procedure TRegistry.WriteBool(const Name: String; Value: Boolean);
     begin
    +  WriteBool(UnicodeString(Name), Value);
    +end;
    +
    +procedure TRegistry.WriteCurrency(const Name: UnicodeString; Value: Currency);
    +begin
       WriteBinaryData(Name, Value, SizeOf(Currency));
     end;
     
    -procedure TRegistry.WriteDate(const Name: string; Value: TDateTime);
    +procedure TRegistry.WriteCurrency(const Name: String; Value: Currency);
     begin
    +  WriteCurrency(UnicodeString(Name), Value);
    +end;
    +
    +procedure TRegistry.WriteDate(const Name: UnicodeString; Value: TDateTime);
    +begin
       WriteBinarydata(Name, Value, SizeOf(TDateTime));
     end;
     
    -procedure TRegistry.WriteTime(const Name: string; Value: TDateTime);
    +procedure TRegistry.WriteDate(const Name: String; Value: TDateTime);
     begin
    +  WriteDate(UnicodeString(Name), Value);
    +end;
    +
    +procedure TRegistry.WriteTime(const Name: UnicodeString; Value: TDateTime);
    +begin
       WriteBinaryData(Name, Value, SizeOf(TDateTime));
     end;
     
    -procedure TRegistry.WriteDateTime(const Name: string; Value: TDateTime);
    +procedure TRegistry.WriteTime(const Name: String; Value: TDateTime);
     begin
    +  WriteTime(UnicodeString(Name), Value);
    +end;
    +
    +procedure TRegistry.WriteDateTime(const Name: UnicodeString; Value: TDateTime);
    +begin
       WriteBinaryData(Name, Value, SizeOf(TDateTime));
     end;
     
    -procedure TRegistry.WriteExpandString(const Name, Value: string);
    -var
    -  u: UnicodeString;
    +procedure TRegistry.WriteDateTime(const Name: String; Value: TDateTime);
    +begin
    +  WriteDateTime(UnicodeString(Name), Value);
    +end;
     
    +procedure TRegistry.WriteExpandString(const Name, Value: UnicodeString);
     begin
    -  u:=Value;
    -  PutData(Name, PWideChar(u), ByteLength(u), rdExpandString);
    +  PutData(Name, PWideChar(Value), ByteLength(Value), rdExpandString);
     end;
     
    -procedure TRegistry.WriteStringList(const Name: string; List: TStrings);
    +procedure TRegistry.WriteExpandString(const Name, Value: String);
    +begin
    +  WriteExpandString(UnicodeString(Name), UnicodeString(Value));
    +end;
     
    +
    +procedure TRegistry.WriteStringList(const Name: UnicodeString; List: TStrings; IsUtf8: Boolean=False);
    +
     Var
    -  Data: string;
    +  UArr: TUnicodeStringArray;
    +begin
    +  UArr := ListToArray(List, IsUtf8);
    +  WriteStringArray(Name, UArr);
    +end;
     
    +procedure TRegistry.WriteStringArray(const Name: UnicodeString; const Arr: TUnicodeStringArray);
    +Var
    +  Data: UnicodeString;
    +  u: UnicodeString;
    +  i: Integer;
     begin
    -  Data := StringReplace(List.Text, LineEnding, #0, [rfReplaceAll]) + #0#0;
    -  PutData(Name, PChar(Data), Length(Data),rdMultiString);
    +  Data := '';
    +  //REG_MULTI_SZ data cannot contain empty strings
    +  for i := Low(Arr) to High(Arr) do
    +  begin
    +    u := Arr[i];
    +    if (u>'') then
    +    begin
    +      if (Data>'') then
    +        Data := Data + #0 + u
    +      else
    +        Data := Data + u;
    +    end;
    +  end;
    +  if StringSizeIncludesNull then
    +    Data := Data + #0#0;
    +  //writeln('Data=',Dbgs(Data));
    +  PutData(Name, PWideChar(Data), ByteLength(Data), rdMultiString);
     end;
     
    -procedure TRegistry.WriteFloat(const Name: string; Value: Double);
    +procedure TRegistry.WriteStringArray(const Name: String; const Arr: TStringArray);
    +var
    +  UArr: TUnicodeStringArray;
    +  i: Integer;
     begin
    +  UArr := nil;
    +  SetLength(UArr, Length(Arr));
    +  for i := Low(Arr) to High(Arr) do UArr[i] := Arr[i];
    +  WriteStringArray(UnicodeString(Name), UArr);
    +end;
    +
    +procedure TRegistry.WriteFloat(const Name: UnicodeString; Value: Double);
    +begin
       WriteBinaryData(Name, Value, SizeOf(Double));
     end;
     
    -procedure TRegistry.WriteInteger(const Name: string; Value: Integer);
    +procedure TRegistry.WriteFloat(const Name: String; Value: Double);
     begin
    +  WriteFloat(UnicodeString(Name), Value);
    +end;
    +
    +procedure TRegistry.WriteInteger(const Name: UnicodeString; Value: Integer);
    +begin
       PutData(Name, @Value, SizeOf(Integer), rdInteger);
     end;
     
    -procedure TRegistry.WriteInt64(const Name: string; Value: Int64);
    +procedure TRegistry.WriteInteger(const Name: String; Value: Integer);
     begin
    +  WriteInteger(UnicodeString(Name), Value);
    +end;
    +
    +procedure TRegistry.WriteInt64(const Name: UnicodeString; Value: Int64);
    +begin
       PutData(Name, @Value, SizeOf(Int64), rdInt64);
     end;
     
    -procedure TRegistry.WriteString(const Name, Value: string);
    +procedure TRegistry.WriteInt64(const Name: String; Value: Int64);
    +begin
    +  WriteInt64(UnicodeString(Name), Value);
    +end;
    +
    +procedure TRegistry.WriteString(const Name, Value: UnicodeString);
    +begin
    +  PutData(Name, PWideChar(Value), ByteLength(Value), rdString);
    +end;
    +
    +procedure TRegistry.WriteString(const Name, Value: String);
    +begin
    +  WriteString(UnicodeString(Name), UnicodeString(Value));
    +end;
    +
    +procedure TRegistry.GetKeyNames(Strings: TStrings);
     var
    -  u: UnicodeString;
    +  UArr: TUnicodeStringArray;
    +begin
    +  UArr := GetKeyNames;
    +  ArrayToList(UArr, Strings, True);
    +end;
     
    +procedure TRegistry.GetValueNames(Strings: TStrings);
    +var
    +  UArr: TUnicodeStringArray;
     begin
    -  u:=Value;
    -  PutData(Name, PWideChar(u), ByteLength(u), rdString);
    +  UArr := GetValueNames;
    +  ArrayToList(UArr, Strings, True);
     end;
     
    -procedure TRegistry.MoveKey(const OldName, NewName: string; Delete: Boolean);
    +procedure TRegistry.MoveKey(const OldName, NewName: UnicodeString; Delete: Boolean);
     begin
     
     end;
     
    +procedure TRegistry.MoveKey(const OldName, NewName: String; Delete: Boolean);
    +begin
    +  MoveKey(UnicodeString(OldName), UnicodeString(NewName), Delete);
    +end;
    +
    +procedure TRegistry.RenameValue(const OldName, NewName: String);
    +begin
    +  RenameValue(UnicodeString(OldName), UnicodeString(NewName));
    +end;
    +
     { ---------------------------------------------------------------------
         Include TRegIniFile implementation
       ---------------------------------------------------------------------}
    @@ -583,7 +1004,7 @@
       Value: TStream): Integer;
     begin
       result:=-1; // unimplemented
    - // 
    + //
     end;
     
     function TRegistryIniFile.ReadDate(const Section, Name: string;
    Index: packages/fcl-registry/src/winreg.inc
    ===================================================================
    --- packages/fcl-registry/src/winreg.inc	(revision 41667)
    +++ packages/fcl-registry/src/winreg.inc	(working copy)
    @@ -28,7 +28,7 @@
       Dispose(PWinRegData(FSysData));
     end;
     
    -Function PrepKey(Const S : String) : String;
    +Function PrepKey(Const S : UnicodeString) : UnicodeString;
     
     begin
       Result := S;
    @@ -36,7 +36,7 @@
         System.Delete(Result, 1, 1);
     end;
     
    -Function RelativeKey(Const S : String) : Boolean;
    +Function RelativeKey(Const S : UnicodeString) : Boolean;
     
     begin
       Result:=(S='') or (S[1]<>'\')
    @@ -43,9 +43,8 @@
     end;
     
     
    -function TRegistry.sysCreateKey(const Key: String): Boolean;
    +function TRegistry.sysCreateKey(Key: UnicodeString): Boolean;
     Var
    -  u: UnicodeString;
       Disposition: Dword;
       Handle: HKEY;
       SecurityAttributes: Pointer; //LPSECURITY_ATTRIBUTES;
    @@ -52,9 +51,9 @@
     
     begin
       SecurityAttributes := Nil;
    -  u:=PrepKey(Key);
    +  Key:=PrepKey(Key);
       FLastError:=RegCreateKeyExW(GetBaseKey(RelativeKey(Key)),
    -                              PWideChar(u),
    +                              PWideChar(Key),
                                   0,
                                   '',
                                   REG_OPTION_NON_VOLATILE,
    @@ -66,7 +65,7 @@
       RegCloseKey(Handle);
     end;
     
    -function TRegistry.DeleteKey(const Key: String): Boolean;
    +function TRegistry.DeleteKey(const Key: UnicodeString): Boolean;
     
     Var
       u: UnicodeString;
    @@ -76,21 +75,21 @@
       Result:=FLastError=ERROR_SUCCESS;
     end;
     
    -function TRegistry.DeleteValue(const Name: String): Boolean;
    +
    +function TRegistry.DeleteValue(const Name: UnicodeString): Boolean;
     begin
    -  FLastError:= RegDeleteValueW(fCurrentKey, PWideChar(UnicodeString(Name)));
    +  FLastError:= RegDeleteValueW(fCurrentKey, PWideChar(Name));
       Result:=FLastError=ERROR_SUCCESS;
     end;
     
    -function TRegistry.SysGetData(const Name: String; Buffer: Pointer;
    +
    +function TRegistry.SysGetData(const Name: UnicodeString; Buffer: Pointer;
               BufSize: Integer; Out RegData: TRegDataType): Integer;
     Var
    -  u: UnicodeString;
       RD : DWord;
     
     begin
    -  u := Name;
    -  FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(u),Nil,
    +  FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(Name),Nil,
                           @RD,Buffer,lpdword(@BufSize));
       if (FLastError<>ERROR_SUCCESS) Then
         Result:=-1
    @@ -103,17 +102,15 @@
         end;
     end;
     
    -function TRegistry.GetDataInfo(const ValueName: String; out Value: TRegDataInfo): Boolean;
    +function TRegistry.GetDataInfo(const ValueName: UnicodeString; out Value: TRegDataInfo): Boolean;
     
     Var
    -  u: UnicodeString;
       RD : DWord;
     
     begin
    -  u:=ValueName;
       With Value do
         begin
    -    FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(u),Nil,lpdword(@RegData),Nil,lpdword(@DataSize));
    +    FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(ValueName),Nil,lpdword(@RegData),Nil,lpdword(@DataSize));
         Result:=FLastError=ERROR_SUCCESS;
         if Result then
           begin
    @@ -131,24 +128,18 @@
     end;
     
     
    -function TRegistry.GetKey(const Key: String): HKEY;
    +function TRegistry.GetKey(Key: UnicodeString): HKEY;
     var
    -  S : string;
    -{$ifndef WinCE}
    -  u : UnicodeString;
    -{$endif}
       Rel : Boolean;
     begin
       Result:=0;
    -  S:=Key;
    -  Rel:=RelativeKey(S);
    +  Rel:=RelativeKey(Key);
       if not(Rel) then
    -    Delete(S,1,1);
    +    Delete(Key,1,1);
     {$ifdef WinCE}
    -  FLastError:=RegOpenKeyEx(GetBaseKey(Rel),PWideChar(WideString(S)),0,FAccess,Result);
    +  FLastError:=RegOpenKeyEx(GetBaseKey(Rel),PWideChar(Key),0,FAccess,Result);
     {$else WinCE}
    -  u:=UnicodeString(S);
    -  FLastError:=RegOpenKeyExW(GetBaseKey(Rel),PWideChar(u),0,FAccess,Result);
    +  FLastError:=RegOpenKeyExW(GetBaseKey(Rel),PWideChar(Key),0,FAccess,Result);
     {$endif WinCE}
     end;
     
    @@ -158,7 +149,7 @@
       winFileTime: Windows.FILETIME;
       sysTime: TSystemTime;
     begin
    -  FillChar(Value, SizeOf(Value), 0);
    +  Value := Default(TRegKeyInfo);
       With Value do
         begin
         FLastError:=RegQueryInfoKeyA(CurrentKey,nil,nil,nil,lpdword(@NumSubKeys),
    @@ -174,7 +165,7 @@
     end;
     
     
    -function TRegistry.KeyExists(const Key: string): Boolean;
    +function TRegistry.KeyExists(const Key: UnicodeString): Boolean;
     var
       KeyHandle : HKEY;
       OldAccess : LONG;
    @@ -196,20 +187,20 @@
     end;
     
     
    -function TRegistry.LoadKey(const Key, FileName: string): Boolean;
    +function TRegistry.LoadKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
     
    -function TRegistry.OpenKey(const Key: string; CanCreate: Boolean): Boolean;
     
    +function TRegistry.OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
    +
     Var
    -  u: UnicodeString;
    +  u, S: UnicodeString;
       Handle: HKEY;
       Disposition: Integer;
       SecurityAttributes: Pointer; //LPSECURITY_ATTRIBUTES;
    -  S: string;
     begin
       SecurityAttributes := Nil;
       u:=PrepKey(Key);
    @@ -232,13 +223,14 @@
         if RelativeKey(Key) then
           S:=CurrentPath + Key
         else
    -      S:=UTF8Encode(u);
    +      S:=u;
         ChangeKey(Handle, S);
       end;
     end;
     
    -function TRegistry.OpenKeyReadOnly(const Key: string): Boolean;
     
    +function TRegistry.OpenKeyReadOnly(const Key: UnicodeString): Boolean;
    +
     Var
       OldAccess: LongWord;
     begin
    @@ -251,7 +243,8 @@
       end;
     end;
     
    -function TRegistry.RegistryConnect(const UNCName: string): Boolean;
    +
    +function TRegistry.RegistryConnect(const UNCName: UnicodeString): Boolean;
     {$ifndef WinCE}
     var
       newroot: HKEY;
    @@ -260,7 +253,7 @@
     {$ifdef WinCE}
       Result:=False;
     {$else}
    -  FLastError:=RegConnectRegistryW(PWideChar(UnicodeString(UNCName)),RootKey,newroot);
    +  FLastError:=RegConnectRegistryW(PWideChar(UNCName),RootKey,newroot);
       Result:=FLastError=ERROR_SUCCESS;
       if Result then begin
         RootKey:=newroot;
    @@ -269,28 +262,33 @@
     {$endif}
     end;
     
    -function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
    +
    +function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.RestoreKey(const Key, FileName: string): Boolean;
    +
    +function TRegistry.RestoreKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.SaveKey(const Key, FileName: string): Boolean;
    +
    +function TRegistry.SaveKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.UnLoadKey(const Key: string): Boolean;
    +
    +function TRegistry.UnLoadKey(const Key: UnicodeString): Boolean;
     begin
       Result := false;
     end;
     
    -function TRegistry.ValueExists(const Name: string): Boolean;
     
    +function TRegistry.ValueExists(const Name: UnicodeString): Boolean;
    +
     var
       Info : TRegDataInfo;
     
    @@ -298,6 +296,7 @@
       Result:=GetDataInfo(Name,Info);
     end;
     
    +
     procedure TRegistry.CloseKey;
     begin
       If (CurrentKey<>0) then
    @@ -316,7 +315,7 @@
       RegCloseKey(key);
     end;
     
    -procedure TRegistry.ChangeKey(Value: HKey; const Path: String);
    +procedure TRegistry.ChangeKey(Value: HKey; const Path: UnicodeString);
     begin
       CloseKey;
       FCurrentKey:=Value;
    @@ -323,8 +322,9 @@
       FCurrentPath:=Path;
     end;
     
    -procedure TRegistry.GetKeyNames(Strings: TStrings);
     
    +function TRegistry.GetKeyNames: TUnicodeStringArray;
    +
     var
       Info:    TRegKeyInfo;
       dwLen:   DWORD;
    @@ -331,15 +331,17 @@
       lpName:  LPWSTR;
       dwIndex: DWORD;
       lResult: LONGINT;
    -  s:       string;
    +  u:       UnicodeString;
     
     begin
    -  Strings.Clear;
    +  Result:=nil;
       if GetKeyInfo(Info) then
       begin
         dwLen:=Info.MaxSubKeyLen+1;
         GetMem(lpName,dwLen*SizeOf(WideChar));
         try
    +      //writeln('TRegistry.GetKeyNames: Info.NumSubKeys=',Info.NumSubKeys);
    +      SetLength(Result, Info.NumSubKeys);
           for dwIndex:=0 to Info.NumSubKeys-1 do
           begin
             dwLen:=Info.MaxSubKeyLen+1;
    @@ -347,19 +349,13 @@
             if lResult<>ERROR_SUCCESS then
               raise ERegistryException.Create(SysErrorMessage(lResult));
             if dwLen=0 then
    -          s:=''
    +          u:=''
             else
             begin           // dwLen>0
    -          SetLength(s,dwLen*3);
    -          dwLen:=UnicodeToUTF8(PChar(s),Length(s)+1,lpName,dwLen);
    -          if dwLen<=1 then
    -            s:=''
    -          else          // dwLen>1
    -            SetLength(s,dwLen-1);
    +          u:=lpName;
             end;            // if dwLen=0
    -        Strings.Add(s);
    +        Result[dwIndex]:=u;
           end;              // for dwIndex:=0 ...
    -
         finally
           FreeMem(lpName);
         end;
    @@ -366,8 +362,9 @@
       end;
     end;
     
    -procedure TRegistry.GetValueNames(Strings: TStrings);
     
    +Function TRegistry.GetValueNames: TUnicodeStringArray;
    +
     var
       Info:    TRegKeyInfo;
       dwLen:   DWORD;
    @@ -374,15 +371,16 @@
       lpName:  LPWSTR;
       dwIndex: DWORD;
       lResult: LONGINT;
    -  s:       string;
    +  u:       UnicodeString;
     
     begin
    -   Strings.Clear;
    +  Result:=nil;
       if GetKeyInfo(Info) then
       begin
         dwLen:=Info.MaxValueLen+1;
         GetMem(lpName,dwLen*SizeOf(WideChar));
         try
    +      SetLength(Result, Info.NumValues);
           for dwIndex:=0 to Info.NumValues-1 do
           begin
             dwLen:=Info.MaxValueLen+1;
    @@ -390,17 +388,12 @@
             if lResult<>ERROR_SUCCESS then
               raise ERegistryException.Create(SysErrorMessage(lResult));
             if dwLen=0 then
    -          s:=''
    +          u:=''
             else
             begin           // dwLen>0
    -          SetLength(s,dwLen*3);
    -          dwLen:=UnicodeToUTF8(PChar(s),Length(s)+1,lpName,dwLen);
    -          if dwLen<=1 then
    -            s:=''
    -          else          // dwLen>1
    -            SetLength(s,dwLen-1);
    +          u:=lpName;
             end;            // if dwLen=0
    -        Strings.Add(s);
    +        Result[dwIndex]:=u;
           end;              // for dwIndex:=0 ...
     
         finally
    @@ -410,12 +403,11 @@
     end;
     
     
    -Function TRegistry.SysPutData(const Name: string; Buffer: Pointer;
    +Function TRegistry.SysPutData(const Name: UnicodeString; Buffer: Pointer;
       BufSize: Integer; RegData: TRegDataType) : Boolean;
     
     
     Var
    -  u: UnicodeString;
       RegDataType: DWORD;
       B : Pchar;
       S : String;
    @@ -422,12 +414,11 @@
     
     begin
       RegDataType:=RegDataWords[RegData];
    -  u:=UnicodeString(Name);
    -  FLastError:=RegSetValueExW(fCurrentKey,PWideChar(u),0,RegDataType,Buffer,BufSize);
    +  FLastError:=RegSetValueExW(fCurrentKey,PWideChar(Name),0,RegDataType,Buffer,BufSize);
       Result:=FLastError=ERROR_SUCCESS;
     end;
     
    -procedure TRegistry.RenameValue(const OldName, NewName: string);
    +procedure TRegistry.RenameValue(const OldName, NewName: UnicodeString);
     
     var
       L: Integer;
    Index: packages/fcl-registry/src/xmlreg.pp
    ===================================================================
    --- packages/fcl-registry/src/xmlreg.pp	(revision 41667)
    +++ packages/fcl-registry/src/xmlreg.pp	(working copy)
    @@ -25,6 +25,7 @@
         FTime     : TDateTime;
       end;
     
    +  TUnicodeStringArray = Array of UnicodeString;
     
       { TXmlRegistry }
     
    @@ -33,24 +34,24 @@
         FAutoFlush,
         FDirty : Boolean;
         FFileName : String;
    -    FRootKey : String;
    +    FRootKey : UnicodeString;
         FDocument : TXMLDocument;
         FCurrentElement : TDomElement;
    -    FCurrentKey : String;
    +    FCurrentKey : UnicodeString;
         Procedure SetFileName(Value : String);
       Protected
    -    function DoGetValueData(Name: String; out DataType: TDataType; Var Data; Var DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
    -    function DoSetValueData(Name: String; DataType: TDataType; const Data; DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
    +    function DoGetValueData(Name: UnicodeString; out DataType: TDataType; Var Data; Var DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
    +    function DoSetValueData(Name: UnicodeString; DataType: TDataType; const Data; DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
         Procedure LoadFromStream(S : TStream);
    -    Function  NormalizeKey(KeyPath : String) : String;
    +    Function  NormalizeKey(KeyPath : UnicodeString) : UnicodeString;
         Procedure CreateEmptyDoc;
    -    Function  FindKey (S : String) : TDomElement;
    -    Function  FindSubKey (S : String; N : TDomElement) : TDomElement;
    -    Function  CreateSubKey (S : String; N : TDomElement) : TDomElement;
    -    Function  FindValueKey (S : String) : TDomElement;
    -    Function  CreateValueKey (S : String) : TDomElement;
    +    Function  FindKey (S : UnicodeString) : TDomElement;
    +    Function  FindSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
    +    Function  CreateSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
    +    Function  FindValueKey (S : UnicodeString) : TDomElement;
    +    Function  CreateValueKey (S : UnicodeString) : TDomElement;
         Function  BufToHex(Const Buf; Len : Integer) : String;
    -    Function  hexToBuf(Const Str : String; Var Buf; Var Len : Integer ) : Integer;
    +    Function  HexToBuf(Const Str : UnicodeString; Var Buf; Var Len : Integer ) : Integer;
         Procedure MaybeFlush;
         Property  Document : TXMLDocument Read FDocument;
         Property  Dirty : Boolean Read FDirty write FDirty;
    @@ -57,29 +58,31 @@
       Public
         Constructor Create(AFileName : String);
         Destructor  Destroy;override;
    -    Function  SetKey(KeyPath : String; AllowCreate : Boolean) : Boolean ;
    -    Procedure SetRootKey(Value : String);
    -    Function  DeleteKey(KeyPath : String) : Boolean;
    -    Function  CreateKey(KeyPath : String) : Boolean;
    -    Function  GetValueSize(Name : String) : Integer;
    -    Function  GetValueType(Name : String) : TDataType;
    -    Function  GetValueInfo(Name : String; Out Info : TDataInfo; AsUnicode : Boolean = False) : Boolean;
    +    Function  SetKey(KeyPath : UnicodeString; AllowCreate : Boolean) : Boolean ;
    +    Procedure SetRootKey(Value : UnicodeString);
    +    Function  DeleteKey(KeyPath : UnicodeString) : Boolean;
    +    Function  CreateKey(KeyPath : UnicodeString) : Boolean;
    +    Function  GetValueSize(Name : UnicodeString) : Integer;
    +    Function  GetValueType(Name : UnicodeString) : TDataType;
    +    Function  GetValueInfo(Name : UnicodeString; Out Info : TDataInfo; AsUnicode : Boolean = False) : Boolean;
         Function  GetKeyInfo(Out Info : TKeyInfo) : Boolean;
         Function  EnumSubKeys(List : TStrings) : Integer;
    +    Function  EnumSubKeys: TUnicodeStringArray;
         Function  EnumValues(List : TStrings) : Integer;
    -    Function  KeyExists(KeyPath : String) : Boolean;
    -    Function  ValueExists(ValueName : String) : Boolean;
    -    Function  RenameValue(Const OldName,NewName : String) : Boolean;
    -    Function  DeleteValue(S : String) : Boolean;
    +    Function  EnumValues: TUnicodeStringArray;
    +    Function  KeyExists(KeyPath : UnicodeString) : Boolean;
    +    Function  ValueExists(ValueName : UnicodeString) : Boolean;
    +    Function  RenameValue(Const OldName,NewName : UnicodeString) : Boolean;
    +    Function  DeleteValue(S : UnicodeString) : Boolean;
         Procedure Flush;
         Procedure Load;
    -    Function GetValueData(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
    -    Function SetValueData(Name : String; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
    +    Function GetValueData(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
    +    Function SetValueData(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
         // These interpret the Data buffer as unicode data
    -    Function GetValueDataUnicode(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
    -    Function SetValueDataUnicode(Name : String; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
    +    Function GetValueDataUnicode(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
    +    Function SetValueDataUnicode(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
         Property FileName : String Read FFileName Write SetFileName;
    -    Property RootKey : String Read FRootKey Write SetRootkey;
    +    Property RootKey : UnicodeString Read FRootKey Write SetRootkey;
         Property AutoFlush : Boolean Read FAutoFlush Write FAutoFlush;
       end;
     
    @@ -143,13 +146,13 @@
       end;
     end;
     
    -Function TXmlRegistry.NormalizeKey(KeyPath : String) : String;
    +Function TXmlRegistry.NormalizeKey(KeyPath : UnicodeString) : UnicodeString;
     
     Var
       L : Integer;
     
     begin
    -  Result:=StringReplace(KeyPath,'\','/',[rfReplaceAll]);
    +  Result:=UnicodeStringReplace(KeyPath,'\','/',[rfReplaceAll]);
       L:=Length(Result);
       If (L>0) and (Result[L]<>'/') then
         Result:=Result+'/';
    @@ -157,10 +160,10 @@
         Result:='/' + Result;
     end;
     
    -Function TXmlRegistry.SetKey(KeyPath : String; AllowCreate : Boolean) : boolean;
    +Function TXmlRegistry.SetKey(KeyPath : UnicodeString; AllowCreate : Boolean) : boolean;
     
     Var
    -  SubKey,ResultKey : String;
    +  SubKey,ResultKey : UnicodeString;
       P : Integer;
       Node,Node2 : TDomElement;
     
    @@ -218,7 +221,7 @@
       MaybeFlush;
     end;
     
    -Procedure TXmlRegistry.SetRootKey(Value : String);
    +Procedure TXmlRegistry.SetRootKey(Value : UnicodeString);
     
     begin
       FRootKey:=NormalizeKey(Value);
    @@ -228,7 +231,7 @@
       FCurrentElement:=Nil;
     end;
     
    -Function TXmlRegistry.DeleteKey(KeyPath : String) : Boolean;
    +Function TXmlRegistry.DeleteKey(KeyPath : UnicodeString) : Boolean;
     
     Var
       N : TDomElement;
    @@ -244,10 +247,10 @@
        end;
     end;
     
    -Function TXmlRegistry.CreateKey(KeyPath : String) : Boolean;
    +Function TXmlRegistry.CreateKey(KeyPath : UnicodeString) : Boolean;
     
     Var
    -  SubKey : String;
    +  SubKey : UnicodeString;
       P : Integer;
       Node,Node2 : TDomElement;
     
    @@ -290,7 +293,7 @@
       MaybeFlush;
     end;
     
    -Function TXmlRegistry.DoGetValueData(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer; IsUnicode : Boolean) : Boolean;
    +Function TXmlRegistry.DoGetValueData(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer; IsUnicode : Boolean) : Boolean;
     
     Type
       PCardinal = ^Cardinal;
    @@ -305,22 +308,27 @@
       D : DWord;
       
     begin
    +  //writeln('TXmlRegistry.DoGetValueData: Name=',Name,' IsUnicode=',IsUnicode);
       Node:=FindValueKey(Name);
       Result:=Node<>Nil;
       If Result then
         begin
    +    //writeln('TXmlRegistry.DoGetValueData: Node<>nil');
         DataNode:=Node.FirstChild;
         HasData:=Assigned(DataNode) and (DataNode.NodeType=TEXT_NODE);
    -    ND:=StrToIntDef(Node[Stype],0);
    +    //writeln('TXmlRegistry.DoGetValueData: HasData=',hasdata);
    +    ND:=StrToIntDef(String(Node[Stype]),0);
    +    //writeln('TXmlRegistry.DoGetValueData: ND=',ND);
         Result:=ND<=Ord(High(TDataType));
         If Result then
           begin
           DataType:=TDataType(ND);
    +      //writeln('TXmlRegistry.DoGetValueData: DataType=',DataType);
           NS:=0; // Initialize, for optional nodes.
           Case DataType of
             dtDWORD : begin   // DataNode is required
                       NS:=SizeOf(Cardinal);
    -                  Result:=HasData and TryStrToDWord(DataNode.NodeValue,D) and (DataSize>=NS);
    +                  Result:=HasData and TryStrToDWord(String(DataNode.NodeValue),D) and (DataSize>=NS);
                       if Result then
                         PCardinal(@Data)^:=D;
                       end;
    @@ -329,7 +337,7 @@
                          begin
                          if not IsUnicode then
                            begin
    -                       S:=UTF8Encode(DataNode.NodeValue); // Convert to ansistring
    +                       S:=DataNode.NodeValue; // Convert to ansistring
                            NS:=Length(S);
                            Result:=(DataSize>=NS);
                            if Result then
    @@ -350,8 +358,10 @@
                        if HasData then
                          begin
                          BL:=Length(DataNode.NodeValue);
    +                     //writeln('TXmlRegistry.DoGetValueData: BL=',BL);
                          NS:=BL div 2;
                          Result:=DataSize>=NS;
    +                     //writeln('TXmlRegistry.DoGetValueData: Result=',Result);
                          If Result then
                            // No need to check for -1, We checked NS before calling.
                            NS:=HexToBuf(DataNode.NodeValue,Data,BL);
    @@ -363,7 +373,7 @@
         end;
     end;
     
    -Function TXmlRegistry.DoSetValueData(Name : String; DataType : TDataType; Const Data; DataSize : Integer; IsUnicode : Boolean) : Boolean;
    +Function TXmlRegistry.DoSetValueData(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer; IsUnicode : Boolean) : Boolean;
     
     Type
       PCardinal = ^Cardinal;
    @@ -374,6 +384,7 @@
       SW : UnicodeString;
     
     begin
    +  //writeln('TXmlRegistry.DoSetValueData A: Name=',Name,', DataType=',DataType,', DataSize=',DataSize,', IsUnicode=',IsUnicode);
       Node:=FindValueKey(Name);
       If Node=Nil then
         Node:=CreateValueKey(Name);
    @@ -380,20 +391,20 @@
       Result:=(Node<>Nil);
       If Result then
         begin
    -    Node[SType]:=IntToStr(Ord(DataType));
    +    Node[SType]:=UnicodeString(IntToStr(Ord(DataType)));
         DataNode:=Node.FirstChild;
     
         Case DataType of
    -      dtDWORD : SW:=IntToStr(PCardinal(@Data)^);
    +      dtDWORD : SW:=UnicodeString(IntToStr(PCardinal(@Data)^));
           dtString : begin
                      if IsUnicode then
                        SW:=UnicodeString(PUnicodeChar(@Data))
                      else
                        SW:=UnicodeString(PAnsiChar(@Data));
    -                   //S:=UTF8Encode(SW);
    +                   //S:=SW;
                      end;
    -      dtBinary : SW:=BufToHex(Data,DataSize);
    -      dtStrings : SW:=BufToHex(Data,DataSize);
    +      dtBinary : SW:=UnicodeString(BufToHex(Data,DataSize));
    +      dtStrings : SW:=UnicodeString(BufToHex(Data,DataSize));
         else
           sw:='';
         end;
    @@ -416,29 +427,29 @@
         end;
     end;
     
    -Function TXmlRegistry.SetValueData(Name : String; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
    +Function TXmlRegistry.SetValueData(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
     
     begin
       Result:=DoSetValueData(Name,DataType,Data,DataSize,False);
     end;
     
    -Function TXmlRegistry.GetValueData(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
    +Function TXmlRegistry.GetValueData(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
     
     begin
       Result:=DoGetValueData(Name,DataType,Data,DataSize,False);
     end;
     
    -function TXmlRegistry.GetValueDataUnicode(Name: String; out DataType: TDataType; Var Data; Var DataSize: Integer): Boolean;
    +function TXmlRegistry.GetValueDataUnicode(Name: UnicodeString; out DataType: TDataType; Var Data; Var DataSize: Integer): Boolean;
     begin
       Result:=DoGetValueData(Name,DataType,Data,DataSize,True);
     end;
     
    -function TXmlRegistry.SetValueDataUnicode(Name: String; DataType: TDataType; const Data; DataSize: Integer): Boolean;
    +function TXmlRegistry.SetValueDataUnicode(Name: UnicodeString; DataType: TDataType; const Data; DataSize: Integer): Boolean;
     begin
       Result:=DoSetValueData(Name,DataType,Data,DataSize,True)
     end;
     
    -Function TXmlRegistry.FindSubKey (S : String; N : TDomElement) : TDomElement;
    +Function TXmlRegistry.FindSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
     
     Var
       Node : TDOMNode;
    @@ -451,7 +462,7 @@
         While (Result=Nil) and (Assigned(Node)) do
           begin
           If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SKey) then
    -        If CompareText(TDomElement(Node)[SName],S)=0 then
    +        If UnicodeCompareText(TDomElement(Node)[SName],S)=0 then
               Result:=TDomElement(Node);
           Node:=Node.NextSibling;
           end;
    @@ -458,7 +469,7 @@
         end;
     end;
     
    -Function TXmlRegistry.CreateSubKey (S : String; N : TDomElement) : TDomElement;
    +Function TXmlRegistry.CreateSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
     
     begin
       Result:=FDocument.CreateElement(SKey);
    @@ -468,7 +479,7 @@
       FDirty:=True;
     end;
     
    -Function  TXmlRegistry.FindValueKey (S : String) : TDomElement;
    +Function  TXmlRegistry.FindValueKey (S : UnicodeString) : TDomElement;
     
     Var
       Node : TDOMNode;
    @@ -481,7 +492,7 @@
         While (Result=Nil) and (Assigned(Node)) do
           begin
           If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SValue) then
    -        If CompareText(TDomElement(Node)[SName],S)=0 then
    +        If UnicodeCompareText(TDomElement(Node)[SName],S)=0 then
               Result:=TDomElement(Node);
           Node:=Node.NextSibling;
           end;
    @@ -488,7 +499,7 @@
         end;
     end;
     
    -Function  TXmlRegistry.CreateValueKey (S : String) : TDomElement;
    +Function  TXmlRegistry.CreateValueKey (S : UnicodeString) : TDomElement;
     
     begin
       If Assigned(FCurrentElement) then
    @@ -581,38 +592,47 @@
         end;
     end;
     
    -Function TXMLRegistry.hexToBuf(Const Str : String; Var Buf; Var Len : Integer ) : Integer;
    +Function TXMLRegistry.HexToBuf(Const Str : UnicodeString; Var Buf; Var Len : Integer ) : Integer;
     
     Var
       NLeN,I : Integer;
       P : PByte;
    -  S : String;
    +  S : UnicodeString;
       B : Byte;
       Code : Integer;
     
     begin
    +  //writeln('TXMLRegistry.HexToBuf A: Str=',Str,', Len=',Len);
       Result:=0;
       P:=@Buf;
    +  //writeln('TXMLRegistry.HexToBuf B: (p=nil)=',p=nil);
       NLen:= Length(Str) div 2;
    +  //writeln('TXMLRegistry.HexToBuf C: NLen=',NLen,', SizeOf(TDateTime)=',SizeOf(TDateTime));
       If (NLen>Len) then
         begin
         Len:=NLen;
         Exit(-1);
         end;
    -  For I:=0 to Len-1 do
    +  For I:=0 to NLen-1 do
         begin
    +    //write('TXMLRegistry.HexToBuf: i=',i);
         S:='$'+Copy(Str,(I*2)+1,2);
    +    //write(', S=',S);
         Val(S,B,Code);
    +    //writeln(', Code=',Code);
         If Code<>0 then
    -      begin
    -      Inc(Result);
    -      B:=0;
    +      begin    //This means invalid data in the registry, why continue and increment result? Why not Exit(-1)?
    +      //Inc(Result);   //the whole function only worked because this was called as often as when Code=0, so by change
    +      //B:=0;          //it causes AV's
    +      Exit(-1);
           end;
    +    Inc(Result);
         P[I]:=B;
         end;
    +  //writeln('TXMLRegistry.HexToBuf End: Result=',Result);
     end;
     
    -Function TXMLRegistry.DeleteValue(S : String) : Boolean;
    +Function TXMLRegistry.DeleteValue(S : UnicodeString) : Boolean;
     
     Var
       N : TDomElement;
    @@ -628,31 +648,31 @@
         end;
     end;
     
    -Function TXMLRegistry.GetValueSize(Name : String) : Integer;
    +Function TXMLRegistry.GetValueSize(Name : UnicodeString) : Integer;
     
     Var
       Info : TDataInfo;
     
     begin
    -  If GetValueInfo(Name,Info) then
    +  If GetValueInfo(Name,Info,True) then
         Result:=Info.DataSize
       else
         Result:=-1;
     end;
     
    -Function TXMLRegistry.GetValueType(Name : String) : TDataType;
    +Function TXMLRegistry.GetValueType(Name : UnicodeString) : TDataType;
     
     Var
       Info : TDataInfo;
     
     begin
    -  If GetValueInfo(Name,Info) then
    +  If GetValueInfo(Name,Info,True) then
         Result:=Info.DataType
       else
         Result:=dtUnknown;
     end;
     
    -function TXmlRegistry.GetValueInfo(Name: String; out Info: TDataInfo; AsUnicode: Boolean): Boolean;
    +function TXmlRegistry.GetValueInfo(Name: UnicodeString; out Info: TDataInfo; AsUnicode: Boolean): Boolean;
     
     Var
       N  : TDomElement;
    @@ -671,7 +691,7 @@
             L:=Length(DN.NodeValue)*SizeOf(UnicodeChar)
           else
             begin
    -        S := UTF8Encode(DN.NodeValue);
    +        S := DN.NodeValue;
             L:=Length(S);
             end
           end
    @@ -679,7 +699,7 @@
           L:=0;
         With Info do
           begin
    -      DataType:=TDataType(StrToIntDef(N[SType],0));
    +      DataType:=TDataType(StrToIntDef(String(N[SType]),0));
           Case DataType of
             dtUnknown : DataSize:=0;
             dtDword   : Datasize:=SizeOf(Cardinal);
    @@ -724,10 +744,10 @@
                   ValueLen:=L;
                 DataNode:=TDomElement(Node).FirstChild;
                 If (DataNode<>Nil) and (DataNode is TDomText) then
    -              Case TDataType(StrToIntDef(TDomElement(Node)[SType],0)) of
    +              Case TDataType(StrToIntDef(String(TDomElement(Node)[SType]),0)) of
                     dtUnknown : L:=0;
                     dtDWord   : L:=4;
    -                DtString  : L:=Length(UTF8Encode(DataNode.NodeValue));
    +                DtString  : L:=Length(String(DataNode.NodeValue));
                     dtBinary  : L:=Length(DataNode.NodeValue) div 2;
                   end
                 else
    @@ -761,6 +781,37 @@
         end;
     end;
     
    +function TXmlRegistry.EnumSubKeys: TUnicodeStringArray;
    +
    +Var
    +  Node : TDOMNode;
    +  Len, Count: Integer;
    +
    +begin
    +  Result:=nil;
    +  If FCurrentElement<>Nil then
    +    begin
    +    Node:=FCurrentElement.FirstChild;
    +    Len:=0;
    +    Count:=0;
    +    While Assigned(Node) do
    +      begin
    +      If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SKey) then
    +        begin
    +        Inc(Count);
    +        if (Count>Len) then
    +          begin
    +          Inc(Len,10); //avoid calling SetLength on each addition
    +          SetLength(Result,Len);
    +          end;
    +        Result[Count-1]:=TDomElement(Node)[SName];
    +        end;
    +      Node:=Node.NextSibling;
    +      end;
    +    SetLength(Result,Count);
    +    end;
    +end;
    +
     Function TXMLRegistry.EnumValues(List : TStrings) : Integer;
     
     Var
    @@ -775,7 +826,8 @@
         While Assigned(Node) do
           begin
           If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SValue) then
    -        List.Add(TDomElement(Node)[SName]);
    +        If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SValue) then
    +          List.Add(TDomElement(Node)[SName]);
           Node:=Node.NextSibling;
           end;
         Result:=List.Count;
    @@ -782,13 +834,44 @@
         end;
     end;
     
    -Function TXMLRegistry.KeyExists(KeyPath : String) : Boolean;
    +Function TXMLRegistry.EnumValues: TUnicodeStringArray;
     
    +Var
    +  Node : TDOMNode;
    +  Len, Count: Integer;
     begin
    +  Result:=nil;
    +  If FCurrentElement<>Nil then
    +    begin
    +    Node:=FCurrentElement.FirstChild;
    +    Count:=0;
    +    Len:=0;
    +    While Assigned(Node) do
    +      begin
    +      If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SValue) then
    +        begin
    +        Inc(Count);
    +        if (Count>Len) then
    +          begin
    +          Inc(Len,10); //avoid calling SetLength on each addition
    +          SetLength(Result,Len);
    +          end;
    +        Result[Count-1]:=TDomElement(Node)[SName];
    +        end;
    +      Node:=Node.NextSibling;
    +      end;
    +    SetLength(Result,Count);
    +    end;
    +end;
    +
    +
    +Function TXMLRegistry.KeyExists(KeyPath : UnicodeString) : Boolean;
    +
    +begin
       Result:=FindKey(KeyPath)<>Nil;
     end;
     
    -Function TXMLRegistry.RenameValue(Const OldName,NewName : String) : Boolean;
    +Function TXMLRegistry.RenameValue(Const OldName,NewName : UnicodeString) : Boolean;
     
     Var
       N : TDomElement;
    @@ -804,10 +887,10 @@
         end;
     end;
     
    -Function TXMLRegistry.FindKey (S : String) : TDomElement;
    +Function TXMLRegistry.FindKey (S : UnicodeString) : TDomElement;
     
     Var
    -  SubKey : String;
    +  SubKey : UnicodeString;
       P : Integer;
       Node : TDomElement;
     
    @@ -840,7 +923,7 @@
       Until (Result=Nil) or (Length(S)=0);
     end;
     
    -Function  TXmlRegistry.ValueExists(ValueName : String) : Boolean;
    +Function  TXmlRegistry.ValueExists(ValueName : UnicodeString) : Boolean;
     
     begin
       Result:=FindValueKey(ValueName)<>Nil;
    Index: packages/fcl-registry/src/xregreg.inc
    ===================================================================
    --- packages/fcl-registry/src/xregreg.inc	(revision 41667)
    +++ packages/fcl-registry/src/xregreg.inc	(working copy)
    @@ -116,7 +116,11 @@
     procedure TRegistry.SysRegCreate;
     var s : string;
     begin
    +  FStringSizeIncludesNull:=False;
       s:=includetrailingpathdelimiter(GetAppConfigDir(GlobalXMLFile));
    +  {$ifdef XMLRegfile_in_CurDir}
    +  s:='.' + PathDelim;
    +  {$endif}
       ForceDirectories(s);
       FSysData:=TXMLRegistryInstance.GetXMLRegistry(s+XFileName);
       TXmlRegistry(FSysData).AutoFlush:=False;
    @@ -130,24 +134,24 @@
       TXMLRegistryInstance.FreeXMLRegistry(TXMLRegistry(FSysData));
     end;
     
    -function TRegistry.SysCreateKey(const Key: String): Boolean;
    +function TRegistry.SysCreateKey(Key: UnicodeString): Boolean;
     
     begin
       Result:=TXmlRegistry(FSysData).CreateKey(Key);
     end;
     
    -function TRegistry.DeleteKey(const Key: string): Boolean;
    +function TRegistry.DeleteKey(const Key: UnicodeString): Boolean;
     
     begin
       Result:=TXMLRegistry(FSysData).DeleteKey(Key);
     end;
     
    -function TRegistry.DeleteValue(const Name: string): Boolean;
    +function TRegistry.DeleteValue(const Name: UnicodeString): Boolean;
     begin
       Result:=TXmlRegistry(FSysData).DeleteValue(Name);
     end;
     
    -function TRegistry.SysGetData(const Name: String; Buffer: Pointer;
    +function TRegistry.SysGetData(const Name: UnicodeString; Buffer: Pointer;
               BufSize: Integer; Out RegData: TRegDataType): Integer;
     
     Var
    @@ -160,7 +164,7 @@
         Result:=-1;
     end;
     
    -function TRegistry.GetDataInfo(const ValueName: string; out Value: TRegDataInfo): Boolean;
    +function TRegistry.GetDataInfo(const ValueName: UnicodeString; out Value: TRegDataInfo): Boolean;
     
     Var
       Info : TDataInfo;
    @@ -181,7 +185,7 @@
           end;
     end;
     
    -function TRegistry.GetKey(const Key: string): HKEY;
    +function TRegistry.GetKey(Key: UnicodeString): HKEY;
     begin
       Result := 0;
     end;
    @@ -205,17 +209,17 @@
           end;
     end;
     
    -function TRegistry.KeyExists(const Key: string): Boolean;
    +function TRegistry.KeyExists(const Key: UnicodeString): Boolean;
     begin
       Result:=TXmlRegistry(FSysData).KeyExists(Key);
     end;
     
    -function TRegistry.LoadKey(const Key, FileName: string): Boolean;
    +function TRegistry.LoadKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.OpenKey(const Key: string; CanCreate: Boolean): Boolean;
    +function TRegistry.OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
     
     begin
       Result:=TXmlRegistry(FSysData).SetKey(Key,CanCreate);
    @@ -222,59 +226,59 @@
       FCurrentKey:=1;
     end;
     
    -function TRegistry.OpenKeyReadOnly(const Key: string): Boolean;
    +function TRegistry.OpenKeyReadOnly(const Key: UnicodeString): Boolean;
     
     begin
       Result:=TXmlRegistry(FSysData).SetKey(Key,False);
     end;
     
    -function TRegistry.RegistryConnect(const UNCName: string): Boolean;
    +function TRegistry.RegistryConnect(const UNCName: UnicodeString): Boolean;
     begin
       Result := True;
     end;
     
    -function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
    +function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.RestoreKey(const Key, FileName: string): Boolean;
    +function TRegistry.RestoreKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.SaveKey(const Key, FileName: string): Boolean;
    +function TRegistry.SaveKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.UnLoadKey(const Key: string): Boolean;
    +function TRegistry.UnLoadKey(const Key: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.ValueExists(const Name: string): Boolean;
    +function TRegistry.ValueExists(const Name: UnicodeString): Boolean;
     begin
       Result := TXmlRegistry(FSysData).ValueExists(Name);
     end;
     
    -procedure TRegistry.ChangeKey(Value: HKey; const Path: string);
    +procedure TRegistry.ChangeKey(Value: HKey; const Path: UnicodeString);
     begin
     
     end;
     
    -procedure TRegistry.GetKeyNames(Strings: TStrings);
    +function TRegistry.GetKeyNames: TUnicodeStringArray;
     begin
    -  TXmlRegistry(FSysData).EnumSubKeys(Strings);
    +  Result:=TXmlRegistry(FSysData).EnumSubKeys;
     end;
     
    -procedure TRegistry.GetValueNames(Strings: TStrings);
    +function TRegistry.GetValueNames: TUnicodeStringArray;
     begin
    -  TXmlRegistry(FSysData).EnumValues(Strings);
    +  Result := TXmlRegistry(FSysData).EnumValues;
     end;
     
     
    -function TRegistry.SysPutData(const Name: string; Buffer: Pointer;
    +function TRegistry.SysPutData(const Name: UnicodeString; Buffer: Pointer;
       BufSize: Integer; RegData: TRegDataType): Boolean;
     
     Var
    @@ -281,15 +285,18 @@
       DataType : TDataType;
     
     begin
    +  //writeln('TRegistry.SysPutData: Name=',Name,', RegData=',RegData,', BufSize=',BufSize);
       DataType:=RegDataTypeToXmlDataType(RegData);
    +
       Result:=TXMLRegistry(FSysData).SetValueDataUnicode(Name,DataType,Buffer^,BufSize);
     end;
     
    -procedure TRegistry.RenameValue(const OldName, NewName: string);
    +procedure TRegistry.RenameValue(const OldName, NewName: UnicodeString);
     begin
       TXMLRegistry(FSysData).RenameValue(OldName,NewName);
     end;
     
    +
     procedure TRegistry.SetCurrentKey(Value: HKEY);
     begin
       fCurrentKey := Value;
    @@ -298,7 +305,7 @@
     procedure TRegistry.SetRootKey(Value: HKEY);
     
     Var
    -  S: String;
    +  S: UnicodeString;
     
     begin
       If (Value=HKEY_CLASSES_ROOT) then
    @@ -347,3 +354,5 @@
         TXMLRegistry(FSysData).SetRootKey(TXMLRegistry(FSysData).RootKey);
       end;
     end;
    +
    +
    
  • registry.unicode.part7.diff (68,110 bytes)
    Index: packages/fcl-registry/src/regdef.inc
    ===================================================================
    --- packages/fcl-registry/src/regdef.inc	(revision 41749)
    +++ packages/fcl-registry/src/regdef.inc	(working copy)
    @@ -2,7 +2,7 @@
       HKEY = THandle;
       PHKEY = ^HKEY;
       
    -{$ifdef windows}
    +{$if defined(windows) and not defined(XMLREG)}
     
     { Direct mapping to constants in Windows unit }
     
    Index: packages/fcl-registry/src/registry.pp
    ===================================================================
    --- packages/fcl-registry/src/registry.pp	(revision 41749)
    +++ packages/fcl-registry/src/registry.pp	(working copy)
    @@ -39,6 +39,8 @@
         DataSize: Integer;
       end;
     
    +  TUnicodeStringArray = Array of UnicodeString;
    +
     { ---------------------------------------------------------------------
         TRegistry
       ---------------------------------------------------------------------}
    @@ -54,22 +56,31 @@
         fCurrentKey: HKEY;
         fRootKey: HKEY;
         fLazyWrite: Boolean;
    -    fCurrentPath: string;
    +    fCurrentPath: UnicodeString;
         function GetLastErrorMsg: string;
    +    function RegMultiSzDataToUnicodeStringArray(U: UnicodeString): TUnicodeStringArray;
    +    function ListToArray(List: TStrings; IsUtf8: Boolean): TUnicodeStringArray;
    +    procedure ArrayToList(const Arr: TUnicodeStringArray; List: TStrings; ForceUtf8: Boolean);
         procedure SetRootKey(Value: HKEY);
         Procedure SysRegCreate;
         Procedure SysRegFree;
    -    Function  SysGetData(const Name: String; Buffer: Pointer; BufSize: Integer; Out RegData: TRegDataType): Integer;
    -    Function  SysPutData(const Name: string; Buffer: Pointer; BufSize: Integer; RegData: TRegDataType) : Boolean;
    -    Function  SysCreateKey(const Key: String): Boolean;
    +    Function  SysGetData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; Out RegData: TRegDataType): Integer;
    +    Function  SysPutData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; RegData: TRegDataType) : Boolean;
    +    Function  SysCreateKey(Key: UnicodeString): Boolean;
       protected
         function GetBaseKey(Relative: Boolean): HKey;
    -    function GetData(const Name: string; Buffer: Pointer;
    +    function GetData(const Name: UnicodeString; Buffer: Pointer;
                       BufSize: Integer; Out RegData: TRegDataType): Integer;
    -    function GetKey(const Key: string): HKEY;
    -    procedure ChangeKey(Value: HKey; const Path: string);
    -    procedure PutData(const Name: string; Buffer: Pointer;
    +    function GetData(const Name: String; Buffer: Pointer;
    +                  BufSize: Integer; Out RegData: TRegDataType): Integer;
    +    function GetKey(Key: UnicodeString): HKEY;
    +    function GetKey(Key: String): HKEY;
    +    procedure ChangeKey(Value: HKey; const Path: UnicodeString);
    +    procedure ChangeKey(Value: HKey; const Path: String);
    +    procedure PutData(const Name: UnicodeString; Buffer: Pointer;
                       BufSize: Integer; RegData: TRegDataType);
    +    procedure PutData(const Name: String; Buffer: Pointer;
    +                  BufSize: Integer; RegData: TRegDataType);
         procedure SetCurrentKey(Value: HKEY);
       public
         constructor Create; overload;
    @@ -76,58 +87,105 @@
         constructor Create(aaccess:longword); overload;
         destructor Destroy; override;
     
    -    function CreateKey(const Key: string): Boolean;
    -    function DeleteKey(const Key: string): Boolean;
    -    function DeleteValue(const Name: string): Boolean;
    -    function GetDataInfo(const ValueName: string; Out Value: TRegDataInfo): Boolean;
    -    function GetDataSize(const ValueName: string): Integer;
    -    function GetDataType(const ValueName: string): TRegDataType;
    +    function CreateKey(const Key: UnicodeString): Boolean;
    +    function CreateKey(const Key: String): Boolean;
    +    function DeleteKey(const Key: UnicodeString): Boolean;
    +    function DeleteKey(const Key: String): Boolean;
    +    function DeleteValue(const Name: UnicodeString): Boolean;
    +    function DeleteValue(const Name: String): Boolean;
    +    function GetDataInfo(const ValueName: UnicodeString; Out Value: TRegDataInfo): Boolean;
    +    function GetDataInfo(const ValueName: String; Out Value: TRegDataInfo): Boolean;
    +    function GetDataSize(const ValueName: UnicodeString): Integer;
    +    function GetDataSize(const ValueName: String): Integer;
    +    function GetDataType(const ValueName: UnicodeString): TRegDataType;
    +    function GetDataType(const ValueName: String): TRegDataType;
         function GetKeyInfo(Out Value: TRegKeyInfo): Boolean;
         function HasSubKeys: Boolean;
    -    function KeyExists(const Key: string): Boolean;
    -    function LoadKey(const Key, FileName: string): Boolean;
    -    function OpenKey(const Key: string; CanCreate: Boolean): Boolean;
    -    function OpenKeyReadOnly(const Key: string): Boolean;
    -    function ReadCurrency(const Name: string): Currency;
    -    function ReadBinaryData(const Name: string; var Buffer; BufSize: Integer): Integer;
    -    function ReadBool(const Name: string): Boolean;
    -    function ReadDate(const Name: string): TDateTime;
    -    function ReadDateTime(const Name: string): TDateTime;
    -    function ReadFloat(const Name: string): Double;
    -    function ReadInteger(const Name: string): Integer;
    -    function ReadInt64(const Name: string): Int64;
    -    function ReadString(const Name: string): string;
    -    procedure ReadStringList(const Name: string; AList: TStrings);
    -    function ReadTime(const Name: string): TDateTime;
    -    function RegistryConnect(const UNCName: string): Boolean;
    -    function ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
    -    function RestoreKey(const Key, FileName: string): Boolean;
    -    function SaveKey(const Key, FileName: string): Boolean;
    -    function UnLoadKey(const Key: string): Boolean;
    -    function ValueExists(const Name: string): Boolean;
    +    function KeyExists(const Key: UnicodeString): Boolean;
    +    function KeyExists(const Key: String): Boolean;
    +    function LoadKey(const Key, FileName: UnicodeString): Boolean;
    +    function LoadKey(const Key, FileName: String): Boolean;
    +    function OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
    +    function OpenKey(const Key: String; CanCreate: Boolean): Boolean;
    +    function OpenKeyReadOnly(const Key: UnicodeString): Boolean;
    +    function OpenKeyReadOnly(const Key: String): Boolean;
    +    function ReadCurrency(const Name: UnicodeString): Currency;
    +    function ReadCurrency(const Name: String): Currency;
    +    function ReadBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer): Integer;
    +    function ReadBinaryData(const Name: String; var Buffer; BufSize: Integer): Integer;
    +    function ReadBool(const Name: UnicodeString): Boolean;
    +    function ReadBool(const Name: String): Boolean;
    +    function ReadDate(const Name: UnicodeString): TDateTime;
    +    function ReadDate(const Name: String): TDateTime;
    +    function ReadDateTime(const Name: UnicodeString): TDateTime;
    +    function ReadDateTime(const Name: String): TDateTime;
    +    function ReadFloat(const Name: UnicodeString): Double;
    +    function ReadFloat(const Name: String): Double;
    +    function ReadInteger(const Name: UnicodeString): Integer;
    +    function ReadInteger(const Name: String): Integer;
    +    function ReadInt64(const Name: UnicodeString): Int64;
    +    function ReadInt64(const Name: String): Int64;
    +    function ReadString(const Name: UnicodeString): UnicodeString;
    +    function ReadString(const Name: String): string;
    +    procedure ReadStringList(const Name: UnicodeString; AList: TStrings; ForceUtf8: Boolean=False);
    +    procedure ReadStringList(const Name: String; AList: TStrings);
    +    function ReadStringArray(const Name: UnicodeString): TUnicodeStringArray;
    +    function ReadStringArray(const Name: String): TStringArray;
    +    function ReadTime(const Name: UnicodeString): TDateTime;
    +    function ReadTime(const Name: String): TDateTime;
    +    function RegistryConnect(const UNCName: UnicodeString): Boolean;
    +    function RegistryConnect(const UNCName: String): Boolean;
    +    function ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
    +    function ReplaceKey(const Key, FileName, BackUpFileName: String): Boolean;
    +    function RestoreKey(const Key, FileName: UnicodeString): Boolean;
    +    function RestoreKey(const Key, FileName: String): Boolean;
    +    function SaveKey(const Key, FileName: UnicodeString): Boolean;
    +    function SaveKey(const Key, FileName: String): Boolean;
    +    function UnLoadKey(const Key: UnicodeString): Boolean;
    +    function UnLoadKey(const Key: String): Boolean;
    +    function ValueExists(const Name: UnicodeString): Boolean;
    +    function ValueExists(const Name: String): Boolean;
     
         procedure CloseKey;
         procedure CloseKey(key:HKEY);
         procedure GetKeyNames(Strings: TStrings);
    +    function GetKeyNames: TUnicodeStringArray;
         procedure GetValueNames(Strings: TStrings);
    -    procedure MoveKey(const OldName, NewName: string; Delete: Boolean);
    -    procedure RenameValue(const OldName, NewName: string);
    -    procedure WriteCurrency(const Name: string; Value: Currency);
    -    procedure WriteBinaryData(const Name: string; var Buffer; BufSize: Integer);
    -    procedure WriteBool(const Name: string; Value: Boolean);
    -    procedure WriteDate(const Name: string; Value: TDateTime);
    -    procedure WriteDateTime(const Name: string; Value: TDateTime);
    -    procedure WriteFloat(const Name: string; Value: Double);
    -    procedure WriteInteger(const Name: string; Value: Integer);
    -    procedure WriteInt64(const Name: string; Value: Int64);
    -    procedure WriteString(const Name, Value: string);
    -    procedure WriteExpandString(const Name, Value: string);
    -    procedure WriteStringList(const Name: string; List: TStrings);
    -    procedure WriteTime(const Name: string; Value: TDateTime);
    +    //ToDo
    +    function GetValueNames: TUnicodeStringArray;
    +    procedure MoveKey(const OldName, NewName: UnicodeString; Delete: Boolean);
    +    procedure MoveKey(const OldName, NewName: String; Delete: Boolean);
    +    procedure RenameValue(const OldName, NewName: UnicodeString);
    +    procedure RenameValue(const OldName, NewName: String);
    +    procedure WriteCurrency(const Name: UnicodeString; Value: Currency);
    +    procedure WriteCurrency(const Name: String; Value: Currency);
    +    procedure WriteBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer);
    +    procedure WriteBinaryData(const Name: String; var Buffer; BufSize: Integer);
    +    procedure WriteBool(const Name: UnicodeString; Value: Boolean);
    +    procedure WriteBool(const Name: String; Value: Boolean);
    +    procedure WriteDate(const Name: UnicodeString; Value: TDateTime);
    +    procedure WriteDate(const Name: String; Value: TDateTime);
    +    procedure WriteDateTime(const Name: UnicodeString; Value: TDateTime);
    +    procedure WriteDateTime(const Name: String; Value: TDateTime);
    +    procedure WriteFloat(const Name: UnicodeString; Value: Double);
    +    procedure WriteFloat(const Name: String; Value: Double);
    +    procedure WriteInteger(const Name: UnicodeString; Value: Integer);
    +    procedure WriteInteger(const Name: String; Value: Integer);
    +    procedure WriteInt64(const Name: UnicodeString; Value: Int64);
    +    procedure WriteInt64(const Name: String; Value: Int64);
    +    procedure WriteString(const Name, Value: UnicodeString);
    +    procedure WriteString(const Name, Value: String);
    +    procedure WriteExpandString(const Name, Value: UnicodeString);
    +    procedure WriteExpandString(const Name, Value: String);
    +    procedure WriteStringList(const Name: UnicodeString; List: TStrings; IsUtf8: Boolean=False);
    +    procedure WriteStringArray(const Name: UnicodeString; const Arr: TUnicodeStringArray);
    +    procedure WriteStringArray(const Name: String; const Arr: TStringArray);
    +    procedure WriteTime(const Name: UnicodeString; Value: TDateTime);
    +    procedure WriteTime(const Name: String; Value: TDateTime);
     
         property Access: LongWord read fAccess write fAccess;
         property CurrentKey: HKEY read fCurrentKey;
    -    property CurrentPath: string read fCurrentPath;
    +    property CurrentPath: UnicodeString read fCurrentPath;
         property LazyWrite: Boolean read fLazyWrite write fLazyWrite;
         property RootKey: HKEY read fRootKey write SetRootKey;
         Property StringSizeIncludesNull : Boolean read FStringSizeIncludesNull;
    @@ -235,6 +293,16 @@
         Generic, implementation-independent code.
       ---------------------------------------------------------------------}
     
    +{$ifdef DebugRegistry}
    +function DbgS(const S: UnicodeString): String;
    +var
    +  C: WideChar;
    +begin
    +  Result := '';
    +  for C in S do Result := Result + IntToHex(Word(C),4) + #32;
    +  Result := TrimRight(Result);
    +end;
    +{$endif}
     
     constructor TRegistry.Create;
     
    @@ -261,7 +329,7 @@
       inherited Destroy;
     end;
     
    -function TRegistry.CreateKey(const Key: string): Boolean;
    +function TRegistry.CreateKey(const Key: UnicodeString): Boolean;
     
     begin
       Result:=SysCreateKey(Key);
    @@ -269,6 +337,27 @@
         Raise ERegistryException.CreateFmt(SRegCreateFailed, [Key]);
     end;
     
    +function TRegistry.CreateKey(const Key: String): Boolean;
    +begin
    +  Result:=CreateKey(UnicodeString(Key));
    +end;
    +
    +function TRegistry.DeleteKey(const Key: String): Boolean;
    +begin
    +  Result:=DeleteKey(UnicodeString(Key));
    +end;
    +
    +function TRegistry.DeleteValue(const Name: String): Boolean;
    +begin
    +  Result:=DeleteValue(UnicodeString(Name));
    +end;
    +
    +function TRegistry.GetDataInfo(const ValueName: String; out Value: TRegDataInfo
    +  ): Boolean;
    +begin
    +  Result:=GetDataInfo(UnicodeString(ValueName), Value);
    +end;
    +
     function TRegistry.GetBaseKey(Relative: Boolean): HKey;
     begin
       If Relative and (CurrentKey<>0) Then
    @@ -277,7 +366,7 @@
         Result := RootKey;
     end;
     
    -function TRegistry.GetData(const Name: string; Buffer: Pointer; BufSize: Integer; out RegData: TRegDataType): Integer;
    +function TRegistry.GetData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; out RegData: TRegDataType): Integer;
     begin
       Result:=SysGetData(Name,Buffer,BufSize,RegData);
       If (Result=-1) then
    @@ -284,7 +373,24 @@
         Raise ERegistryException.CreateFmt(SRegGetDataFailed, [Name]);
     end;
     
    -procedure TRegistry.PutData(const Name: string; Buffer: Pointer;
    +function TRegistry.GetData(const Name: String; Buffer: Pointer;
    +  BufSize: Integer; out RegData: TRegDataType): Integer;
    +begin
    +  Result:=GetData(UnicodeString(Name), Buffer, BufSize, RegData);
    +end;
    +
    +function TRegistry.GetKey(Key: String): HKEY;
    +begin
    +  Result:=GetKey(UnicodeString(Key));
    +end;
    +
    +procedure TRegistry.ChangeKey(Value: HKey; const Path: String);
    +begin
    +  ChangeKey(Value, UnicodeString(Path));
    +end;
    +
    +
    +procedure TRegistry.PutData(const Name: UnicodeString; Buffer: Pointer;
       BufSize: Integer; RegData: TRegDataType);
     
     begin
    @@ -292,9 +398,15 @@
         Raise ERegistryException.CreateFmt(SRegSetDataFailed, [Name]);
     end;
     
    +procedure TRegistry.PutData(const Name: String; Buffer: Pointer;
    +  BufSize: Integer; RegData: TRegDataType);
    +begin
    +  PutData(UnicodeString(Name), Buffer, BufSize, RegData);
    +end;
     
    -function TRegistry.GetDataSize(const ValueName: string): Integer;
     
    +function TRegistry.GetDataSize(const ValueName: UnicodeString): Integer;
    +
     Var
       Info: TRegDataInfo;
     
    @@ -305,8 +417,13 @@
         Result := -1;
     end;
     
    -function TRegistry.GetDataType(const ValueName: string): TRegDataType;
    +function TRegistry.GetDataSize(const ValueName: String): Integer;
    +begin
    +  Result:=GetDataSize(UnicodeString(ValueName));
    +end;
     
    +function TRegistry.GetDataType(const ValueName: UnicodeString): TRegDataType;
    +
     Var
       Info: TRegDataInfo;
     
    @@ -315,6 +432,32 @@
       Result:=Info.RegData;
     end;
     
    +function TRegistry.GetDataType(const ValueName: String): TRegDataType;
    +begin
    +  Result:=GetDataType(UnicodeString(ValueName));
    +end;
    +
    +
    +function TRegistry.KeyExists(const Key: String): Boolean;
    +begin
    +  Result:=KeyExists(UnicodeString(Key));
    +end;
    +
    +function TRegistry.LoadKey(const Key, FileName: String): Boolean;
    +begin
    +  Result:=LoadKey(UnicodeString(Key), UnicodeString(FileName));
    +end;
    +
    +function TRegistry.OpenKey(const Key: String; CanCreate: Boolean): Boolean;
    +begin
    +  Result:=OpenKey(UnicodeString(Key), CanCreate);
    +end;
    +
    +function TRegistry.OpenKeyReadOnly(const Key: String): Boolean;
    +begin
    +  Result:=OpenKeyReadOnly(UnicodeString(Key));
    +end;
    +
     function TRegistry.HasSubKeys: Boolean;
     
     Var
    @@ -326,7 +469,7 @@
         Result:=(Info.NumSubKeys>0);
     end;
     
    -function TRegistry.ReadBinaryData(const Name: string; var Buffer; BufSize: Integer): Integer;
    +function TRegistry.ReadBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer): Integer;
     
     Var
       RegDataType: TRegDataType;
    @@ -337,8 +480,14 @@
         Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
     end;
     
    -function TRegistry.ReadInteger(const Name: string): Integer;
    +function TRegistry.ReadBinaryData(const Name: String; var Buffer;
    +  BufSize: Integer): Integer;
    +begin
    +  Result:=ReadBinaryData(UnicodeString(Name), Buffer, BufSize);
    +end;
     
    +function TRegistry.ReadInteger(const Name: UnicodeString): Integer;
    +
     Var
       RegDataType: TRegDataType;
     
    @@ -348,8 +497,13 @@
         Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
     end;
     
    -function TRegistry.ReadInt64(const Name: string): Int64;
    +function TRegistry.ReadInteger(const Name: String): Integer;
    +begin
    +  Result:=ReadInteger(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadInt64(const Name: UnicodeString): Int64;
    +
     Var
       RegDataType: TRegDataType;
     
    @@ -359,21 +513,36 @@
         Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
     end;
     
    -function TRegistry.ReadBool(const Name: string): Boolean;
    +function TRegistry.ReadInt64(const Name: String): Int64;
    +begin
    +  Result:=ReadInt64(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadBool(const Name: UnicodeString): Boolean;
    +
     begin
       Result:=ReadInteger(Name)<>0;
     end;
     
    -function TRegistry.ReadCurrency(const Name: string): Currency;
    +function TRegistry.ReadBool(const Name: String): Boolean;
    +begin
    +  Result:=ReadBool(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadCurrency(const Name: UnicodeString): Currency;
    +
     begin
       Result:=Default(Currency);
       ReadBinaryData(Name, Result, SizeOf(Currency));
     end;
     
    -function TRegistry.ReadDate(const Name: string): TDateTime;
    +function TRegistry.ReadCurrency(const Name: String): Currency;
    +begin
    +  Result:=ReadCurrency(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadDate(const Name: UnicodeString): TDateTime;
    +
     begin
       Result:=Default(TDateTime);
       ReadBinaryData(Name, Result, SizeOf(TDateTime));
    @@ -380,22 +549,37 @@
       Result:=Trunc(Result);
     end;
     
    -function TRegistry.ReadDateTime(const Name: string): TDateTime;
    +function TRegistry.ReadDate(const Name: String): TDateTime;
    +begin
    +  Result:=ReadDate(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadDateTime(const Name: UnicodeString): TDateTime;
    +
     begin
       Result:=Default(TDateTime);
       ReadBinaryData(Name, Result, SizeOf(TDateTime));
     end;
     
    -function TRegistry.ReadFloat(const Name: string): Double;
    +function TRegistry.ReadDateTime(const Name: String): TDateTime;
    +begin
    +  Result:=ReadDateTime(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadFloat(const Name: UnicodeString): Double;
    +
     begin
       Result:=Default(Double);
       ReadBinaryData(Name,Result,SizeOf(Double));
     end;
     
    -function TRegistry.ReadString(const Name: string): string;
    +function TRegistry.ReadFloat(const Name: String): Double;
    +begin
    +  Result:=ReadFloat(UnicodeString(Name));
    +end;
     
    +function TRegistry.ReadString(const Name: UnicodeString): UnicodeString;
    +
     Var
       Info : TRegDataInfo;
       ReadDataSize: Integer;
    @@ -421,47 +605,139 @@
           if StringSizeIncludesNull and
              (u[Length(u)] = WideChar(0)) then
             SetLength(u,Length(u)-1);
    -      Result:=UTF8Encode(u);
    +      Result:=u;
         end;
       end;
     end;
     
    -procedure TRegistry.ReadStringList(const Name: string; AList: TStrings);
    +function TRegistry.ReadString(const Name: String): string;
    +begin
    +  Result:=ReadString(UnicodeString(Name));
    +end;
     
    +
    +procedure TRegistry.ReadStringList(const Name: UnicodeString; AList: TStrings; ForceUtf8: Boolean=False);
    +
     Var
    +  UArr: TUnicodeStringArray;
    +
    +begin
    +  UArr := ReadStringArray(Name);
    +  ArrayToList(UArr, AList, ForceUtf8);
    +end;
    +
    +procedure TRegistry.ReadStringList(const Name: String; AList: TStrings);
    +begin
    +  ReadStringList(UnicodeString(Name), AList);
    +end;
    +
    +function TRegistry.RegMultiSzDataToUnicodeStringArray(U: UnicodeString): TUnicodeStringArray;
    +var
    +  Len, i, p: Integer;
    +  Sub: UnicodeString;
    +begin
    +  Result := nil;
    +  if (U = '') then Exit;
    +  Len := 1;
    +  for i := 1 to Length(U) do if (U[i] = #0) then Inc(Len);
    +  SetLength(Result, Len);
    +  i := 0;
    +
    +  while (U <> '') and (i < Length(Result)) do
    +  begin
    +    p := Pos(#0, U);
    +    if (p = 0) then p := Length(U) + 1;
    +    Sub := Copy(U, 1, p - 1);
    +    Result[i] := Sub;
    +    System.Delete(U, 1, p);
    +    Inc(i);
    +  end;
    +end;
    +
    +function TRegistry.ListToArray(List: TStrings; IsUtf8: Boolean): TUnicodeStringArray;
    +var
    +  i, curr, Len: Integer;
    +  u: UnicodeString;
    +begin
    +  Result := nil;
    +  Len := List.Count;
    +  SetLength(Result, Len);
    +  //REG_MULTI_SZ data cannot contain empty strings
    +  curr := 0;
    +  for i := 0 to List.Count - 1 do
    +  begin
    +    if IsUtf8 then
    +      u := Utf8Decode(List[i])
    +    else
    +      u := List[i];
    +    if (u>'') then
    +    begin
    +      Result[curr] := u;
    +      inc(curr);
    +    end
    +    else
    +      Dec(Len);
    +  end;
    +  if (Len <> List.Count) then SetLength(Result, Len);
    +end;
    +
    +procedure TRegistry.ArrayToList(const Arr: TUnicodeStringArray; List: TStrings; ForceUtf8: Boolean);
    +var
    +  i: Integer;
    +begin
    +  List.Clear;
    +  for i := Low(Arr) to High(Arr) do
    +  begin
    +    if ForceUtf8 then
    +      List.Add(Utf8Encode(Arr[i]))
    +    else
    +      List.Add(String(Arr[i]));
    +  end;
    +end;
    +
    +function TRegistry.ReadStringArray(const Name: UnicodeString): TUnicodeStringArray;
    +Var
       Info : TRegDataInfo;
       ReadDataSize: Integer;
    -  Data: string;
    +  Data: UnicodeString;
     
     begin
    -  AList.Clear;
    +  Result := nil;
       GetDataInfo(Name,Info);
    +  //writeln('TRegistry.ReadStringArray: datasize=',info.datasize);
       if info.datasize>0 then
         begin
          If Not (Info.RegData in [rdMultiString]) then
            Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
          SetLength(Data,Info.DataSize);
    -     ReadDataSize := GetData(Name,PChar(Data),Info.DataSize,Info.RegData);
    +     ReadDataSize := GetData(Name,PWideChar(Data),Info.DataSize,Info.RegData) div SizeOf(WideChar);
    +     //writeln('TRegistry.ReadStringArray: ReadDataSize=',ReadDataSize);
          if ReadDataSize > 0 then
          begin
    -       // If the data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type,
    -       // the size includes any terminating null character or characters
    -       // unless the data was stored without them! (RegQueryValueEx @ MSDN)
    -       if StringSizeIncludesNull then begin
    -         if Data[ReadDataSize] = #0 then
    -           Dec(ReadDataSize);
    -         if Data[ReadDataSize] = #0 then
    -           Dec(ReadDataSize);
    -       end;
    +       // Windows returns the data with or without trailing zero's, so just strip all trailing null characters
    +        while (Data[ReadDataSize] = #0) do Dec(ReadDataSize);
            SetLength(Data, ReadDataSize);
    -       Data := StringReplace(Data, #0, LineEnding, [rfReplaceAll]);
    -       AList.Text := Data;
    +       //writeln('Data=',dbgs(data));
    +       //Data := UnicodeStringReplace(Data, #0, AList.LineBreak, [rfReplaceAll]);
    +       //AList.Text := Data;
    +       Result := RegMultiSzDataToUnicodeStringArray(Data);
          end
        end
     end;
     
    -function TRegistry.ReadTime(const Name: string): TDateTime;
    +function TRegistry.ReadStringArray(const Name: String): TStringArray;
    +var
    +  UArr: TUnicodeStringArray;
    +  i: Integer;
    +begin
    +  Result := nil;
    +  UArr := ReadStringArray(UnicodeString(Name));
    +  SetLength(Result, Length(UArr));
    +  for i := Low(UArr) to High(UArr) do Result[i] := UArr[i];
    +end;
     
    +function TRegistry.ReadTime(const Name: UnicodeString): TDateTime;
    +
     begin
       Result:=Default(TDateTime);
       ReadBinaryData(Name, Result, SizeOf(TDateTime));
    @@ -468,85 +744,230 @@
       Result:=Frac(Result);
     end;
     
    -procedure TRegistry.WriteBinaryData(const Name: string; var Buffer; BufSize: Integer);
    +function TRegistry.ReadTime(const Name: String): TDateTime;
     begin
    +  Result:=ReadTime(UnicodeString(Name));
    +end;
    +
    +function TRegistry.RegistryConnect(const UNCName: String): Boolean;
    +begin
    +  Result:=RegistryConnect(UnicodeString(UNCName));
    +end;
    +
    +function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: String): Boolean;
    +begin
    +  Result:=ReplaceKey(UnicodeString(Key), UnicodeString(FileName), UnicodeString(BackUpFileName))
    +end;
    +
    +function TRegistry.RestoreKey(const Key, FileName: String): Boolean;
    +begin
    +  Result:=RestoreKey(UnicodeString(Key), UnicodeString(FileName));
    +end;
    +
    +function TRegistry.SaveKey(const Key, FileName: String): Boolean;
    +begin
    +  Result:=SaveKey(UnicodeString(Key), UnicodeString(FileName));
    +end;
    +
    +function TRegistry.UnLoadKey(const Key: String): Boolean;
    +begin
    +  Result:=UnloadKey(UnicodeString(Key));
    +end;
    +
    +function TRegistry.ValueExists(const Name: String): Boolean;
    +begin
    +  Result:=ValueExists(UnicodeString(Name));
    +end;
    +
    +procedure TRegistry.WriteBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer);
    +begin
       PutData(Name, @Buffer, BufSize, rdBinary);
     end;
     
    -procedure TRegistry.WriteBool(const Name: string; Value: Boolean);
    +procedure TRegistry.WriteBinaryData(const Name: String; var Buffer;
    +  BufSize: Integer);
    +begin
    +  WriteBinaryData(UnicodeString(Name), Buffer, BufSize);
    +end;
     
    +procedure TRegistry.WriteBool(const Name: UnicodeString; Value: Boolean);
    +
     begin
       WriteInteger(Name,Ord(Value));
     end;
     
    -procedure TRegistry.WriteCurrency(const Name: string; Value: Currency);
    +procedure TRegistry.WriteBool(const Name: String; Value: Boolean);
     begin
    +  WriteBool(UnicodeString(Name), Value);
    +end;
    +
    +procedure TRegistry.WriteCurrency(const Name: UnicodeString; Value: Currency);
    +begin
       WriteBinaryData(Name, Value, SizeOf(Currency));
     end;
     
    -procedure TRegistry.WriteDate(const Name: string; Value: TDateTime);
    +procedure TRegistry.WriteCurrency(const Name: String; Value: Currency);
     begin
    +  WriteCurrency(UnicodeString(Name), Value);
    +end;
    +
    +procedure TRegistry.WriteDate(const Name: UnicodeString; Value: TDateTime);
    +begin
       WriteBinarydata(Name, Value, SizeOf(TDateTime));
     end;
     
    -procedure TRegistry.WriteTime(const Name: string; Value: TDateTime);
    +procedure TRegistry.WriteDate(const Name: String; Value: TDateTime);
     begin
    +  WriteDate(UnicodeString(Name), Value);
    +end;
    +
    +procedure TRegistry.WriteTime(const Name: UnicodeString; Value: TDateTime);
    +begin
       WriteBinaryData(Name, Value, SizeOf(TDateTime));
     end;
     
    -procedure TRegistry.WriteDateTime(const Name: string; Value: TDateTime);
    +procedure TRegistry.WriteTime(const Name: String; Value: TDateTime);
     begin
    +  WriteTime(UnicodeString(Name), Value);
    +end;
    +
    +procedure TRegistry.WriteDateTime(const Name: UnicodeString; Value: TDateTime);
    +begin
       WriteBinaryData(Name, Value, SizeOf(TDateTime));
     end;
     
    -procedure TRegistry.WriteExpandString(const Name, Value: string);
    -var
    -  u: UnicodeString;
    +procedure TRegistry.WriteDateTime(const Name: String; Value: TDateTime);
    +begin
    +  WriteDateTime(UnicodeString(Name), Value);
    +end;
     
    +procedure TRegistry.WriteExpandString(const Name, Value: UnicodeString);
     begin
    -  u:=Value;
    -  PutData(Name, PWideChar(u), ByteLength(u), rdExpandString);
    +  PutData(Name, PWideChar(Value), ByteLength(Value), rdExpandString);
     end;
     
    -procedure TRegistry.WriteStringList(const Name: string; List: TStrings);
    +procedure TRegistry.WriteExpandString(const Name, Value: String);
    +begin
    +  WriteExpandString(UnicodeString(Name), UnicodeString(Value));
    +end;
     
    +
    +procedure TRegistry.WriteStringList(const Name: UnicodeString; List: TStrings; IsUtf8: Boolean=False);
    +
     Var
    -  Data: string;
    +  UArr: TUnicodeStringArray;
    +begin
    +  UArr := ListToArray(List, IsUtf8);
    +  WriteStringArray(Name, UArr);
    +end;
     
    +procedure TRegistry.WriteStringArray(const Name: UnicodeString; const Arr: TUnicodeStringArray);
    +Var
    +  Data: UnicodeString;
    +  u: UnicodeString;
    +  i: Integer;
     begin
    -  Data := StringReplace(List.Text, LineEnding, #0, [rfReplaceAll]) + #0#0;
    -  PutData(Name, PChar(Data), Length(Data),rdMultiString);
    +  Data := '';
    +  //REG_MULTI_SZ data cannot contain empty strings
    +  for i := Low(Arr) to High(Arr) do
    +  begin
    +    u := Arr[i];
    +    if (u>'') then
    +    begin
    +      if (Data>'') then
    +        Data := Data + #0 + u
    +      else
    +        Data := Data + u;
    +    end;
    +  end;
    +  if StringSizeIncludesNull then
    +    Data := Data + #0#0;
    +  //writeln('Data=',Dbgs(Data));
    +  PutData(Name, PWideChar(Data), ByteLength(Data), rdMultiString);
     end;
     
    -procedure TRegistry.WriteFloat(const Name: string; Value: Double);
    +procedure TRegistry.WriteStringArray(const Name: String; const Arr: TStringArray);
    +var
    +  UArr: TUnicodeStringArray;
    +  i: Integer;
     begin
    +  UArr := nil;
    +  SetLength(UArr, Length(Arr));
    +  for i := Low(Arr) to High(Arr) do UArr[i] := Arr[i];
    +  WriteStringArray(UnicodeString(Name), UArr);
    +end;
    +
    +procedure TRegistry.WriteFloat(const Name: UnicodeString; Value: Double);
    +begin
       WriteBinaryData(Name, Value, SizeOf(Double));
     end;
     
    -procedure TRegistry.WriteInteger(const Name: string; Value: Integer);
    +procedure TRegistry.WriteFloat(const Name: String; Value: Double);
     begin
    +  WriteFloat(UnicodeString(Name), Value);
    +end;
    +
    +procedure TRegistry.WriteInteger(const Name: UnicodeString; Value: Integer);
    +begin
       PutData(Name, @Value, SizeOf(Integer), rdInteger);
     end;
     
    -procedure TRegistry.WriteInt64(const Name: string; Value: Int64);
    +procedure TRegistry.WriteInteger(const Name: String; Value: Integer);
     begin
    +  WriteInteger(UnicodeString(Name), Value);
    +end;
    +
    +procedure TRegistry.WriteInt64(const Name: UnicodeString; Value: Int64);
    +begin
       PutData(Name, @Value, SizeOf(Int64), rdInt64);
     end;
     
    -procedure TRegistry.WriteString(const Name, Value: string);
    +procedure TRegistry.WriteInt64(const Name: String; Value: Int64);
    +begin
    +  WriteInt64(UnicodeString(Name), Value);
    +end;
    +
    +procedure TRegistry.WriteString(const Name, Value: UnicodeString);
    +begin
    +  PutData(Name, PWideChar(Value), ByteLength(Value), rdString);
    +end;
    +
    +procedure TRegistry.WriteString(const Name, Value: String);
    +begin
    +  WriteString(UnicodeString(Name), UnicodeString(Value));
    +end;
    +
    +procedure TRegistry.GetKeyNames(Strings: TStrings);
     var
    -  u: UnicodeString;
    +  UArr: TUnicodeStringArray;
    +begin
    +  UArr := GetKeyNames;
    +  ArrayToList(UArr, Strings, True);
    +end;
     
    +procedure TRegistry.GetValueNames(Strings: TStrings);
    +var
    +  UArr: TUnicodeStringArray;
     begin
    -  u:=Value;
    -  PutData(Name, PWideChar(u), ByteLength(u), rdString);
    +  UArr := GetValueNames;
    +  ArrayToList(UArr, Strings, True);
     end;
     
    -procedure TRegistry.MoveKey(const OldName, NewName: string; Delete: Boolean);
    +procedure TRegistry.MoveKey(const OldName, NewName: UnicodeString; Delete: Boolean);
     begin
     
     end;
     
    +procedure TRegistry.MoveKey(const OldName, NewName: String; Delete: Boolean);
    +begin
    +  MoveKey(UnicodeString(OldName), UnicodeString(NewName), Delete);
    +end;
    +
    +procedure TRegistry.RenameValue(const OldName, NewName: String);
    +begin
    +  RenameValue(UnicodeString(OldName), UnicodeString(NewName));
    +end;
    +
     { ---------------------------------------------------------------------
         Include TRegIniFile implementation
       ---------------------------------------------------------------------}
    @@ -583,7 +1004,7 @@
       Value: TStream): Integer;
     begin
       result:=-1; // unimplemented
    - // 
    + //
     end;
     
     function TRegistryIniFile.ReadDate(const Section, Name: string;
    Index: packages/fcl-registry/src/winreg.inc
    ===================================================================
    --- packages/fcl-registry/src/winreg.inc	(revision 41749)
    +++ packages/fcl-registry/src/winreg.inc	(working copy)
    @@ -28,7 +28,7 @@
       Dispose(PWinRegData(FSysData));
     end;
     
    -Function PrepKey(Const S : String) : String;
    +Function PrepKey(Const S : UnicodeString) : UnicodeString;
     
     begin
       Result := S;
    @@ -36,7 +36,7 @@
         System.Delete(Result, 1, 1);
     end;
     
    -Function RelativeKey(Const S : String) : Boolean;
    +Function RelativeKey(Const S : UnicodeString) : Boolean;
     
     begin
       Result:=(S='') or (S[1]<>'\')
    @@ -43,9 +43,8 @@
     end;
     
     
    -function TRegistry.sysCreateKey(const Key: String): Boolean;
    +function TRegistry.sysCreateKey(Key: UnicodeString): Boolean;
     Var
    -  u: UnicodeString;
       Disposition: Dword;
       Handle: HKEY;
       SecurityAttributes: Pointer; //LPSECURITY_ATTRIBUTES;
    @@ -52,9 +51,9 @@
     
     begin
       SecurityAttributes := Nil;
    -  u:=PrepKey(Key);
    +  Key:=PrepKey(Key);
       FLastError:=RegCreateKeyExW(GetBaseKey(RelativeKey(Key)),
    -                              PWideChar(u),
    +                              PWideChar(Key),
                                   0,
                                   '',
                                   REG_OPTION_NON_VOLATILE,
    @@ -66,7 +65,7 @@
       RegCloseKey(Handle);
     end;
     
    -function TRegistry.DeleteKey(const Key: String): Boolean;
    +function TRegistry.DeleteKey(const Key: UnicodeString): Boolean;
     
     Var
       u: UnicodeString;
    @@ -76,21 +75,21 @@
       Result:=FLastError=ERROR_SUCCESS;
     end;
     
    -function TRegistry.DeleteValue(const Name: String): Boolean;
    +
    +function TRegistry.DeleteValue(const Name: UnicodeString): Boolean;
     begin
    -  FLastError:= RegDeleteValueW(fCurrentKey, PWideChar(UnicodeString(Name)));
    +  FLastError:= RegDeleteValueW(fCurrentKey, PWideChar(Name));
       Result:=FLastError=ERROR_SUCCESS;
     end;
     
    -function TRegistry.SysGetData(const Name: String; Buffer: Pointer;
    +
    +function TRegistry.SysGetData(const Name: UnicodeString; Buffer: Pointer;
               BufSize: Integer; Out RegData: TRegDataType): Integer;
     Var
    -  u: UnicodeString;
       RD : DWord;
     
     begin
    -  u := Name;
    -  FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(u),Nil,
    +  FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(Name),Nil,
                           @RD,Buffer,lpdword(@BufSize));
       if (FLastError<>ERROR_SUCCESS) Then
         Result:=-1
    @@ -103,17 +102,15 @@
         end;
     end;
     
    -function TRegistry.GetDataInfo(const ValueName: String; out Value: TRegDataInfo): Boolean;
    +function TRegistry.GetDataInfo(const ValueName: UnicodeString; out Value: TRegDataInfo): Boolean;
     
     Var
    -  u: UnicodeString;
       RD : DWord;
     
     begin
    -  u:=ValueName;
       With Value do
         begin
    -    FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(u),Nil,lpdword(@RegData),Nil,lpdword(@DataSize));
    +    FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(ValueName),Nil,lpdword(@RegData),Nil,lpdword(@DataSize));
         Result:=FLastError=ERROR_SUCCESS;
         if Result then
           begin
    @@ -131,24 +128,18 @@
     end;
     
     
    -function TRegistry.GetKey(const Key: String): HKEY;
    +function TRegistry.GetKey(Key: UnicodeString): HKEY;
     var
    -  S : string;
    -{$ifndef WinCE}
    -  u : UnicodeString;
    -{$endif}
       Rel : Boolean;
     begin
       Result:=0;
    -  S:=Key;
    -  Rel:=RelativeKey(S);
    +  Rel:=RelativeKey(Key);
       if not(Rel) then
    -    Delete(S,1,1);
    +    Delete(Key,1,1);
     {$ifdef WinCE}
    -  FLastError:=RegOpenKeyEx(GetBaseKey(Rel),PWideChar(WideString(S)),0,FAccess,Result);
    +  FLastError:=RegOpenKeyEx(GetBaseKey(Rel),PWideChar(Key),0,FAccess,Result);
     {$else WinCE}
    -  u:=UnicodeString(S);
    -  FLastError:=RegOpenKeyExW(GetBaseKey(Rel),PWideChar(u),0,FAccess,Result);
    +  FLastError:=RegOpenKeyExW(GetBaseKey(Rel),PWideChar(Key),0,FAccess,Result);
     {$endif WinCE}
     end;
     
    @@ -174,7 +165,7 @@
     end;
     
     
    -function TRegistry.KeyExists(const Key: string): Boolean;
    +function TRegistry.KeyExists(const Key: UnicodeString): Boolean;
     var
       KeyHandle : HKEY;
       OldAccess : LONG;
    @@ -196,20 +187,20 @@
     end;
     
     
    -function TRegistry.LoadKey(const Key, FileName: string): Boolean;
    +function TRegistry.LoadKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
     
    -function TRegistry.OpenKey(const Key: string; CanCreate: Boolean): Boolean;
     
    +function TRegistry.OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
    +
     Var
    -  u: UnicodeString;
    +  u, S: UnicodeString;
       Handle: HKEY;
       Disposition: Integer;
       SecurityAttributes: Pointer; //LPSECURITY_ATTRIBUTES;
    -  S: string;
     begin
       SecurityAttributes := Nil;
       u:=PrepKey(Key);
    @@ -232,13 +223,14 @@
         if RelativeKey(Key) then
           S:=CurrentPath + Key
         else
    -      S:=UTF8Encode(u);
    +      S:=u;
         ChangeKey(Handle, S);
       end;
     end;
     
    -function TRegistry.OpenKeyReadOnly(const Key: string): Boolean;
     
    +function TRegistry.OpenKeyReadOnly(const Key: UnicodeString): Boolean;
    +
     Var
       OldAccess: LongWord;
     begin
    @@ -251,7 +243,8 @@
       end;
     end;
     
    -function TRegistry.RegistryConnect(const UNCName: string): Boolean;
    +
    +function TRegistry.RegistryConnect(const UNCName: UnicodeString): Boolean;
     {$ifndef WinCE}
     var
       newroot: HKEY;
    @@ -260,7 +253,7 @@
     {$ifdef WinCE}
       Result:=False;
     {$else}
    -  FLastError:=RegConnectRegistryW(PWideChar(UnicodeString(UNCName)),RootKey,newroot);
    +  FLastError:=RegConnectRegistryW(PWideChar(UNCName),RootKey,newroot);
       Result:=FLastError=ERROR_SUCCESS;
       if Result then begin
         RootKey:=newroot;
    @@ -269,28 +262,33 @@
     {$endif}
     end;
     
    -function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
    +
    +function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.RestoreKey(const Key, FileName: string): Boolean;
    +
    +function TRegistry.RestoreKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.SaveKey(const Key, FileName: string): Boolean;
    +
    +function TRegistry.SaveKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.UnLoadKey(const Key: string): Boolean;
    +
    +function TRegistry.UnLoadKey(const Key: UnicodeString): Boolean;
     begin
       Result := false;
     end;
     
    -function TRegistry.ValueExists(const Name: string): Boolean;
     
    +function TRegistry.ValueExists(const Name: UnicodeString): Boolean;
    +
     var
       Info : TRegDataInfo;
     
    @@ -298,6 +296,7 @@
       Result:=GetDataInfo(Name,Info);
     end;
     
    +
     procedure TRegistry.CloseKey;
     begin
       If (CurrentKey<>0) then
    @@ -316,7 +315,7 @@
       RegCloseKey(key);
     end;
     
    -procedure TRegistry.ChangeKey(Value: HKey; const Path: String);
    +procedure TRegistry.ChangeKey(Value: HKey; const Path: UnicodeString);
     begin
       CloseKey;
       FCurrentKey:=Value;
    @@ -323,8 +322,9 @@
       FCurrentPath:=Path;
     end;
     
    -procedure TRegistry.GetKeyNames(Strings: TStrings);
     
    +function TRegistry.GetKeyNames: TUnicodeStringArray;
    +
     var
       Info:    TRegKeyInfo;
       dwLen:   DWORD;
    @@ -331,15 +331,17 @@
       lpName:  LPWSTR;
       dwIndex: DWORD;
       lResult: LONGINT;
    -  s:       string;
    +  u:       UnicodeString;
     
     begin
    -  Strings.Clear;
    +  Result:=nil;
       if GetKeyInfo(Info) then
       begin
         dwLen:=Info.MaxSubKeyLen+1;
         GetMem(lpName,dwLen*SizeOf(WideChar));
         try
    +      //writeln('TRegistry.GetKeyNames: Info.NumSubKeys=',Info.NumSubKeys);
    +      SetLength(Result, Info.NumSubKeys);
           for dwIndex:=0 to Info.NumSubKeys-1 do
           begin
             dwLen:=Info.MaxSubKeyLen+1;
    @@ -347,19 +349,13 @@
             if lResult<>ERROR_SUCCESS then
               raise ERegistryException.Create(SysErrorMessage(lResult));
             if dwLen=0 then
    -          s:=''
    +          u:=''
             else
             begin           // dwLen>0
    -          SetLength(s,dwLen*3);
    -          dwLen:=UnicodeToUTF8(PChar(s),Length(s)+1,lpName,dwLen);
    -          if dwLen<=1 then
    -            s:=''
    -          else          // dwLen>1
    -            SetLength(s,dwLen-1);
    +          u:=lpName;
             end;            // if dwLen=0
    -        Strings.Add(s);
    +        Result[dwIndex]:=u;
           end;              // for dwIndex:=0 ...
    -
         finally
           FreeMem(lpName);
         end;
    @@ -366,8 +362,9 @@
       end;
     end;
     
    -procedure TRegistry.GetValueNames(Strings: TStrings);
     
    +Function TRegistry.GetValueNames: TUnicodeStringArray;
    +
     var
       Info:    TRegKeyInfo;
       dwLen:   DWORD;
    @@ -374,15 +371,16 @@
       lpName:  LPWSTR;
       dwIndex: DWORD;
       lResult: LONGINT;
    -  s:       string;
    +  u:       UnicodeString;
     
     begin
    -   Strings.Clear;
    +  Result:=nil;
       if GetKeyInfo(Info) then
       begin
         dwLen:=Info.MaxValueLen+1;
         GetMem(lpName,dwLen*SizeOf(WideChar));
         try
    +      SetLength(Result, Info.NumValues);
           for dwIndex:=0 to Info.NumValues-1 do
           begin
             dwLen:=Info.MaxValueLen+1;
    @@ -390,17 +388,12 @@
             if lResult<>ERROR_SUCCESS then
               raise ERegistryException.Create(SysErrorMessage(lResult));
             if dwLen=0 then
    -          s:=''
    +          u:=''
             else
             begin           // dwLen>0
    -          SetLength(s,dwLen*3);
    -          dwLen:=UnicodeToUTF8(PChar(s),Length(s)+1,lpName,dwLen);
    -          if dwLen<=1 then
    -            s:=''
    -          else          // dwLen>1
    -            SetLength(s,dwLen-1);
    +          u:=lpName;
             end;            // if dwLen=0
    -        Strings.Add(s);
    +        Result[dwIndex]:=u;
           end;              // for dwIndex:=0 ...
     
         finally
    @@ -410,12 +403,11 @@
     end;
     
     
    -Function TRegistry.SysPutData(const Name: string; Buffer: Pointer;
    +Function TRegistry.SysPutData(const Name: UnicodeString; Buffer: Pointer;
       BufSize: Integer; RegData: TRegDataType) : Boolean;
     
     
     Var
    -  u: UnicodeString;
       RegDataType: DWORD;
       B : Pchar;
       S : String;
    @@ -422,12 +414,11 @@
     
     begin
       RegDataType:=RegDataWords[RegData];
    -  u:=UnicodeString(Name);
    -  FLastError:=RegSetValueExW(fCurrentKey,PWideChar(u),0,RegDataType,Buffer,BufSize);
    +  FLastError:=RegSetValueExW(fCurrentKey,PWideChar(Name),0,RegDataType,Buffer,BufSize);
       Result:=FLastError=ERROR_SUCCESS;
     end;
     
    -procedure TRegistry.RenameValue(const OldName, NewName: string);
    +procedure TRegistry.RenameValue(const OldName, NewName: UnicodeString);
     
     var
       L: Integer;
    Index: packages/fcl-registry/src/xmlreg.pp
    ===================================================================
    --- packages/fcl-registry/src/xmlreg.pp	(revision 41749)
    +++ packages/fcl-registry/src/xmlreg.pp	(working copy)
    @@ -25,6 +25,7 @@
         FTime     : TDateTime;
       end;
     
    +  TUnicodeStringArray = Array of UnicodeString;
     
       { TXmlRegistry }
     
    @@ -33,24 +34,24 @@
         FAutoFlush,
         FDirty : Boolean;
         FFileName : String;
    -    FRootKey : String;
    +    FRootKey : UnicodeString;
         FDocument : TXMLDocument;
         FCurrentElement : TDomElement;
    -    FCurrentKey : String;
    +    FCurrentKey : UnicodeString;
         Procedure SetFileName(Value : String);
       Protected
    -    function DoGetValueData(Name: String; out DataType: TDataType; Var Data; Var DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
    -    function DoSetValueData(Name: String; DataType: TDataType; const Data; DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
    +    function DoGetValueData(Name: UnicodeString; out DataType: TDataType; Var Data; Var DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
    +    function DoSetValueData(Name: UnicodeString; DataType: TDataType; const Data; DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
         Procedure LoadFromStream(S : TStream);
    -    Function  NormalizeKey(KeyPath : String) : String;
    +    Function  NormalizeKey(KeyPath : UnicodeString) : UnicodeString;
         Procedure CreateEmptyDoc;
    -    Function  FindKey (S : String) : TDomElement;
    -    Function  FindSubKey (S : String; N : TDomElement) : TDomElement;
    -    Function  CreateSubKey (S : String; N : TDomElement) : TDomElement;
    -    Function  FindValueKey (S : String) : TDomElement;
    -    Function  CreateValueKey (S : String) : TDomElement;
    +    Function  FindKey (S : UnicodeString) : TDomElement;
    +    Function  FindSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
    +    Function  CreateSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
    +    Function  FindValueKey (S : UnicodeString) : TDomElement;
    +    Function  CreateValueKey (S : UnicodeString) : TDomElement;
         Function  BufToHex(Const Buf; Len : Integer) : String;
    -    Function  hexToBuf(Const Str : String; Var Buf; Var Len : Integer ) : Integer;
    +    Function  HexToBuf(Const Str : UnicodeString; Var Buf; Var Len : Integer ) : Integer;
         Procedure MaybeFlush;
         Property  Document : TXMLDocument Read FDocument;
         Property  Dirty : Boolean Read FDirty write FDirty;
    @@ -57,29 +58,31 @@
       Public
         Constructor Create(AFileName : String);
         Destructor  Destroy;override;
    -    Function  SetKey(KeyPath : String; AllowCreate : Boolean) : Boolean ;
    -    Procedure SetRootKey(Value : String);
    -    Function  DeleteKey(KeyPath : String) : Boolean;
    -    Function  CreateKey(KeyPath : String) : Boolean;
    -    Function  GetValueSize(Name : String) : Integer;
    -    Function  GetValueType(Name : String) : TDataType;
    -    Function  GetValueInfo(Name : String; Out Info : TDataInfo; AsUnicode : Boolean = False) : Boolean;
    +    Function  SetKey(KeyPath : UnicodeString; AllowCreate : Boolean) : Boolean ;
    +    Procedure SetRootKey(Value : UnicodeString);
    +    Function  DeleteKey(KeyPath : UnicodeString) : Boolean;
    +    Function  CreateKey(KeyPath : UnicodeString) : Boolean;
    +    Function  GetValueSize(Name : UnicodeString) : Integer;
    +    Function  GetValueType(Name : UnicodeString) : TDataType;
    +    Function  GetValueInfo(Name : UnicodeString; Out Info : TDataInfo; AsUnicode : Boolean = False) : Boolean;
         Function  GetKeyInfo(Out Info : TKeyInfo) : Boolean;
         Function  EnumSubKeys(List : TStrings) : Integer;
    +    Function  EnumSubKeys: TUnicodeStringArray;
         Function  EnumValues(List : TStrings) : Integer;
    -    Function  KeyExists(KeyPath : String) : Boolean;
    -    Function  ValueExists(ValueName : String) : Boolean;
    -    Function  RenameValue(Const OldName,NewName : String) : Boolean;
    -    Function  DeleteValue(S : String) : Boolean;
    +    Function  EnumValues: TUnicodeStringArray;
    +    Function  KeyExists(KeyPath : UnicodeString) : Boolean;
    +    Function  ValueExists(ValueName : UnicodeString) : Boolean;
    +    Function  RenameValue(Const OldName,NewName : UnicodeString) : Boolean;
    +    Function  DeleteValue(S : UnicodeString) : Boolean;
         Procedure Flush;
         Procedure Load;
    -    Function GetValueData(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
    -    Function SetValueData(Name : String; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
    +    Function GetValueData(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
    +    Function SetValueData(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
         // These interpret the Data buffer as unicode data
    -    Function GetValueDataUnicode(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
    -    Function SetValueDataUnicode(Name : String; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
    +    Function GetValueDataUnicode(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
    +    Function SetValueDataUnicode(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
         Property FileName : String Read FFileName Write SetFileName;
    -    Property RootKey : String Read FRootKey Write SetRootkey;
    +    Property RootKey : UnicodeString Read FRootKey Write SetRootkey;
         Property AutoFlush : Boolean Read FAutoFlush Write FAutoFlush;
       end;
     
    @@ -143,13 +146,13 @@
       end;
     end;
     
    -Function TXmlRegistry.NormalizeKey(KeyPath : String) : String;
    +Function TXmlRegistry.NormalizeKey(KeyPath : UnicodeString) : UnicodeString;
     
     Var
       L : Integer;
     
     begin
    -  Result:=StringReplace(KeyPath,'\','/',[rfReplaceAll]);
    +  Result:=UnicodeStringReplace(KeyPath,'\','/',[rfReplaceAll]);
       L:=Length(Result);
       If (L>0) and (Result[L]<>'/') then
         Result:=Result+'/';
    @@ -157,10 +160,10 @@
         Result:='/' + Result;
     end;
     
    -Function TXmlRegistry.SetKey(KeyPath : String; AllowCreate : Boolean) : boolean;
    +Function TXmlRegistry.SetKey(KeyPath : UnicodeString; AllowCreate : Boolean) : boolean;
     
     Var
    -  SubKey,ResultKey : String;
    +  SubKey,ResultKey : UnicodeString;
       P : Integer;
       Node,Node2 : TDomElement;
     
    @@ -218,7 +221,7 @@
       MaybeFlush;
     end;
     
    -Procedure TXmlRegistry.SetRootKey(Value : String);
    +Procedure TXmlRegistry.SetRootKey(Value : UnicodeString);
     
     begin
       FRootKey:=NormalizeKey(Value);
    @@ -228,7 +231,7 @@
       FCurrentElement:=Nil;
     end;
     
    -Function TXmlRegistry.DeleteKey(KeyPath : String) : Boolean;
    +Function TXmlRegistry.DeleteKey(KeyPath : UnicodeString) : Boolean;
     
     Var
       N : TDomElement;
    @@ -244,10 +247,10 @@
        end;
     end;
     
    -Function TXmlRegistry.CreateKey(KeyPath : String) : Boolean;
    +Function TXmlRegistry.CreateKey(KeyPath : UnicodeString) : Boolean;
     
     Var
    -  SubKey : String;
    +  SubKey : UnicodeString;
       P : Integer;
       Node,Node2 : TDomElement;
     
    @@ -290,7 +293,7 @@
       MaybeFlush;
     end;
     
    -Function TXmlRegistry.DoGetValueData(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer; IsUnicode : Boolean) : Boolean;
    +Function TXmlRegistry.DoGetValueData(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer; IsUnicode : Boolean) : Boolean;
     
     Type
       PCardinal = ^Cardinal;
    @@ -305,22 +308,27 @@
       D : DWord;
       
     begin
    +  //writeln('TXmlRegistry.DoGetValueData: Name=',Name,' IsUnicode=',IsUnicode);
       Node:=FindValueKey(Name);
       Result:=Node<>Nil;
       If Result then
         begin
    +    //writeln('TXmlRegistry.DoGetValueData: Node<>nil');
         DataNode:=Node.FirstChild;
         HasData:=Assigned(DataNode) and (DataNode.NodeType=TEXT_NODE);
    -    ND:=StrToIntDef(Node[Stype],0);
    +    //writeln('TXmlRegistry.DoGetValueData: HasData=',hasdata);
    +    ND:=StrToIntDef(String(Node[Stype]),0);
    +    //writeln('TXmlRegistry.DoGetValueData: ND=',ND);
         Result:=ND<=Ord(High(TDataType));
         If Result then
           begin
           DataType:=TDataType(ND);
    +      //writeln('TXmlRegistry.DoGetValueData: DataType=',DataType);
           NS:=0; // Initialize, for optional nodes.
           Case DataType of
             dtDWORD : begin   // DataNode is required
                       NS:=SizeOf(Cardinal);
    -                  Result:=HasData and TryStrToDWord(DataNode.NodeValue,D) and (DataSize>=NS);
    +                  Result:=HasData and TryStrToDWord(String(DataNode.NodeValue),D) and (DataSize>=NS);
                       if Result then
                         PCardinal(@Data)^:=D;
                       end;
    @@ -329,7 +337,7 @@
                          begin
                          if not IsUnicode then
                            begin
    -                       S:=UTF8Encode(DataNode.NodeValue); // Convert to ansistring
    +                       S:=DataNode.NodeValue; // Convert to ansistring
                            NS:=Length(S);
                            Result:=(DataSize>=NS);
                            if Result then
    @@ -350,8 +358,10 @@
                        if HasData then
                          begin
                          BL:=Length(DataNode.NodeValue);
    +                     //writeln('TXmlRegistry.DoGetValueData: BL=',BL);
                          NS:=BL div 2;
                          Result:=DataSize>=NS;
    +                     //writeln('TXmlRegistry.DoGetValueData: Result=',Result);
                          If Result then
                            // No need to check for -1, We checked NS before calling.
                            NS:=HexToBuf(DataNode.NodeValue,Data,BL);
    @@ -363,7 +373,7 @@
         end;
     end;
     
    -Function TXmlRegistry.DoSetValueData(Name : String; DataType : TDataType; Const Data; DataSize : Integer; IsUnicode : Boolean) : Boolean;
    +Function TXmlRegistry.DoSetValueData(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer; IsUnicode : Boolean) : Boolean;
     
     Type
       PCardinal = ^Cardinal;
    @@ -374,6 +384,7 @@
       SW : UnicodeString;
     
     begin
    +  //writeln('TXmlRegistry.DoSetValueData A: Name=',Name,', DataType=',DataType,', DataSize=',DataSize,', IsUnicode=',IsUnicode);
       Node:=FindValueKey(Name);
       If Node=Nil then
         Node:=CreateValueKey(Name);
    @@ -380,20 +391,20 @@
       Result:=(Node<>Nil);
       If Result then
         begin
    -    Node[SType]:=IntToStr(Ord(DataType));
    +    Node[SType]:=UnicodeString(IntToStr(Ord(DataType)));
         DataNode:=Node.FirstChild;
     
         Case DataType of
    -      dtDWORD : SW:=IntToStr(PCardinal(@Data)^);
    +      dtDWORD : SW:=UnicodeString(IntToStr(PCardinal(@Data)^));
           dtString : begin
                      if IsUnicode then
                        SW:=UnicodeString(PUnicodeChar(@Data))
                      else
                        SW:=UnicodeString(PAnsiChar(@Data));
    -                   //S:=UTF8Encode(SW);
    +                   //S:=SW;
                      end;
    -      dtBinary : SW:=BufToHex(Data,DataSize);
    -      dtStrings : SW:=BufToHex(Data,DataSize);
    +      dtBinary : SW:=UnicodeString(BufToHex(Data,DataSize));
    +      dtStrings : SW:=UnicodeString(BufToHex(Data,DataSize));
         else
           sw:='';
         end;
    @@ -416,29 +427,29 @@
         end;
     end;
     
    -Function TXmlRegistry.SetValueData(Name : String; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
    +Function TXmlRegistry.SetValueData(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
     
     begin
       Result:=DoSetValueData(Name,DataType,Data,DataSize,False);
     end;
     
    -Function TXmlRegistry.GetValueData(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
    +Function TXmlRegistry.GetValueData(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
     
     begin
       Result:=DoGetValueData(Name,DataType,Data,DataSize,False);
     end;
     
    -function TXmlRegistry.GetValueDataUnicode(Name: String; out DataType: TDataType; Var Data; Var DataSize: Integer): Boolean;
    +function TXmlRegistry.GetValueDataUnicode(Name: UnicodeString; out DataType: TDataType; Var Data; Var DataSize: Integer): Boolean;
     begin
       Result:=DoGetValueData(Name,DataType,Data,DataSize,True);
     end;
     
    -function TXmlRegistry.SetValueDataUnicode(Name: String; DataType: TDataType; const Data; DataSize: Integer): Boolean;
    +function TXmlRegistry.SetValueDataUnicode(Name: UnicodeString; DataType: TDataType; const Data; DataSize: Integer): Boolean;
     begin
       Result:=DoSetValueData(Name,DataType,Data,DataSize,True)
     end;
     
    -Function TXmlRegistry.FindSubKey (S : String; N : TDomElement) : TDomElement;
    +Function TXmlRegistry.FindSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
     
     Var
       Node : TDOMNode;
    @@ -451,7 +462,7 @@
         While (Result=Nil) and (Assigned(Node)) do
           begin
           If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SKey) then
    -        If CompareText(TDomElement(Node)[SName],S)=0 then
    +        If UnicodeCompareText(TDomElement(Node)[SName],S)=0 then
               Result:=TDomElement(Node);
           Node:=Node.NextSibling;
           end;
    @@ -458,7 +469,7 @@
         end;
     end;
     
    -Function TXmlRegistry.CreateSubKey (S : String; N : TDomElement) : TDomElement;
    +Function TXmlRegistry.CreateSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
     
     begin
       Result:=FDocument.CreateElement(SKey);
    @@ -468,7 +479,7 @@
       FDirty:=True;
     end;
     
    -Function  TXmlRegistry.FindValueKey (S : String) : TDomElement;
    +Function  TXmlRegistry.FindValueKey (S : UnicodeString) : TDomElement;
     
     Var
       Node : TDOMNode;
    @@ -481,7 +492,7 @@
         While (Result=Nil) and (Assigned(Node)) do
           begin
           If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SValue) then
    -        If CompareText(TDomElement(Node)[SName],S)=0 then
    +        If UnicodeCompareText(TDomElement(Node)[SName],S)=0 then
               Result:=TDomElement(Node);
           Node:=Node.NextSibling;
           end;
    @@ -488,7 +499,7 @@
         end;
     end;
     
    -Function  TXmlRegistry.CreateValueKey (S : String) : TDomElement;
    +Function  TXmlRegistry.CreateValueKey (S : UnicodeString) : TDomElement;
     
     begin
       If Assigned(FCurrentElement) then
    @@ -581,38 +592,47 @@
         end;
     end;
     
    -Function TXMLRegistry.hexToBuf(Const Str : String; Var Buf; Var Len : Integer ) : Integer;
    +Function TXMLRegistry.HexToBuf(Const Str : UnicodeString; Var Buf; Var Len : Integer ) : Integer;
     
     Var
       NLeN,I : Integer;
       P : PByte;
    -  S : String;
    +  S : UnicodeString;
       B : Byte;
       Code : Integer;
     
     begin
    +  //writeln('TXMLRegistry.HexToBuf A: Str=',Str,', Len=',Len);
       Result:=0;
       P:=@Buf;
    +  //writeln('TXMLRegistry.HexToBuf B: (p=nil)=',p=nil);
       NLen:= Length(Str) div 2;
    +  //writeln('TXMLRegistry.HexToBuf C: NLen=',NLen,', SizeOf(TDateTime)=',SizeOf(TDateTime));
       If (NLen>Len) then
         begin
         Len:=NLen;
         Exit(-1);
         end;
    -  For I:=0 to Len-1 do
    +  For I:=0 to NLen-1 do
         begin
    +    //write('TXMLRegistry.HexToBuf: i=',i);
         S:='$'+Copy(Str,(I*2)+1,2);
    +    //write(', S=',S);
         Val(S,B,Code);
    +    //writeln(', Code=',Code);
         If Code<>0 then
    -      begin
    -      Inc(Result);
    -      B:=0;
    +      begin    //This means invalid data in the registry, why continue and increment result? Why not Exit(-1)?
    +      //Inc(Result);   //the whole function only worked because this was called as often as when Code=0, so by change
    +      //B:=0;          //it causes AV's
    +      Exit(-1);
           end;
    +    Inc(Result);
         P[I]:=B;
         end;
    +  //writeln('TXMLRegistry.HexToBuf End: Result=',Result);
     end;
     
    -Function TXMLRegistry.DeleteValue(S : String) : Boolean;
    +Function TXMLRegistry.DeleteValue(S : UnicodeString) : Boolean;
     
     Var
       N : TDomElement;
    @@ -628,31 +648,31 @@
         end;
     end;
     
    -Function TXMLRegistry.GetValueSize(Name : String) : Integer;
    +Function TXMLRegistry.GetValueSize(Name : UnicodeString) : Integer;
     
     Var
       Info : TDataInfo;
     
     begin
    -  If GetValueInfo(Name,Info) then
    +  If GetValueInfo(Name,Info,True) then
         Result:=Info.DataSize
       else
         Result:=-1;
     end;
     
    -Function TXMLRegistry.GetValueType(Name : String) : TDataType;
    +Function TXMLRegistry.GetValueType(Name : UnicodeString) : TDataType;
     
     Var
       Info : TDataInfo;
     
     begin
    -  If GetValueInfo(Name,Info) then
    +  If GetValueInfo(Name,Info,True) then
         Result:=Info.DataType
       else
         Result:=dtUnknown;
     end;
     
    -function TXmlRegistry.GetValueInfo(Name: String; out Info: TDataInfo; AsUnicode: Boolean): Boolean;
    +function TXmlRegistry.GetValueInfo(Name: UnicodeString; out Info: TDataInfo; AsUnicode: Boolean): Boolean;
     
     Var
       N  : TDomElement;
    @@ -671,7 +691,7 @@
             L:=Length(DN.NodeValue)*SizeOf(UnicodeChar)
           else
             begin
    -        S := UTF8Encode(DN.NodeValue);
    +        S := DN.NodeValue;
             L:=Length(S);
             end
           end
    @@ -679,7 +699,7 @@
           L:=0;
         With Info do
           begin
    -      DataType:=TDataType(StrToIntDef(N[SType],0));
    +      DataType:=TDataType(StrToIntDef(String(N[SType]),0));
           Case DataType of
             dtUnknown : DataSize:=0;
             dtDword   : Datasize:=SizeOf(Cardinal);
    @@ -724,10 +744,10 @@
                   ValueLen:=L;
                 DataNode:=TDomElement(Node).FirstChild;
                 If (DataNode<>Nil) and (DataNode is TDomText) then
    -              Case TDataType(StrToIntDef(TDomElement(Node)[SType],0)) of
    +              Case TDataType(StrToIntDef(String(TDomElement(Node)[SType]),0)) of
                     dtUnknown : L:=0;
                     dtDWord   : L:=4;
    -                DtString  : L:=Length(UTF8Encode(DataNode.NodeValue));
    +                DtString  : L:=Length(String(DataNode.NodeValue));
                     dtBinary  : L:=Length(DataNode.NodeValue) div 2;
                   end
                 else
    @@ -761,6 +781,37 @@
         end;
     end;
     
    +function TXmlRegistry.EnumSubKeys: TUnicodeStringArray;
    +
    +Var
    +  Node : TDOMNode;
    +  Len, Count: Integer;
    +
    +begin
    +  Result:=nil;
    +  If FCurrentElement<>Nil then
    +    begin
    +    Node:=FCurrentElement.FirstChild;
    +    Len:=0;
    +    Count:=0;
    +    While Assigned(Node) do
    +      begin
    +      If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SKey) then
    +        begin
    +        Inc(Count);
    +        if (Count>Len) then
    +          begin
    +          Inc(Len,10); //avoid calling SetLength on each addition
    +          SetLength(Result,Len);
    +          end;
    +        Result[Count-1]:=TDomElement(Node)[SName];
    +        end;
    +      Node:=Node.NextSibling;
    +      end;
    +    SetLength(Result,Count);
    +    end;
    +end;
    +
     Function TXMLRegistry.EnumValues(List : TStrings) : Integer;
     
     Var
    @@ -775,7 +826,8 @@
         While Assigned(Node) do
           begin
           If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SValue) then
    -        List.Add(TDomElement(Node)[SName]);
    +        If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SValue) then
    +          List.Add(TDomElement(Node)[SName]);
           Node:=Node.NextSibling;
           end;
         Result:=List.Count;
    @@ -782,13 +834,44 @@
         end;
     end;
     
    -Function TXMLRegistry.KeyExists(KeyPath : String) : Boolean;
    +Function TXMLRegistry.EnumValues: TUnicodeStringArray;
     
    +Var
    +  Node : TDOMNode;
    +  Len, Count: Integer;
     begin
    +  Result:=nil;
    +  If FCurrentElement<>Nil then
    +    begin
    +    Node:=FCurrentElement.FirstChild;
    +    Count:=0;
    +    Len:=0;
    +    While Assigned(Node) do
    +      begin
    +      If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SValue) then
    +        begin
    +        Inc(Count);
    +        if (Count>Len) then
    +          begin
    +          Inc(Len,10); //avoid calling SetLength on each addition
    +          SetLength(Result,Len);
    +          end;
    +        Result[Count-1]:=TDomElement(Node)[SName];
    +        end;
    +      Node:=Node.NextSibling;
    +      end;
    +    SetLength(Result,Count);
    +    end;
    +end;
    +
    +
    +Function TXMLRegistry.KeyExists(KeyPath : UnicodeString) : Boolean;
    +
    +begin
       Result:=FindKey(KeyPath)<>Nil;
     end;
     
    -Function TXMLRegistry.RenameValue(Const OldName,NewName : String) : Boolean;
    +Function TXMLRegistry.RenameValue(Const OldName,NewName : UnicodeString) : Boolean;
     
     Var
       N : TDomElement;
    @@ -804,10 +887,10 @@
         end;
     end;
     
    -Function TXMLRegistry.FindKey (S : String) : TDomElement;
    +Function TXMLRegistry.FindKey (S : UnicodeString) : TDomElement;
     
     Var
    -  SubKey : String;
    +  SubKey : UnicodeString;
       P : Integer;
       Node : TDomElement;
     
    @@ -840,7 +923,7 @@
       Until (Result=Nil) or (Length(S)=0);
     end;
     
    -Function  TXmlRegistry.ValueExists(ValueName : String) : Boolean;
    +Function  TXmlRegistry.ValueExists(ValueName : UnicodeString) : Boolean;
     
     begin
       Result:=FindValueKey(ValueName)<>Nil;
    Index: packages/fcl-registry/src/xregreg.inc
    ===================================================================
    --- packages/fcl-registry/src/xregreg.inc	(revision 41749)
    +++ packages/fcl-registry/src/xregreg.inc	(working copy)
    @@ -116,7 +116,11 @@
     procedure TRegistry.SysRegCreate;
     var s : string;
     begin
    +  FStringSizeIncludesNull:=False;
       s:=includetrailingpathdelimiter(GetAppConfigDir(GlobalXMLFile));
    +  {$ifdef XMLRegfile_in_CurDir}
    +  s:='.' + PathDelim;
    +  {$endif}
       ForceDirectories(s);
       FSysData:=TXMLRegistryInstance.GetXMLRegistry(s+XFileName);
       TXmlRegistry(FSysData).AutoFlush:=False;
    @@ -130,24 +134,24 @@
       TXMLRegistryInstance.FreeXMLRegistry(TXMLRegistry(FSysData));
     end;
     
    -function TRegistry.SysCreateKey(const Key: String): Boolean;
    +function TRegistry.SysCreateKey(Key: UnicodeString): Boolean;
     
     begin
       Result:=TXmlRegistry(FSysData).CreateKey(Key);
     end;
     
    -function TRegistry.DeleteKey(const Key: string): Boolean;
    +function TRegistry.DeleteKey(const Key: UnicodeString): Boolean;
     
     begin
       Result:=TXMLRegistry(FSysData).DeleteKey(Key);
     end;
     
    -function TRegistry.DeleteValue(const Name: string): Boolean;
    +function TRegistry.DeleteValue(const Name: UnicodeString): Boolean;
     begin
       Result:=TXmlRegistry(FSysData).DeleteValue(Name);
     end;
     
    -function TRegistry.SysGetData(const Name: String; Buffer: Pointer;
    +function TRegistry.SysGetData(const Name: UnicodeString; Buffer: Pointer;
               BufSize: Integer; Out RegData: TRegDataType): Integer;
     
     Var
    @@ -160,7 +164,7 @@
         Result:=-1;
     end;
     
    -function TRegistry.GetDataInfo(const ValueName: string; out Value: TRegDataInfo): Boolean;
    +function TRegistry.GetDataInfo(const ValueName: UnicodeString; out Value: TRegDataInfo): Boolean;
     
     Var
       Info : TDataInfo;
    @@ -181,7 +185,7 @@
           end;
     end;
     
    -function TRegistry.GetKey(const Key: string): HKEY;
    +function TRegistry.GetKey(Key: UnicodeString): HKEY;
     begin
       Result := 0;
     end;
    @@ -205,17 +209,17 @@
           end;
     end;
     
    -function TRegistry.KeyExists(const Key: string): Boolean;
    +function TRegistry.KeyExists(const Key: UnicodeString): Boolean;
     begin
       Result:=TXmlRegistry(FSysData).KeyExists(Key);
     end;
     
    -function TRegistry.LoadKey(const Key, FileName: string): Boolean;
    +function TRegistry.LoadKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.OpenKey(const Key: string; CanCreate: Boolean): Boolean;
    +function TRegistry.OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
     
     begin
       Result:=TXmlRegistry(FSysData).SetKey(Key,CanCreate);
    @@ -222,59 +226,59 @@
       FCurrentKey:=1;
     end;
     
    -function TRegistry.OpenKeyReadOnly(const Key: string): Boolean;
    +function TRegistry.OpenKeyReadOnly(const Key: UnicodeString): Boolean;
     
     begin
       Result:=TXmlRegistry(FSysData).SetKey(Key,False);
     end;
     
    -function TRegistry.RegistryConnect(const UNCName: string): Boolean;
    +function TRegistry.RegistryConnect(const UNCName: UnicodeString): Boolean;
     begin
       Result := True;
     end;
     
    -function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
    +function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.RestoreKey(const Key, FileName: string): Boolean;
    +function TRegistry.RestoreKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.SaveKey(const Key, FileName: string): Boolean;
    +function TRegistry.SaveKey(const Key, FileName: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.UnLoadKey(const Key: string): Boolean;
    +function TRegistry.UnLoadKey(const Key: UnicodeString): Boolean;
     begin
       Result := False;
     end;
     
    -function TRegistry.ValueExists(const Name: string): Boolean;
    +function TRegistry.ValueExists(const Name: UnicodeString): Boolean;
     begin
       Result := TXmlRegistry(FSysData).ValueExists(Name);
     end;
     
    -procedure TRegistry.ChangeKey(Value: HKey; const Path: string);
    +procedure TRegistry.ChangeKey(Value: HKey; const Path: UnicodeString);
     begin
     
     end;
     
    -procedure TRegistry.GetKeyNames(Strings: TStrings);
    +function TRegistry.GetKeyNames: TUnicodeStringArray;
     begin
    -  TXmlRegistry(FSysData).EnumSubKeys(Strings);
    +  Result:=TXmlRegistry(FSysData).EnumSubKeys;
     end;
     
    -procedure TRegistry.GetValueNames(Strings: TStrings);
    +function TRegistry.GetValueNames: TUnicodeStringArray;
     begin
    -  TXmlRegistry(FSysData).EnumValues(Strings);
    +  Result := TXmlRegistry(FSysData).EnumValues;
     end;
     
     
    -function TRegistry.SysPutData(const Name: string; Buffer: Pointer;
    +function TRegistry.SysPutData(const Name: UnicodeString; Buffer: Pointer;
       BufSize: Integer; RegData: TRegDataType): Boolean;
     
     Var
    @@ -281,15 +285,18 @@
       DataType : TDataType;
     
     begin
    +  //writeln('TRegistry.SysPutData: Name=',Name,', RegData=',RegData,', BufSize=',BufSize);
       DataType:=RegDataTypeToXmlDataType(RegData);
    +
       Result:=TXMLRegistry(FSysData).SetValueDataUnicode(Name,DataType,Buffer^,BufSize);
     end;
     
    -procedure TRegistry.RenameValue(const OldName, NewName: string);
    +procedure TRegistry.RenameValue(const OldName, NewName: UnicodeString);
     begin
       TXMLRegistry(FSysData).RenameValue(OldName,NewName);
     end;
     
    +
     procedure TRegistry.SetCurrentKey(Value: HKEY);
     begin
       fCurrentKey := Value;
    @@ -298,7 +305,7 @@
     procedure TRegistry.SetRootKey(Value: HKEY);
     
     Var
    -  S: String;
    +  S: UnicodeString;
     
     begin
       If (Value=HKEY_CLASSES_ROOT) then
    @@ -347,3 +354,5 @@
         TXMLRegistry(FSysData).SetRootKey(TXMLRegistry(FSysData).RootKey);
       end;
     end;
    +
    +
    

Relationships

has duplicate 0034876 resolvedMichael Van Canneyt TRegistry's rdMultiString treats Unicode strings as AnsiStrings 

Activities

Bart Broersma

2019-03-10 12:01

reporter  

registry.no-utf8encode.diff (2,444 bytes)
Index: packages/fcl-registry/src/registry.pp
===================================================================
--- packages/fcl-registry/src/registry.pp	(revision 41558)
+++ packages/fcl-registry/src/registry.pp	(working copy)
@@ -421,7 +421,7 @@
       if StringSizeIncludesNull and
          (u[Length(u)] = WideChar(0)) then
         SetLength(u,Length(u)-1);
-      Result:=UTF8Encode(u);
+      Result:=u;
     end;
   end;
 end;
Index: packages/fcl-registry/src/winreg.inc
===================================================================
--- packages/fcl-registry/src/winreg.inc	(revision 41558)
+++ packages/fcl-registry/src/winreg.inc	(working copy)
@@ -232,7 +232,7 @@
     if RelativeKey(Key) then
       S:=CurrentPath + Key
     else
-      S:=UTF8Encode(u);
+      S:=u;
     ChangeKey(Handle, S);
   end;
 end;
Index: packages/fcl-registry/src/xmlreg.pp
===================================================================
--- packages/fcl-registry/src/xmlreg.pp	(revision 41558)
+++ packages/fcl-registry/src/xmlreg.pp	(working copy)
@@ -329,7 +329,7 @@
                      begin
                      if not IsUnicode then
                        begin
-                       S:=UTF8Encode(DataNode.NodeValue); // Convert to ansistring
+                       S:=DataNode.NodeValue; // Convert to ansistring
                        NS:=Length(S);
                        Result:=(DataSize>=NS);
                        if Result then
@@ -390,7 +390,7 @@
                    SW:=UnicodeString(PUnicodeChar(@Data))
                  else
                    SW:=UnicodeString(PAnsiChar(@Data));
-                   //S:=UTF8Encode(SW);
+                   //S:=SW;
                  end;
       dtBinary : SW:=BufToHex(Data,DataSize);
       dtStrings : SW:=BufToHex(Data,DataSize);
@@ -671,7 +671,7 @@
         L:=Length(DN.NodeValue)*SizeOf(UnicodeChar)
       else
         begin
-        S := UTF8Encode(DN.NodeValue);
+        S := DN.NodeValue;
         L:=Length(S);
         end
       end
@@ -727,7 +727,7 @@
               Case TDataType(StrToIntDef(TDomElement(Node)[SType],0)) of
                 dtUnknown : L:=0;
                 dtDWord   : L:=4;
-                DtString  : L:=Length(UTF8Encode(DataNode.NodeValue));
+                DtString  : L:=Length(String(DataNode.NodeValue));
                 dtBinary  : L:=Length(DataNode.NodeValue) div 2;
               end
             else

Bart Broersma

2019-03-10 12:11

reporter   ~0114766

Note: applying this patch will invalidate the patch for 0035022.
So, if at all possible please apply patch from 0035022 first.

Michael Van Canneyt

2019-03-10 12:11

administrator   ~0114767

Last edited: 2019-03-10 12:13

View 2 revisions

This patch will not be applied as-is. It results in manifestly wrong data.
The current behaviour is the result of a bugreport fix, it is there for a reason.

I understand & endorse the need for proper unicode support, so the patch
will only be applied in combination with an actual unicode support patch.

The use case of a non-lazarus command-line application is so minor that this can wait for a proper solution for unicode.

Splitting up this issue is actually doing more damage than good: a single patch that solves the whole encoding issue is best.

Bart Broersma

2019-03-10 23:08

reporter   ~0114782

> The use case of a non-lazarus command-line application is so minor that this can wait for a proper solution for unicode.

Utf8Encode is superfluous in Lazarus, so removing it will not harm.

Bart Broersma

2019-03-10 23:17

reporter   ~0114783

> The current behaviour is the result of a bugreport fix, it is there for a reason.

That fix for 0032185 did introduce a regression.
It would only work if input strings were UTF8 encoded (which they are on Lazarus, but not in plain fpc programs, so in the latter case it resulted in manifest wrong data).

Bart Broersma

2019-03-11 18:53

reporter   ~0114791

Related to 0034876

Bart Broersma

2019-03-13 14:02

reporter   ~0114813

Last edited: 2019-03-13 14:05

View 2 revisions

As discussed on the fpc-devel ML: we strive now to create a single patchfile that resolves all TRegistry unicode issues.
This patch must then also include the fix for issue 0034876.

The idea is to overload all public/protected methods with string variables to have a counterpart with unicodestring parameters.
Private methods will have unicode string parameters only.

Michael Van Canneyt

2019-03-13 14:24

administrator   ~0114816

Do not forget to check patches attached to 0034876

Bart Broersma

2019-03-13 17:45

reporter  

registry.unicode.part1.diff (37,734 bytes)
Index: packages/fcl-registry/src/regdef.inc
===================================================================
--- packages/fcl-registry/src/regdef.inc	(revision 41667)
+++ packages/fcl-registry/src/regdef.inc	(working copy)
@@ -2,7 +2,7 @@
   HKEY = THandle;
   PHKEY = ^HKEY;
   
-{$ifdef windows}
+{$if defined(windows) and not defined(XMLREG)}
 
 { Direct mapping to constants in Windows unit }
 
Index: packages/fcl-registry/src/registry.pp
===================================================================
--- packages/fcl-registry/src/registry.pp	(revision 41667)
+++ packages/fcl-registry/src/registry.pp	(working copy)
@@ -54,22 +54,28 @@
     fCurrentKey: HKEY;
     fRootKey: HKEY;
     fLazyWrite: Boolean;
-    fCurrentPath: string;
+    fCurrentPath: UnicodeString;
     function GetLastErrorMsg: string;
     procedure SetRootKey(Value: HKEY);
     Procedure SysRegCreate;
     Procedure SysRegFree;
-    Function  SysGetData(const Name: String; Buffer: Pointer; BufSize: Integer; Out RegData: TRegDataType): Integer;
-    Function  SysPutData(const Name: string; Buffer: Pointer; BufSize: Integer; RegData: TRegDataType) : Boolean;
-    Function  SysCreateKey(const Key: String): Boolean;
+    Function  SysGetData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; Out RegData: TRegDataType): Integer;
+    Function  SysPutData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; RegData: TRegDataType) : Boolean;
+    Function  SysCreateKey(Key: UnicodeString): Boolean;
   protected
     function GetBaseKey(Relative: Boolean): HKey;
-    function GetData(const Name: string; Buffer: Pointer;
+    function GetData(const Name: UnicodeString; Buffer: Pointer;
                   BufSize: Integer; Out RegData: TRegDataType): Integer;
-    function GetKey(const Key: string): HKEY;
-    procedure ChangeKey(Value: HKey; const Path: string);
-    procedure PutData(const Name: string; Buffer: Pointer;
+    function GetData(const Name: String; Buffer: Pointer;
+                  BufSize: Integer; Out RegData: TRegDataType): Integer;
+    function GetKey(Key: UnicodeString): HKEY;
+    function GetKey(Key: String): HKEY;
+    procedure ChangeKey(Value: HKey; const Path: UnicodeString);
+    procedure ChangeKey(Value: HKey; const Path: String);
+    procedure PutData(const Name: UnicodeString; Buffer: Pointer;
                   BufSize: Integer; RegData: TRegDataType);
+    procedure PutData(const Name: String; Buffer: Pointer;
+                  BufSize: Integer; RegData: TRegDataType);
     procedure SetCurrentKey(Value: HKEY);
   public
     constructor Create; overload;
@@ -76,58 +82,85 @@
     constructor Create(aaccess:longword); overload;
     destructor Destroy; override;
 
-    function CreateKey(const Key: string): Boolean;
-    function DeleteKey(const Key: string): Boolean;
-    function DeleteValue(const Name: string): Boolean;
-    function GetDataInfo(const ValueName: string; Out Value: TRegDataInfo): Boolean;
-    function GetDataSize(const ValueName: string): Integer;
-    function GetDataType(const ValueName: string): TRegDataType;
+    function CreateKey(const Key: UnicodeString): Boolean;
+    function CreateKey(const Key: String): Boolean;
+    function DeleteKey(const Key: UnicodeString): Boolean;
+    function DeleteKey(const Key: String): Boolean;
+    function DeleteValue(const Name: UnicodeString): Boolean;
+    function DeleteValue(const Name: String): Boolean;
+    function GetDataInfo(const ValueName: UnicodeString; Out Value: TRegDataInfo): Boolean;
+    function GetDataInfo(const ValueName: String; Out Value: TRegDataInfo): Boolean;
+    function GetDataSize(const ValueName: UnicodeString): Integer;
+    function GetDataSize(const ValueName: String): Integer;
+    function GetDataType(const ValueName: UnicodeString): TRegDataType;
+    function GetDataType(const ValueName: String): TRegDataType;
     function GetKeyInfo(Out Value: TRegKeyInfo): Boolean;
     function HasSubKeys: Boolean;
-    function KeyExists(const Key: string): Boolean;
-    function LoadKey(const Key, FileName: string): Boolean;
-    function OpenKey(const Key: string; CanCreate: Boolean): Boolean;
-    function OpenKeyReadOnly(const Key: string): Boolean;
-    function ReadCurrency(const Name: string): Currency;
-    function ReadBinaryData(const Name: string; var Buffer; BufSize: Integer): Integer;
-    function ReadBool(const Name: string): Boolean;
-    function ReadDate(const Name: string): TDateTime;
-    function ReadDateTime(const Name: string): TDateTime;
-    function ReadFloat(const Name: string): Double;
-    function ReadInteger(const Name: string): Integer;
-    function ReadInt64(const Name: string): Int64;
-    function ReadString(const Name: string): string;
-    procedure ReadStringList(const Name: string; AList: TStrings);
-    function ReadTime(const Name: string): TDateTime;
-    function RegistryConnect(const UNCName: string): Boolean;
-    function ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
-    function RestoreKey(const Key, FileName: string): Boolean;
-    function SaveKey(const Key, FileName: string): Boolean;
-    function UnLoadKey(const Key: string): Boolean;
-    function ValueExists(const Name: string): Boolean;
+    function KeyExists(const Key: UnicodeString): Boolean;
+    function KeyExists(const Key: String): Boolean;
+    function LoadKey(const Key, FileName: UnicodeString): Boolean;
+    function LoadKey(const Key, FileName: String): Boolean;
+    function OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
+    function OpenKey(const Key: String; CanCreate: Boolean): Boolean;
+    function OpenKeyReadOnly(const Key: UnicodeString): Boolean;
+    function OpenKeyReadOnly(const Key: String): Boolean;
+    function ReadCurrency(const Name: UnicodeString): Currency;
+    function ReadCurrency(const Name: String): Currency;
+    function ReadBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer): Integer;
+    function ReadBinaryData(const Name: String; var Buffer; BufSize: Integer): Integer;
+    function ReadBool(const Name: UnicodeString): Boolean;
+    function ReadBool(const Name: String): Boolean;
+    function ReadDate(const Name: UnicodeString): TDateTime;
+    function ReadDate(const Name: String): TDateTime;
+    function ReadDateTime(const Name: UnicodeString): TDateTime;
+    function ReadDateTime(const Name: String): TDateTime;
+    function ReadFloat(const Name: UnicodeString): Double;
+    function ReadFloat(const Name: String): Double;
+    function ReadInteger(const Name: UnicodeString): Integer;
+    function ReadInteger(const Name: String): Integer;
+    function ReadInt64(const Name: UnicodeString): Int64;
+    function ReadInt64(const Name: String): Int64;
+    function ReadString(const Name: UnicodeString): string;
+    function ReadString(const Name: String): string;
+    procedure ReadStringList(const Name: UnicodeString; AList: TStrings);
+    procedure ReadStringList(const Name: String; AList: TStrings);
+    function ReadTime(const Name: UnicodeString): TDateTime;
+    function ReadTime(const Name: String): TDateTime;
+    function RegistryConnect(const UNCName: UnicodeString): Boolean;
+    function RegistryConnect(const UNCName: String): Boolean;
+    function ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
+    function ReplaceKey(const Key, FileName, BackUpFileName: String): Boolean;
+    function RestoreKey(const Key, FileName: UnicodeString): Boolean;
+    function RestoreKey(const Key, FileName: String): Boolean;
+    function SaveKey(const Key, FileName: UnicodeString): Boolean;
+    function SaveKey(const Key, FileName: String): Boolean;
+    function UnLoadKey(const Key: UnicodeString): Boolean;
+    function UnLoadKey(const Key: String): Boolean;
+    function ValueExists(const Name: UnicodeString): Boolean;
+    function ValueExists(const Name: String): Boolean;
 
     procedure CloseKey;
     procedure CloseKey(key:HKEY);
     procedure GetKeyNames(Strings: TStrings);
     procedure GetValueNames(Strings: TStrings);
-    procedure MoveKey(const OldName, NewName: string; Delete: Boolean);
-    procedure RenameValue(const OldName, NewName: string);
-    procedure WriteCurrency(const Name: string; Value: Currency);
-    procedure WriteBinaryData(const Name: string; var Buffer; BufSize: Integer);
-    procedure WriteBool(const Name: string; Value: Boolean);
-    procedure WriteDate(const Name: string; Value: TDateTime);
-    procedure WriteDateTime(const Name: string; Value: TDateTime);
-    procedure WriteFloat(const Name: string; Value: Double);
-    procedure WriteInteger(const Name: string; Value: Integer);
-    procedure WriteInt64(const Name: string; Value: Int64);
-    procedure WriteString(const Name, Value: string);
-    procedure WriteExpandString(const Name, Value: string);
-    procedure WriteStringList(const Name: string; List: TStrings);
-    procedure WriteTime(const Name: string; Value: TDateTime);
+    procedure MoveKey(const OldName, NewName: UnicodeString; Delete: Boolean);
+    procedure RenameValue(const OldName, NewName: UnicodeString);
+    procedure WriteCurrency(const Name: UnicodeString; Value: Currency);
+    procedure WriteBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer);
+    procedure WriteBool(const Name: UnicodeString; Value: Boolean);
+    procedure WriteDate(const Name: UnicodeString; Value: TDateTime);
+    procedure WriteDateTime(const Name: UnicodeString; Value: TDateTime);
+    procedure WriteFloat(const Name: UnicodeString; Value: Double);
+    procedure WriteInteger(const Name: UnicodeString; Value: Integer);
+    procedure WriteInt64(const Name: UnicodeString; Value: Int64);
+    procedure WriteString(const Name, Value: UnicodeString);
+    procedure WriteExpandString(const Name, Value: UnicodeString);
+    procedure WriteStringList(const Name: UnicodeString; List: TStrings);
+    procedure WriteTime(const Name: UnicodeString; Value: TDateTime);
 
     property Access: LongWord read fAccess write fAccess;
     property CurrentKey: HKEY read fCurrentKey;
-    property CurrentPath: string read fCurrentPath;
+    property CurrentPath: UnicodeString read fCurrentPath;
     property LazyWrite: Boolean read fLazyWrite write fLazyWrite;
     property RootKey: HKEY read fRootKey write SetRootKey;
     Property StringSizeIncludesNull : Boolean read FStringSizeIncludesNull;
@@ -261,7 +294,7 @@
   inherited Destroy;
 end;
 
-function TRegistry.CreateKey(const Key: string): Boolean;
+function TRegistry.CreateKey(const Key: UnicodeString): Boolean;
 
 begin
   Result:=SysCreateKey(Key);
@@ -269,6 +302,27 @@
     Raise ERegistryException.CreateFmt(SRegCreateFailed, [Key]);
 end;
 
+function TRegistry.CreateKey(const Key: String): Boolean;
+begin
+  Result:=CreateKey(UnicodeString(Key));
+end;
+
+function TRegistry.DeleteKey(const Key: String): Boolean;
+begin
+  Result:=DeleteKey(UnicodeString(Key));
+end;
+
+function TRegistry.DeleteValue(const Name: String): Boolean;
+begin
+  Result:=DeleteValue(UnicodeString(Name));
+end;
+
+function TRegistry.GetDataInfo(const ValueName: String; out Value: TRegDataInfo
+  ): Boolean;
+begin
+  Result:=GetDataInfo(UnicodeString(ValueName), Value);
+end;
+
 function TRegistry.GetBaseKey(Relative: Boolean): HKey;
 begin
   If Relative and (CurrentKey<>0) Then
@@ -277,7 +331,7 @@
     Result := RootKey;
 end;
 
-function TRegistry.GetData(const Name: string; Buffer: Pointer; BufSize: Integer; out RegData: TRegDataType): Integer;
+function TRegistry.GetData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; out RegData: TRegDataType): Integer;
 begin
   Result:=SysGetData(Name,Buffer,BufSize,RegData);
   If (Result=-1) then
@@ -284,7 +338,24 @@
     Raise ERegistryException.CreateFmt(SRegGetDataFailed, [Name]);
 end;
 
-procedure TRegistry.PutData(const Name: string; Buffer: Pointer;
+function TRegistry.GetData(const Name: String; Buffer: Pointer;
+  BufSize: Integer; out RegData: TRegDataType): Integer;
+begin
+  Result:=GetData(UnicodeString(Name), Buffer, BufSize, RegData);
+end;
+
+function TRegistry.GetKey(Key: String): HKEY;
+begin
+  Result:=GetKey(UnicodeString(Key));
+end;
+
+procedure TRegistry.ChangeKey(Value: HKey; const Path: String);
+begin
+  ChangeKey(Value, UnicodeString(Path));
+end;
+
+
+procedure TRegistry.PutData(const Name: UnicodeString; Buffer: Pointer;
   BufSize: Integer; RegData: TRegDataType);
 
 begin
@@ -292,9 +363,15 @@
     Raise ERegistryException.CreateFmt(SRegSetDataFailed, [Name]);
 end;
 
+procedure TRegistry.PutData(const Name: String; Buffer: Pointer;
+  BufSize: Integer; RegData: TRegDataType);
+begin
+  PutData(UnicodeString(Name), Buffer, BufSize, RegData);
+end;
 
-function TRegistry.GetDataSize(const ValueName: string): Integer;
 
+function TRegistry.GetDataSize(const ValueName: UnicodeString): Integer;
+
 Var
   Info: TRegDataInfo;
 
@@ -305,8 +382,13 @@
     Result := -1;
 end;
 
-function TRegistry.GetDataType(const ValueName: string): TRegDataType;
+function TRegistry.GetDataSize(const ValueName: String): Integer;
+begin
+  Result:=GetDataSize(UnicodeString(ValueName));
+end;
 
+function TRegistry.GetDataType(const ValueName: UnicodeString): TRegDataType;
+
 Var
   Info: TRegDataInfo;
 
@@ -315,6 +397,32 @@
   Result:=Info.RegData;
 end;
 
+function TRegistry.GetDataType(const ValueName: String): TRegDataType;
+begin
+  Result:=GetDataType(UnicodeString(ValueName));
+end;
+
+
+function TRegistry.KeyExists(const Key: String): Boolean;
+begin
+  Result:=KeyExists(UnicodeString(Key));
+end;
+
+function TRegistry.LoadKey(const Key, FileName: String): Boolean;
+begin
+  Result:=LoadKey(UnicodeString(Key), UnicodeString(FileName));
+end;
+
+function TRegistry.OpenKey(const Key: String; CanCreate: Boolean): Boolean;
+begin
+  Result:=OpenKey(UnicodeString(Key), CanCreate);
+end;
+
+function TRegistry.OpenKeyReadOnly(const Key: String): Boolean;
+begin
+  Result:=OpenKeyReadOnly(UnicodeString(Key));
+end;
+
 function TRegistry.HasSubKeys: Boolean;
 
 Var
@@ -326,7 +434,7 @@
     Result:=(Info.NumSubKeys>0);
 end;
 
-function TRegistry.ReadBinaryData(const Name: string; var Buffer; BufSize: Integer): Integer;
+function TRegistry.ReadBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer): Integer;
 
 Var
   RegDataType: TRegDataType;
@@ -337,8 +445,14 @@
     Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
 end;
 
-function TRegistry.ReadInteger(const Name: string): Integer;
+function TRegistry.ReadBinaryData(const Name: String; var Buffer;
+  BufSize: Integer): Integer;
+begin
+  Result:=ReadBinaryData(UnicodeString(Name), Buffer, BufSize);
+end;
 
+function TRegistry.ReadInteger(const Name: UnicodeString): Integer;
+
 Var
   RegDataType: TRegDataType;
 
@@ -348,8 +462,13 @@
     Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
 end;
 
-function TRegistry.ReadInt64(const Name: string): Int64;
+function TRegistry.ReadInteger(const Name: String): Integer;
+begin
+  Result:=ReadInteger(UnicodeString(Name));
+end;
 
+function TRegistry.ReadInt64(const Name: UnicodeString): Int64;
+
 Var
   RegDataType: TRegDataType;
 
@@ -359,21 +478,36 @@
     Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
 end;
 
-function TRegistry.ReadBool(const Name: string): Boolean;
+function TRegistry.ReadInt64(const Name: String): Int64;
+begin
+  Result:=ReadInt64(UnicodeString(Name));
+end;
 
+function TRegistry.ReadBool(const Name: UnicodeString): Boolean;
+
 begin
   Result:=ReadInteger(Name)<>0;
 end;
 
-function TRegistry.ReadCurrency(const Name: string): Currency;
+function TRegistry.ReadBool(const Name: String): Boolean;
+begin
+  Result:=ReadBool(UnicodeString(Name));
+end;
 
+function TRegistry.ReadCurrency(const Name: UnicodeString): Currency;
+
 begin
   Result:=Default(Currency);
   ReadBinaryData(Name, Result, SizeOf(Currency));
 end;
 
-function TRegistry.ReadDate(const Name: string): TDateTime;
+function TRegistry.ReadCurrency(const Name: String): Currency;
+begin
+  Result:=ReadCurrency(UnicodeString(Name));
+end;
 
+function TRegistry.ReadDate(const Name: UnicodeString): TDateTime;
+
 begin
   Result:=Default(TDateTime);
   ReadBinaryData(Name, Result, SizeOf(TDateTime));
@@ -380,22 +514,37 @@
   Result:=Trunc(Result);
 end;
 
-function TRegistry.ReadDateTime(const Name: string): TDateTime;
+function TRegistry.ReadDate(const Name: String): TDateTime;
+begin
+  Result:=ReadDate(UnicodeString(Name));
+end;
 
+function TRegistry.ReadDateTime(const Name: UnicodeString): TDateTime;
+
 begin
   Result:=Default(TDateTime);
   ReadBinaryData(Name, Result, SizeOf(TDateTime));
 end;
 
-function TRegistry.ReadFloat(const Name: string): Double;
+function TRegistry.ReadDateTime(const Name: String): TDateTime;
+begin
+  Result:=ReadDateTime(UnicodeString(Name));
+end;
 
+function TRegistry.ReadFloat(const Name: UnicodeString): Double;
+
 begin
   Result:=Default(Double);
   ReadBinaryData(Name,Result,SizeOf(Double));
 end;
 
-function TRegistry.ReadString(const Name: string): string;
+function TRegistry.ReadFloat(const Name: String): Double;
+begin
+  Result:=ReadFloat(UnicodeString(Name));
+end;
 
+function TRegistry.ReadString(const Name: UnicodeString): string;
+
 Var
   Info : TRegDataInfo;
   ReadDataSize: Integer;
@@ -421,17 +570,22 @@
       if StringSizeIncludesNull and
          (u[Length(u)] = WideChar(0)) then
         SetLength(u,Length(u)-1);
-      Result:=UTF8Encode(u);
+      Result:=u;
     end;
   end;
 end;
 
-procedure TRegistry.ReadStringList(const Name: string; AList: TStrings);
+function TRegistry.ReadString(const Name: String): string;
+begin
+  Result:=ReadString(UnicodeString(Name));
+end;
 
+procedure TRegistry.ReadStringList(const Name: UnicodeString; AList: TStrings);
+
 Var
   Info : TRegDataInfo;
-  ReadDataSize: Integer;
-  Data: string;
+  ReadDataSize, i: Integer;
+  Data: UnicodeString;
 
 begin
   AList.Clear;
@@ -441,7 +595,7 @@
      If Not (Info.RegData in [rdMultiString]) then
        Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
      SetLength(Data,Info.DataSize);
-     ReadDataSize := GetData(Name,PChar(Data),Info.DataSize,Info.RegData);
+     ReadDataSize := GetData(Name,PWideChar(Data),Info.DataSize,Info.RegData) div SizeOf(WideChar);
      if ReadDataSize > 0 then
      begin
        // If the data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type,
@@ -454,14 +608,19 @@
            Dec(ReadDataSize);
        end;
        SetLength(Data, ReadDataSize);
-       Data := StringReplace(Data, #0, LineEnding, [rfReplaceAll]);
+       Data := UnicodeStringReplace(Data, #0, AList.LineBreak, [rfReplaceAll]);
        AList.Text := Data;
      end
    end
 end;
 
-function TRegistry.ReadTime(const Name: string): TDateTime;
+procedure TRegistry.ReadStringList(const Name: String; AList: TStrings);
+begin
+  ReadStringList(UnicodeString(Name), AList);
+end;
 
+function TRegistry.ReadTime(const Name: UnicodeString): TDateTime;
+
 begin
   Result:=Default(TDateTime);
   ReadBinaryData(Name, Result, SizeOf(TDateTime));
@@ -468,81 +627,123 @@
   Result:=Frac(Result);
 end;
 
-procedure TRegistry.WriteBinaryData(const Name: string; var Buffer; BufSize: Integer);
+function TRegistry.ReadTime(const Name: String): TDateTime;
 begin
+  Result:=ReadTime(UnicodeString(Name));
+end;
+
+function TRegistry.RegistryConnect(const UNCName: String): Boolean;
+begin
+  Result:=RegistryConnect(UnicodeString(UNCName));
+end;
+
+function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: String): Boolean;
+begin
+  Result:=ReplaceKey(UnicodeString(Key), UnicodeString(FileName), UnicodeString(BackUpFileName))
+end;
+
+function TRegistry.RestoreKey(const Key, FileName: String): Boolean;
+begin
+  Result:=RestoreKey(UnicodeString(Key), UnicodeString(FileName));
+end;
+
+function TRegistry.SaveKey(const Key, FileName: String): Boolean;
+begin
+  Result:=SaveKey(UnicodeString(Key), UnicodeString(FileName));
+end;
+
+function TRegistry.UnLoadKey(const Key: String): Boolean;
+begin
+  Result:=UnloadKey(UnicodeString(Key));
+end;
+
+function TRegistry.ValueExists(const Name: String): Boolean;
+begin
+  Result:=ValueExists(UnicodeString(Name));
+end;
+
+procedure TRegistry.WriteBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer);
+begin
   PutData(Name, @Buffer, BufSize, rdBinary);
 end;
 
-procedure TRegistry.WriteBool(const Name: string; Value: Boolean);
+procedure TRegistry.WriteBool(const Name: UnicodeString; Value: Boolean);
 
 begin
   WriteInteger(Name,Ord(Value));
 end;
 
-procedure TRegistry.WriteCurrency(const Name: string; Value: Currency);
+procedure TRegistry.WriteCurrency(const Name: UnicodeString; Value: Currency);
 begin
   WriteBinaryData(Name, Value, SizeOf(Currency));
 end;
 
-procedure TRegistry.WriteDate(const Name: string; Value: TDateTime);
+procedure TRegistry.WriteDate(const Name: UnicodeString; Value: TDateTime);
 begin
   WriteBinarydata(Name, Value, SizeOf(TDateTime));
 end;
 
-procedure TRegistry.WriteTime(const Name: string; Value: TDateTime);
+procedure TRegistry.WriteTime(const Name: UnicodeString; Value: TDateTime);
 begin
   WriteBinaryData(Name, Value, SizeOf(TDateTime));
 end;
 
-procedure TRegistry.WriteDateTime(const Name: string; Value: TDateTime);
+procedure TRegistry.WriteDateTime(const Name: UnicodeString; Value: TDateTime);
 begin
   WriteBinaryData(Name, Value, SizeOf(TDateTime));
 end;
 
-procedure TRegistry.WriteExpandString(const Name, Value: string);
-var
-  u: UnicodeString;
-
+procedure TRegistry.WriteExpandString(const Name, Value: UnicodeString);
 begin
-  u:=Value;
-  PutData(Name, PWideChar(u), ByteLength(u), rdExpandString);
+  PutData(Name, PWideChar(Value), ByteLength(Value), rdExpandString);
 end;
 
-procedure TRegistry.WriteStringList(const Name: string; List: TStrings);
+procedure TRegistry.WriteStringList(const Name: UnicodeString; List: TStrings);
 
 Var
-  Data: string;
-
+  Data: UnicodeString;
+  u: UnicodeString;
+  i: Integer;
 begin
-  Data := StringReplace(List.Text, LineEnding, #0, [rfReplaceAll]) + #0#0;
-  PutData(Name, PChar(Data), Length(Data),rdMultiString);
+  Data := '';
+  //REG_MULTI_SZ data cannot contain empty strings
+  for i := 0 to List.Count - 1 do
+  begin
+    u := List[i];
+    if (u>'') then
+    begin
+      if (Data>'') then
+        Data := Data + #0 + u
+      else
+        Data := Data + u;
+    end;
+  end;
+  if StringSizeIncludesNull then
+    Data := Data + #0#0;
+  PutData(Name, PWideChar(Data), ByteLength(Data), rdMultiString);
 end;
 
-procedure TRegistry.WriteFloat(const Name: string; Value: Double);
+procedure TRegistry.WriteFloat(const Name: UnicodeString; Value: Double);
 begin
   WriteBinaryData(Name, Value, SizeOf(Double));
 end;
 
-procedure TRegistry.WriteInteger(const Name: string; Value: Integer);
+procedure TRegistry.WriteInteger(const Name: UnicodeString; Value: Integer);
 begin
   PutData(Name, @Value, SizeOf(Integer), rdInteger);
 end;
 
-procedure TRegistry.WriteInt64(const Name: string; Value: Int64);
+procedure TRegistry.WriteInt64(const Name: UnicodeString; Value: Int64);
 begin
   PutData(Name, @Value, SizeOf(Int64), rdInt64);
 end;
 
-procedure TRegistry.WriteString(const Name, Value: string);
-var
-  u: UnicodeString;
-
+procedure TRegistry.WriteString(const Name, Value: UnicodeString);
 begin
-  u:=Value;
-  PutData(Name, PWideChar(u), ByteLength(u), rdString);
+  PutData(Name, PWideChar(Value), ByteLength(Value), rdString);
 end;
 
-procedure TRegistry.MoveKey(const OldName, NewName: string; Delete: Boolean);
+procedure TRegistry.MoveKey(const OldName, NewName: UnicodeString; Delete: Boolean);
 begin
 
 end;
Index: packages/fcl-registry/src/winreg.inc
===================================================================
--- packages/fcl-registry/src/winreg.inc	(revision 41667)
+++ packages/fcl-registry/src/winreg.inc	(working copy)
@@ -1,7 +1,7 @@
 Const
   RegDataWords : Array [TRegDataType] of DWORD
                = (REG_NONE,REG_SZ,REG_EXPAND_SZ,REG_BINARY,REG_DWORD,REG_DWORD_BIG_ENDIAN,
-                  REG_LINK,REG_MULTI_SZ,REG_RESOURCE_LIST,REG_FULL_RESOURCE_DESCRIPTOR,REG_RESOURCE_REQUIREMENTS_LIST,REG_QWORD);
+                  REG_LINK,REG_MULTI_SZ,REG_RESOURCE_LIST,REG_FULL_RESOURCE_DESCRIPTOR,REG_RESOURCE_REQUIREMENTS_LIST,11{REG_QWORD}); //*****UNDO THIS!
 
 type
   TWinRegData = record
@@ -28,7 +28,7 @@
   Dispose(PWinRegData(FSysData));
 end;
 
-Function PrepKey(Const S : String) : String;
+Function PrepKey(Const S : UnicodeString) : UnicodeString;
 
 begin
   Result := S;
@@ -36,7 +36,7 @@
     System.Delete(Result, 1, 1);
 end;
 
-Function RelativeKey(Const S : String) : Boolean;
+Function RelativeKey(Const S : UnicodeString) : Boolean;
 
 begin
   Result:=(S='') or (S[1]<>'\')
@@ -43,7 +43,7 @@
 end;
 
 
-function TRegistry.sysCreateKey(const Key: String): Boolean;
+function TRegistry.sysCreateKey(Key: UnicodeString): Boolean;
 Var
   u: UnicodeString;
   Disposition: Dword;
@@ -52,9 +52,9 @@
 
 begin
   SecurityAttributes := Nil;
-  u:=PrepKey(Key);
+  Key:=PrepKey(Key);
   FLastError:=RegCreateKeyExW(GetBaseKey(RelativeKey(Key)),
-                              PWideChar(u),
+                              PWideChar(Key),
                               0,
                               '',
                               REG_OPTION_NON_VOLATILE,
@@ -66,7 +66,7 @@
   RegCloseKey(Handle);
 end;
 
-function TRegistry.DeleteKey(const Key: String): Boolean;
+function TRegistry.DeleteKey(const Key: UnicodeString): Boolean;
 
 Var
   u: UnicodeString;
@@ -76,21 +76,21 @@
   Result:=FLastError=ERROR_SUCCESS;
 end;
 
-function TRegistry.DeleteValue(const Name: String): Boolean;
+
+function TRegistry.DeleteValue(const Name: UnicodeString): Boolean;
 begin
-  FLastError:= RegDeleteValueW(fCurrentKey, PWideChar(UnicodeString(Name)));
+  FLastError:= RegDeleteValueW(fCurrentKey, PWideChar(Name));
   Result:=FLastError=ERROR_SUCCESS;
 end;
 
-function TRegistry.SysGetData(const Name: String; Buffer: Pointer;
+
+function TRegistry.SysGetData(const Name: UnicodeString; Buffer: Pointer;
           BufSize: Integer; Out RegData: TRegDataType): Integer;
 Var
-  u: UnicodeString;
   RD : DWord;
 
 begin
-  u := Name;
-  FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(u),Nil,
+  FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(Name),Nil,
                       @RD,Buffer,lpdword(@BufSize));
   if (FLastError<>ERROR_SUCCESS) Then
     Result:=-1
@@ -103,17 +103,15 @@
     end;
 end;
 
-function TRegistry.GetDataInfo(const ValueName: String; out Value: TRegDataInfo): Boolean;
+function TRegistry.GetDataInfo(const ValueName: UnicodeString; out Value: TRegDataInfo): Boolean;
 
 Var
-  u: UnicodeString;
   RD : DWord;
 
 begin
-  u:=ValueName;
   With Value do
     begin
-    FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(u),Nil,lpdword(@RegData),Nil,lpdword(@DataSize));
+    FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(ValueName),Nil,lpdword(@RegData),Nil,lpdword(@DataSize));
     Result:=FLastError=ERROR_SUCCESS;
     if Result then
       begin
@@ -131,24 +129,18 @@
 end;
 
 
-function TRegistry.GetKey(const Key: String): HKEY;
+function TRegistry.GetKey(Key: UnicodeString): HKEY;
 var
-  S : string;
-{$ifndef WinCE}
-  u : UnicodeString;
-{$endif}
   Rel : Boolean;
 begin
   Result:=0;
-  S:=Key;
-  Rel:=RelativeKey(S);
+  Rel:=RelativeKey(Key);
   if not(Rel) then
-    Delete(S,1,1);
+    Delete(Key,1,1);
 {$ifdef WinCE}
-  FLastError:=RegOpenKeyEx(GetBaseKey(Rel),PWideChar(WideString(S)),0,FAccess,Result);
+  FLastError:=RegOpenKeyEx(GetBaseKey(Rel),PWideChar(Key),0,FAccess,Result);
 {$else WinCE}
-  u:=UnicodeString(S);
-  FLastError:=RegOpenKeyExW(GetBaseKey(Rel),PWideChar(u),0,FAccess,Result);
+  FLastError:=RegOpenKeyExW(GetBaseKey(Rel),PWideChar(Key),0,FAccess,Result);
 {$endif WinCE}
 end;
 
@@ -174,7 +166,7 @@
 end;
 
 
-function TRegistry.KeyExists(const Key: string): Boolean;
+function TRegistry.KeyExists(const Key: UnicodeString): Boolean;
 var
   KeyHandle : HKEY;
   OldAccess : LONG;
@@ -196,20 +188,20 @@
 end;
 
 
-function TRegistry.LoadKey(const Key, FileName: string): Boolean;
+function TRegistry.LoadKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
 
-function TRegistry.OpenKey(const Key: string; CanCreate: Boolean): Boolean;
 
+function TRegistry.OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
+
 Var
-  u: UnicodeString;
+  u, S: UnicodeString;
   Handle: HKEY;
   Disposition: Integer;
   SecurityAttributes: Pointer; //LPSECURITY_ATTRIBUTES;
-  S: string;
 begin
   SecurityAttributes := Nil;
   u:=PrepKey(Key);
@@ -232,13 +224,14 @@
     if RelativeKey(Key) then
       S:=CurrentPath + Key
     else
-      S:=UTF8Encode(u);
+      S:=u;
     ChangeKey(Handle, S);
   end;
 end;
 
-function TRegistry.OpenKeyReadOnly(const Key: string): Boolean;
 
+function TRegistry.OpenKeyReadOnly(const Key: UnicodeString): Boolean;
+
 Var
   OldAccess: LongWord;
 begin
@@ -251,7 +244,8 @@
   end;
 end;
 
-function TRegistry.RegistryConnect(const UNCName: string): Boolean;
+
+function TRegistry.RegistryConnect(const UNCName: UnicodeString): Boolean;
 {$ifndef WinCE}
 var
   newroot: HKEY;
@@ -260,7 +254,7 @@
 {$ifdef WinCE}
   Result:=False;
 {$else}
-  FLastError:=RegConnectRegistryW(PWideChar(UnicodeString(UNCName)),RootKey,newroot);
+  FLastError:=RegConnectRegistryW(PWideChar(UNCName),RootKey,newroot);
   Result:=FLastError=ERROR_SUCCESS;
   if Result then begin
     RootKey:=newroot;
@@ -269,28 +263,33 @@
 {$endif}
 end;
 
-function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
+
+function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.RestoreKey(const Key, FileName: string): Boolean;
+
+function TRegistry.RestoreKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.SaveKey(const Key, FileName: string): Boolean;
+
+function TRegistry.SaveKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.UnLoadKey(const Key: string): Boolean;
+
+function TRegistry.UnLoadKey(const Key: UnicodeString): Boolean;
 begin
   Result := false;
 end;
 
-function TRegistry.ValueExists(const Name: string): Boolean;
 
+function TRegistry.ValueExists(const Name: UnicodeString): Boolean;
+
 var
   Info : TRegDataInfo;
 
@@ -298,6 +297,7 @@
   Result:=GetDataInfo(Name,Info);
 end;
 
+
 procedure TRegistry.CloseKey;
 begin
   If (CurrentKey<>0) then
@@ -316,7 +316,7 @@
   RegCloseKey(key);
 end;
 
-procedure TRegistry.ChangeKey(Value: HKey; const Path: String);
+procedure TRegistry.ChangeKey(Value: HKey; const Path: UnicodeString);
 begin
   CloseKey;
   FCurrentKey:=Value;
@@ -323,6 +323,7 @@
   FCurrentPath:=Path;
 end;
 
+
 procedure TRegistry.GetKeyNames(Strings: TStrings);
 
 var
@@ -410,12 +411,11 @@
 end;
 
 
-Function TRegistry.SysPutData(const Name: string; Buffer: Pointer;
+Function TRegistry.SysPutData(const Name: UnicodeString; Buffer: Pointer;
   BufSize: Integer; RegData: TRegDataType) : Boolean;
 
 
 Var
-  u: UnicodeString;
   RegDataType: DWORD;
   B : Pchar;
   S : String;
@@ -422,12 +422,11 @@
 
 begin
   RegDataType:=RegDataWords[RegData];
-  u:=UnicodeString(Name);
-  FLastError:=RegSetValueExW(fCurrentKey,PWideChar(u),0,RegDataType,Buffer,BufSize);
+  FLastError:=RegSetValueExW(fCurrentKey,PWideChar(Name),0,RegDataType,Buffer,BufSize);
   Result:=FLastError=ERROR_SUCCESS;
 end;
 
-procedure TRegistry.RenameValue(const OldName, NewName: string);
+procedure TRegistry.RenameValue(const OldName, NewName: UnicodeString);
 
 var
   L: Integer;
Index: packages/fcl-registry/src/xmlreg.pp
===================================================================
--- packages/fcl-registry/src/xmlreg.pp	(revision 41667)
+++ packages/fcl-registry/src/xmlreg.pp	(working copy)
@@ -329,7 +329,7 @@
                      begin
                      if not IsUnicode then
                        begin
-                       S:=UTF8Encode(DataNode.NodeValue); // Convert to ansistring
+                       S:=DataNode.NodeValue; // Convert to ansistring
                        NS:=Length(S);
                        Result:=(DataSize>=NS);
                        if Result then
@@ -390,7 +390,7 @@
                    SW:=UnicodeString(PUnicodeChar(@Data))
                  else
                    SW:=UnicodeString(PAnsiChar(@Data));
-                   //S:=UTF8Encode(SW);
+                   //S:=SW;
                  end;
       dtBinary : SW:=BufToHex(Data,DataSize);
       dtStrings : SW:=BufToHex(Data,DataSize);
@@ -671,7 +671,7 @@
         L:=Length(DN.NodeValue)*SizeOf(UnicodeChar)
       else
         begin
-        S := UTF8Encode(DN.NodeValue);
+        S := DN.NodeValue;
         L:=Length(S);
         end
       end
@@ -727,7 +727,7 @@
               Case TDataType(StrToIntDef(TDomElement(Node)[SType],0)) of
                 dtUnknown : L:=0;
                 dtDWord   : L:=4;
-                DtString  : L:=Length(UTF8Encode(DataNode.NodeValue));
+                DtString  : L:=Length(String(DataNode.NodeValue));
                 dtBinary  : L:=Length(DataNode.NodeValue) div 2;
               end
             else
Index: packages/fcl-registry/src/xregreg.inc
===================================================================
--- packages/fcl-registry/src/xregreg.inc	(revision 41667)
+++ packages/fcl-registry/src/xregreg.inc	(working copy)
@@ -130,24 +130,24 @@
   TXMLRegistryInstance.FreeXMLRegistry(TXMLRegistry(FSysData));
 end;
 
-function TRegistry.SysCreateKey(const Key: String): Boolean;
+function TRegistry.SysCreateKey(Key: UnicodeString): Boolean;
 
 begin
   Result:=TXmlRegistry(FSysData).CreateKey(Key);
 end;
 
-function TRegistry.DeleteKey(const Key: string): Boolean;
+function TRegistry.DeleteKey(const Key: UnicodeString): Boolean;
 
 begin
   Result:=TXMLRegistry(FSysData).DeleteKey(Key);
 end;
 
-function TRegistry.DeleteValue(const Name: string): Boolean;
+function TRegistry.DeleteValue(const Name: UnicodeString): Boolean;
 begin
   Result:=TXmlRegistry(FSysData).DeleteValue(Name);
 end;
 
-function TRegistry.SysGetData(const Name: String; Buffer: Pointer;
+function TRegistry.SysGetData(const Name: UnicodeString; Buffer: Pointer;
           BufSize: Integer; Out RegData: TRegDataType): Integer;
 
 Var
@@ -160,7 +160,7 @@
     Result:=-1;
 end;
 
-function TRegistry.GetDataInfo(const ValueName: string; out Value: TRegDataInfo): Boolean;
+function TRegistry.GetDataInfo(const ValueName: UnicodeString; out Value: TRegDataInfo): Boolean;
 
 Var
   Info : TDataInfo;
@@ -181,7 +181,7 @@
       end;
 end;
 
-function TRegistry.GetKey(const Key: string): HKEY;
+function TRegistry.GetKey(Key: UnicodeString): HKEY;
 begin
   Result := 0;
 end;
@@ -205,17 +205,17 @@
       end;
 end;
 
-function TRegistry.KeyExists(const Key: string): Boolean;
+function TRegistry.KeyExists(const Key: UnicodeString): Boolean;
 begin
   Result:=TXmlRegistry(FSysData).KeyExists(Key);
 end;
 
-function TRegistry.LoadKey(const Key, FileName: string): Boolean;
+function TRegistry.LoadKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.OpenKey(const Key: string; CanCreate: Boolean): Boolean;
+function TRegistry.OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
 
 begin
   Result:=TXmlRegistry(FSysData).SetKey(Key,CanCreate);
@@ -222,43 +222,43 @@
   FCurrentKey:=1;
 end;
 
-function TRegistry.OpenKeyReadOnly(const Key: string): Boolean;
+function TRegistry.OpenKeyReadOnly(const Key: UnicodeString): Boolean;
 
 begin
   Result:=TXmlRegistry(FSysData).SetKey(Key,False);
 end;
 
-function TRegistry.RegistryConnect(const UNCName: string): Boolean;
+function TRegistry.RegistryConnect(const UNCName: UnicodeString): Boolean;
 begin
   Result := True;
 end;
 
-function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
+function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.RestoreKey(const Key, FileName: string): Boolean;
+function TRegistry.RestoreKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.SaveKey(const Key, FileName: string): Boolean;
+function TRegistry.SaveKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.UnLoadKey(const Key: string): Boolean;
+function TRegistry.UnLoadKey(const Key: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.ValueExists(const Name: string): Boolean;
+function TRegistry.ValueExists(const Name: UnicodeString): Boolean;
 begin
   Result := TXmlRegistry(FSysData).ValueExists(Name);
 end;
 
-procedure TRegistry.ChangeKey(Value: HKey; const Path: string);
+procedure TRegistry.ChangeKey(Value: HKey; const Path: UnicodeString);
 begin
 
 end;
@@ -274,7 +274,7 @@
 end;
 
 
-function TRegistry.SysPutData(const Name: string; Buffer: Pointer;
+function TRegistry.SysPutData(const Name: UnicodeString; Buffer: Pointer;
   BufSize: Integer; RegData: TRegDataType): Boolean;
 
 Var
@@ -285,7 +285,7 @@
   Result:=TXMLRegistry(FSysData).SetValueDataUnicode(Name,DataType,Buffer^,BufSize);
 end;
 
-procedure TRegistry.RenameValue(const OldName, NewName: string);
+procedure TRegistry.RenameValue(const OldName, NewName: UnicodeString);
 begin
   TXMLRegistry(FSysData).RenameValue(OldName,NewName);
 end;

Bart Broersma

2019-03-13 20:22

reporter  

registry.unicode.part2.diff (53,709 bytes)
Index: packages/fcl-registry/src/regdef.inc
===================================================================
--- packages/fcl-registry/src/regdef.inc	(revision 41667)
+++ packages/fcl-registry/src/regdef.inc	(working copy)
@@ -2,7 +2,7 @@
   HKEY = THandle;
   PHKEY = ^HKEY;
   
-{$ifdef windows}
+{$if defined(windows) and not defined(XMLREG)}
 
 { Direct mapping to constants in Windows unit }
 
Index: packages/fcl-registry/src/registry.pp
===================================================================
--- packages/fcl-registry/src/registry.pp	(revision 41667)
+++ packages/fcl-registry/src/registry.pp	(working copy)
@@ -54,22 +54,28 @@
     fCurrentKey: HKEY;
     fRootKey: HKEY;
     fLazyWrite: Boolean;
-    fCurrentPath: string;
+    fCurrentPath: UnicodeString;
     function GetLastErrorMsg: string;
     procedure SetRootKey(Value: HKEY);
     Procedure SysRegCreate;
     Procedure SysRegFree;
-    Function  SysGetData(const Name: String; Buffer: Pointer; BufSize: Integer; Out RegData: TRegDataType): Integer;
-    Function  SysPutData(const Name: string; Buffer: Pointer; BufSize: Integer; RegData: TRegDataType) : Boolean;
-    Function  SysCreateKey(const Key: String): Boolean;
+    Function  SysGetData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; Out RegData: TRegDataType): Integer;
+    Function  SysPutData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; RegData: TRegDataType) : Boolean;
+    Function  SysCreateKey(Key: UnicodeString): Boolean;
   protected
     function GetBaseKey(Relative: Boolean): HKey;
-    function GetData(const Name: string; Buffer: Pointer;
+    function GetData(const Name: UnicodeString; Buffer: Pointer;
                   BufSize: Integer; Out RegData: TRegDataType): Integer;
-    function GetKey(const Key: string): HKEY;
-    procedure ChangeKey(Value: HKey; const Path: string);
-    procedure PutData(const Name: string; Buffer: Pointer;
+    function GetData(const Name: String; Buffer: Pointer;
+                  BufSize: Integer; Out RegData: TRegDataType): Integer;
+    function GetKey(Key: UnicodeString): HKEY;
+    function GetKey(Key: String): HKEY;
+    procedure ChangeKey(Value: HKey; const Path: UnicodeString);
+    procedure ChangeKey(Value: HKey; const Path: String);
+    procedure PutData(const Name: UnicodeString; Buffer: Pointer;
                   BufSize: Integer; RegData: TRegDataType);
+    procedure PutData(const Name: String; Buffer: Pointer;
+                  BufSize: Integer; RegData: TRegDataType);
     procedure SetCurrentKey(Value: HKEY);
   public
     constructor Create; overload;
@@ -76,58 +82,85 @@
     constructor Create(aaccess:longword); overload;
     destructor Destroy; override;
 
-    function CreateKey(const Key: string): Boolean;
-    function DeleteKey(const Key: string): Boolean;
-    function DeleteValue(const Name: string): Boolean;
-    function GetDataInfo(const ValueName: string; Out Value: TRegDataInfo): Boolean;
-    function GetDataSize(const ValueName: string): Integer;
-    function GetDataType(const ValueName: string): TRegDataType;
+    function CreateKey(const Key: UnicodeString): Boolean;
+    function CreateKey(const Key: String): Boolean;
+    function DeleteKey(const Key: UnicodeString): Boolean;
+    function DeleteKey(const Key: String): Boolean;
+    function DeleteValue(const Name: UnicodeString): Boolean;
+    function DeleteValue(const Name: String): Boolean;
+    function GetDataInfo(const ValueName: UnicodeString; Out Value: TRegDataInfo): Boolean;
+    function GetDataInfo(const ValueName: String; Out Value: TRegDataInfo): Boolean;
+    function GetDataSize(const ValueName: UnicodeString): Integer;
+    function GetDataSize(const ValueName: String): Integer;
+    function GetDataType(const ValueName: UnicodeString): TRegDataType;
+    function GetDataType(const ValueName: String): TRegDataType;
     function GetKeyInfo(Out Value: TRegKeyInfo): Boolean;
     function HasSubKeys: Boolean;
-    function KeyExists(const Key: string): Boolean;
-    function LoadKey(const Key, FileName: string): Boolean;
-    function OpenKey(const Key: string; CanCreate: Boolean): Boolean;
-    function OpenKeyReadOnly(const Key: string): Boolean;
-    function ReadCurrency(const Name: string): Currency;
-    function ReadBinaryData(const Name: string; var Buffer; BufSize: Integer): Integer;
-    function ReadBool(const Name: string): Boolean;
-    function ReadDate(const Name: string): TDateTime;
-    function ReadDateTime(const Name: string): TDateTime;
-    function ReadFloat(const Name: string): Double;
-    function ReadInteger(const Name: string): Integer;
-    function ReadInt64(const Name: string): Int64;
-    function ReadString(const Name: string): string;
-    procedure ReadStringList(const Name: string; AList: TStrings);
-    function ReadTime(const Name: string): TDateTime;
-    function RegistryConnect(const UNCName: string): Boolean;
-    function ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
-    function RestoreKey(const Key, FileName: string): Boolean;
-    function SaveKey(const Key, FileName: string): Boolean;
-    function UnLoadKey(const Key: string): Boolean;
-    function ValueExists(const Name: string): Boolean;
+    function KeyExists(const Key: UnicodeString): Boolean;
+    function KeyExists(const Key: String): Boolean;
+    function LoadKey(const Key, FileName: UnicodeString): Boolean;
+    function LoadKey(const Key, FileName: String): Boolean;
+    function OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
+    function OpenKey(const Key: String; CanCreate: Boolean): Boolean;
+    function OpenKeyReadOnly(const Key: UnicodeString): Boolean;
+    function OpenKeyReadOnly(const Key: String): Boolean;
+    function ReadCurrency(const Name: UnicodeString): Currency;
+    function ReadCurrency(const Name: String): Currency;
+    function ReadBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer): Integer;
+    function ReadBinaryData(const Name: String; var Buffer; BufSize: Integer): Integer;
+    function ReadBool(const Name: UnicodeString): Boolean;
+    function ReadBool(const Name: String): Boolean;
+    function ReadDate(const Name: UnicodeString): TDateTime;
+    function ReadDate(const Name: String): TDateTime;
+    function ReadDateTime(const Name: UnicodeString): TDateTime;
+    function ReadDateTime(const Name: String): TDateTime;
+    function ReadFloat(const Name: UnicodeString): Double;
+    function ReadFloat(const Name: String): Double;
+    function ReadInteger(const Name: UnicodeString): Integer;
+    function ReadInteger(const Name: String): Integer;
+    function ReadInt64(const Name: UnicodeString): Int64;
+    function ReadInt64(const Name: String): Int64;
+    function ReadString(const Name: UnicodeString): string;
+    function ReadString(const Name: String): string;
+    procedure ReadStringList(const Name: UnicodeString; AList: TStrings);
+    procedure ReadStringList(const Name: String; AList: TStrings);
+    function ReadTime(const Name: UnicodeString): TDateTime;
+    function ReadTime(const Name: String): TDateTime;
+    function RegistryConnect(const UNCName: UnicodeString): Boolean;
+    function RegistryConnect(const UNCName: String): Boolean;
+    function ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
+    function ReplaceKey(const Key, FileName, BackUpFileName: String): Boolean;
+    function RestoreKey(const Key, FileName: UnicodeString): Boolean;
+    function RestoreKey(const Key, FileName: String): Boolean;
+    function SaveKey(const Key, FileName: UnicodeString): Boolean;
+    function SaveKey(const Key, FileName: String): Boolean;
+    function UnLoadKey(const Key: UnicodeString): Boolean;
+    function UnLoadKey(const Key: String): Boolean;
+    function ValueExists(const Name: UnicodeString): Boolean;
+    function ValueExists(const Name: String): Boolean;
 
     procedure CloseKey;
     procedure CloseKey(key:HKEY);
     procedure GetKeyNames(Strings: TStrings);
     procedure GetValueNames(Strings: TStrings);
-    procedure MoveKey(const OldName, NewName: string; Delete: Boolean);
-    procedure RenameValue(const OldName, NewName: string);
-    procedure WriteCurrency(const Name: string; Value: Currency);
-    procedure WriteBinaryData(const Name: string; var Buffer; BufSize: Integer);
-    procedure WriteBool(const Name: string; Value: Boolean);
-    procedure WriteDate(const Name: string; Value: TDateTime);
-    procedure WriteDateTime(const Name: string; Value: TDateTime);
-    procedure WriteFloat(const Name: string; Value: Double);
-    procedure WriteInteger(const Name: string; Value: Integer);
-    procedure WriteInt64(const Name: string; Value: Int64);
-    procedure WriteString(const Name, Value: string);
-    procedure WriteExpandString(const Name, Value: string);
-    procedure WriteStringList(const Name: string; List: TStrings);
-    procedure WriteTime(const Name: string; Value: TDateTime);
+    procedure MoveKey(const OldName, NewName: UnicodeString; Delete: Boolean);
+    procedure RenameValue(const OldName, NewName: UnicodeString);
+    procedure WriteCurrency(const Name: UnicodeString; Value: Currency);
+    procedure WriteBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer);
+    procedure WriteBool(const Name: UnicodeString; Value: Boolean);
+    procedure WriteDate(const Name: UnicodeString; Value: TDateTime);
+    procedure WriteDateTime(const Name: UnicodeString; Value: TDateTime);
+    procedure WriteFloat(const Name: UnicodeString; Value: Double);
+    procedure WriteInteger(const Name: UnicodeString; Value: Integer);
+    procedure WriteInt64(const Name: UnicodeString; Value: Int64);
+    procedure WriteString(const Name, Value: UnicodeString);
+    procedure WriteExpandString(const Name, Value: UnicodeString);
+    procedure WriteStringList(const Name: UnicodeString; List: TStrings);
+    procedure WriteTime(const Name: UnicodeString; Value: TDateTime);
 
     property Access: LongWord read fAccess write fAccess;
     property CurrentKey: HKEY read fCurrentKey;
-    property CurrentPath: string read fCurrentPath;
+    property CurrentPath: UnicodeString read fCurrentPath;
     property LazyWrite: Boolean read fLazyWrite write fLazyWrite;
     property RootKey: HKEY read fRootKey write SetRootKey;
     Property StringSizeIncludesNull : Boolean read FStringSizeIncludesNull;
@@ -261,7 +294,7 @@
   inherited Destroy;
 end;
 
-function TRegistry.CreateKey(const Key: string): Boolean;
+function TRegistry.CreateKey(const Key: UnicodeString): Boolean;
 
 begin
   Result:=SysCreateKey(Key);
@@ -269,6 +302,27 @@
     Raise ERegistryException.CreateFmt(SRegCreateFailed, [Key]);
 end;
 
+function TRegistry.CreateKey(const Key: String): Boolean;
+begin
+  Result:=CreateKey(UnicodeString(Key));
+end;
+
+function TRegistry.DeleteKey(const Key: String): Boolean;
+begin
+  Result:=DeleteKey(UnicodeString(Key));
+end;
+
+function TRegistry.DeleteValue(const Name: String): Boolean;
+begin
+  Result:=DeleteValue(UnicodeString(Name));
+end;
+
+function TRegistry.GetDataInfo(const ValueName: String; out Value: TRegDataInfo
+  ): Boolean;
+begin
+  Result:=GetDataInfo(UnicodeString(ValueName), Value);
+end;
+
 function TRegistry.GetBaseKey(Relative: Boolean): HKey;
 begin
   If Relative and (CurrentKey<>0) Then
@@ -277,7 +331,7 @@
     Result := RootKey;
 end;
 
-function TRegistry.GetData(const Name: string; Buffer: Pointer; BufSize: Integer; out RegData: TRegDataType): Integer;
+function TRegistry.GetData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; out RegData: TRegDataType): Integer;
 begin
   Result:=SysGetData(Name,Buffer,BufSize,RegData);
   If (Result=-1) then
@@ -284,7 +338,24 @@
     Raise ERegistryException.CreateFmt(SRegGetDataFailed, [Name]);
 end;
 
-procedure TRegistry.PutData(const Name: string; Buffer: Pointer;
+function TRegistry.GetData(const Name: String; Buffer: Pointer;
+  BufSize: Integer; out RegData: TRegDataType): Integer;
+begin
+  Result:=GetData(UnicodeString(Name), Buffer, BufSize, RegData);
+end;
+
+function TRegistry.GetKey(Key: String): HKEY;
+begin
+  Result:=GetKey(UnicodeString(Key));
+end;
+
+procedure TRegistry.ChangeKey(Value: HKey; const Path: String);
+begin
+  ChangeKey(Value, UnicodeString(Path));
+end;
+
+
+procedure TRegistry.PutData(const Name: UnicodeString; Buffer: Pointer;
   BufSize: Integer; RegData: TRegDataType);
 
 begin
@@ -292,9 +363,15 @@
     Raise ERegistryException.CreateFmt(SRegSetDataFailed, [Name]);
 end;
 
+procedure TRegistry.PutData(const Name: String; Buffer: Pointer;
+  BufSize: Integer; RegData: TRegDataType);
+begin
+  PutData(UnicodeString(Name), Buffer, BufSize, RegData);
+end;
 
-function TRegistry.GetDataSize(const ValueName: string): Integer;
 
+function TRegistry.GetDataSize(const ValueName: UnicodeString): Integer;
+
 Var
   Info: TRegDataInfo;
 
@@ -305,8 +382,13 @@
     Result := -1;
 end;
 
-function TRegistry.GetDataType(const ValueName: string): TRegDataType;
+function TRegistry.GetDataSize(const ValueName: String): Integer;
+begin
+  Result:=GetDataSize(UnicodeString(ValueName));
+end;
 
+function TRegistry.GetDataType(const ValueName: UnicodeString): TRegDataType;
+
 Var
   Info: TRegDataInfo;
 
@@ -315,6 +397,32 @@
   Result:=Info.RegData;
 end;
 
+function TRegistry.GetDataType(const ValueName: String): TRegDataType;
+begin
+  Result:=GetDataType(UnicodeString(ValueName));
+end;
+
+
+function TRegistry.KeyExists(const Key: String): Boolean;
+begin
+  Result:=KeyExists(UnicodeString(Key));
+end;
+
+function TRegistry.LoadKey(const Key, FileName: String): Boolean;
+begin
+  Result:=LoadKey(UnicodeString(Key), UnicodeString(FileName));
+end;
+
+function TRegistry.OpenKey(const Key: String; CanCreate: Boolean): Boolean;
+begin
+  Result:=OpenKey(UnicodeString(Key), CanCreate);
+end;
+
+function TRegistry.OpenKeyReadOnly(const Key: String): Boolean;
+begin
+  Result:=OpenKeyReadOnly(UnicodeString(Key));
+end;
+
 function TRegistry.HasSubKeys: Boolean;
 
 Var
@@ -326,7 +434,7 @@
     Result:=(Info.NumSubKeys>0);
 end;
 
-function TRegistry.ReadBinaryData(const Name: string; var Buffer; BufSize: Integer): Integer;
+function TRegistry.ReadBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer): Integer;
 
 Var
   RegDataType: TRegDataType;
@@ -337,8 +445,14 @@
     Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
 end;
 
-function TRegistry.ReadInteger(const Name: string): Integer;
+function TRegistry.ReadBinaryData(const Name: String; var Buffer;
+  BufSize: Integer): Integer;
+begin
+  Result:=ReadBinaryData(UnicodeString(Name), Buffer, BufSize);
+end;
 
+function TRegistry.ReadInteger(const Name: UnicodeString): Integer;
+
 Var
   RegDataType: TRegDataType;
 
@@ -348,8 +462,13 @@
     Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
 end;
 
-function TRegistry.ReadInt64(const Name: string): Int64;
+function TRegistry.ReadInteger(const Name: String): Integer;
+begin
+  Result:=ReadInteger(UnicodeString(Name));
+end;
 
+function TRegistry.ReadInt64(const Name: UnicodeString): Int64;
+
 Var
   RegDataType: TRegDataType;
 
@@ -359,21 +478,36 @@
     Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
 end;
 
-function TRegistry.ReadBool(const Name: string): Boolean;
+function TRegistry.ReadInt64(const Name: String): Int64;
+begin
+  Result:=ReadInt64(UnicodeString(Name));
+end;
 
+function TRegistry.ReadBool(const Name: UnicodeString): Boolean;
+
 begin
   Result:=ReadInteger(Name)<>0;
 end;
 
-function TRegistry.ReadCurrency(const Name: string): Currency;
+function TRegistry.ReadBool(const Name: String): Boolean;
+begin
+  Result:=ReadBool(UnicodeString(Name));
+end;
 
+function TRegistry.ReadCurrency(const Name: UnicodeString): Currency;
+
 begin
   Result:=Default(Currency);
   ReadBinaryData(Name, Result, SizeOf(Currency));
 end;
 
-function TRegistry.ReadDate(const Name: string): TDateTime;
+function TRegistry.ReadCurrency(const Name: String): Currency;
+begin
+  Result:=ReadCurrency(UnicodeString(Name));
+end;
 
+function TRegistry.ReadDate(const Name: UnicodeString): TDateTime;
+
 begin
   Result:=Default(TDateTime);
   ReadBinaryData(Name, Result, SizeOf(TDateTime));
@@ -380,22 +514,37 @@
   Result:=Trunc(Result);
 end;
 
-function TRegistry.ReadDateTime(const Name: string): TDateTime;
+function TRegistry.ReadDate(const Name: String): TDateTime;
+begin
+  Result:=ReadDate(UnicodeString(Name));
+end;
 
+function TRegistry.ReadDateTime(const Name: UnicodeString): TDateTime;
+
 begin
   Result:=Default(TDateTime);
   ReadBinaryData(Name, Result, SizeOf(TDateTime));
 end;
 
-function TRegistry.ReadFloat(const Name: string): Double;
+function TRegistry.ReadDateTime(const Name: String): TDateTime;
+begin
+  Result:=ReadDateTime(UnicodeString(Name));
+end;
 
+function TRegistry.ReadFloat(const Name: UnicodeString): Double;
+
 begin
   Result:=Default(Double);
   ReadBinaryData(Name,Result,SizeOf(Double));
 end;
 
-function TRegistry.ReadString(const Name: string): string;
+function TRegistry.ReadFloat(const Name: String): Double;
+begin
+  Result:=ReadFloat(UnicodeString(Name));
+end;
 
+function TRegistry.ReadString(const Name: UnicodeString): string;
+
 Var
   Info : TRegDataInfo;
   ReadDataSize: Integer;
@@ -421,17 +570,22 @@
       if StringSizeIncludesNull and
          (u[Length(u)] = WideChar(0)) then
         SetLength(u,Length(u)-1);
-      Result:=UTF8Encode(u);
+      Result:=u;
     end;
   end;
 end;
 
-procedure TRegistry.ReadStringList(const Name: string; AList: TStrings);
+function TRegistry.ReadString(const Name: String): string;
+begin
+  Result:=ReadString(UnicodeString(Name));
+end;
 
+procedure TRegistry.ReadStringList(const Name: UnicodeString; AList: TStrings);
+
 Var
   Info : TRegDataInfo;
-  ReadDataSize: Integer;
-  Data: string;
+  ReadDataSize, i: Integer;
+  Data: UnicodeString;
 
 begin
   AList.Clear;
@@ -441,7 +595,7 @@
      If Not (Info.RegData in [rdMultiString]) then
        Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
      SetLength(Data,Info.DataSize);
-     ReadDataSize := GetData(Name,PChar(Data),Info.DataSize,Info.RegData);
+     ReadDataSize := GetData(Name,PWideChar(Data),Info.DataSize,Info.RegData) div SizeOf(WideChar);
      if ReadDataSize > 0 then
      begin
        // If the data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type,
@@ -454,14 +608,19 @@
            Dec(ReadDataSize);
        end;
        SetLength(Data, ReadDataSize);
-       Data := StringReplace(Data, #0, LineEnding, [rfReplaceAll]);
+       Data := UnicodeStringReplace(Data, #0, AList.LineBreak, [rfReplaceAll]);
        AList.Text := Data;
      end
    end
 end;
 
-function TRegistry.ReadTime(const Name: string): TDateTime;
+procedure TRegistry.ReadStringList(const Name: String; AList: TStrings);
+begin
+  ReadStringList(UnicodeString(Name), AList);
+end;
 
+function TRegistry.ReadTime(const Name: UnicodeString): TDateTime;
+
 begin
   Result:=Default(TDateTime);
   ReadBinaryData(Name, Result, SizeOf(TDateTime));
@@ -468,81 +627,123 @@
   Result:=Frac(Result);
 end;
 
-procedure TRegistry.WriteBinaryData(const Name: string; var Buffer; BufSize: Integer);
+function TRegistry.ReadTime(const Name: String): TDateTime;
 begin
+  Result:=ReadTime(UnicodeString(Name));
+end;
+
+function TRegistry.RegistryConnect(const UNCName: String): Boolean;
+begin
+  Result:=RegistryConnect(UnicodeString(UNCName));
+end;
+
+function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: String): Boolean;
+begin
+  Result:=ReplaceKey(UnicodeString(Key), UnicodeString(FileName), UnicodeString(BackUpFileName))
+end;
+
+function TRegistry.RestoreKey(const Key, FileName: String): Boolean;
+begin
+  Result:=RestoreKey(UnicodeString(Key), UnicodeString(FileName));
+end;
+
+function TRegistry.SaveKey(const Key, FileName: String): Boolean;
+begin
+  Result:=SaveKey(UnicodeString(Key), UnicodeString(FileName));
+end;
+
+function TRegistry.UnLoadKey(const Key: String): Boolean;
+begin
+  Result:=UnloadKey(UnicodeString(Key));
+end;
+
+function TRegistry.ValueExists(const Name: String): Boolean;
+begin
+  Result:=ValueExists(UnicodeString(Name));
+end;
+
+procedure TRegistry.WriteBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer);
+begin
   PutData(Name, @Buffer, BufSize, rdBinary);
 end;
 
-procedure TRegistry.WriteBool(const Name: string; Value: Boolean);
+procedure TRegistry.WriteBool(const Name: UnicodeString; Value: Boolean);
 
 begin
   WriteInteger(Name,Ord(Value));
 end;
 
-procedure TRegistry.WriteCurrency(const Name: string; Value: Currency);
+procedure TRegistry.WriteCurrency(const Name: UnicodeString; Value: Currency);
 begin
   WriteBinaryData(Name, Value, SizeOf(Currency));
 end;
 
-procedure TRegistry.WriteDate(const Name: string; Value: TDateTime);
+procedure TRegistry.WriteDate(const Name: UnicodeString; Value: TDateTime);
 begin
   WriteBinarydata(Name, Value, SizeOf(TDateTime));
 end;
 
-procedure TRegistry.WriteTime(const Name: string; Value: TDateTime);
+procedure TRegistry.WriteTime(const Name: UnicodeString; Value: TDateTime);
 begin
   WriteBinaryData(Name, Value, SizeOf(TDateTime));
 end;
 
-procedure TRegistry.WriteDateTime(const Name: string; Value: TDateTime);
+procedure TRegistry.WriteDateTime(const Name: UnicodeString; Value: TDateTime);
 begin
   WriteBinaryData(Name, Value, SizeOf(TDateTime));
 end;
 
-procedure TRegistry.WriteExpandString(const Name, Value: string);
-var
-  u: UnicodeString;
-
+procedure TRegistry.WriteExpandString(const Name, Value: UnicodeString);
 begin
-  u:=Value;
-  PutData(Name, PWideChar(u), ByteLength(u), rdExpandString);
+  PutData(Name, PWideChar(Value), ByteLength(Value), rdExpandString);
 end;
 
-procedure TRegistry.WriteStringList(const Name: string; List: TStrings);
+procedure TRegistry.WriteStringList(const Name: UnicodeString; List: TStrings);
 
 Var
-  Data: string;
-
+  Data: UnicodeString;
+  u: UnicodeString;
+  i: Integer;
 begin
-  Data := StringReplace(List.Text, LineEnding, #0, [rfReplaceAll]) + #0#0;
-  PutData(Name, PChar(Data), Length(Data),rdMultiString);
+  Data := '';
+  //REG_MULTI_SZ data cannot contain empty strings
+  for i := 0 to List.Count - 1 do
+  begin
+    u := List[i];
+    if (u>'') then
+    begin
+      if (Data>'') then
+        Data := Data + #0 + u
+      else
+        Data := Data + u;
+    end;
+  end;
+  if StringSizeIncludesNull then
+    Data := Data + #0#0;
+  PutData(Name, PWideChar(Data), ByteLength(Data), rdMultiString);
 end;
 
-procedure TRegistry.WriteFloat(const Name: string; Value: Double);
+procedure TRegistry.WriteFloat(const Name: UnicodeString; Value: Double);
 begin
   WriteBinaryData(Name, Value, SizeOf(Double));
 end;
 
-procedure TRegistry.WriteInteger(const Name: string; Value: Integer);
+procedure TRegistry.WriteInteger(const Name: UnicodeString; Value: Integer);
 begin
   PutData(Name, @Value, SizeOf(Integer), rdInteger);
 end;
 
-procedure TRegistry.WriteInt64(const Name: string; Value: Int64);
+procedure TRegistry.WriteInt64(const Name: UnicodeString; Value: Int64);
 begin
   PutData(Name, @Value, SizeOf(Int64), rdInt64);
 end;
 
-procedure TRegistry.WriteString(const Name, Value: string);
-var
-  u: UnicodeString;
-
+procedure TRegistry.WriteString(const Name, Value: UnicodeString);
 begin
-  u:=Value;
-  PutData(Name, PWideChar(u), ByteLength(u), rdString);
+  PutData(Name, PWideChar(Value), ByteLength(Value), rdString);
 end;
 
-procedure TRegistry.MoveKey(const OldName, NewName: string; Delete: Boolean);
+procedure TRegistry.MoveKey(const OldName, NewName: UnicodeString; Delete: Boolean);
 begin
 
 end;
Index: packages/fcl-registry/src/winreg.inc
===================================================================
--- packages/fcl-registry/src/winreg.inc	(revision 41667)
+++ packages/fcl-registry/src/winreg.inc	(working copy)
@@ -1,7 +1,7 @@
 Const
   RegDataWords : Array [TRegDataType] of DWORD
                = (REG_NONE,REG_SZ,REG_EXPAND_SZ,REG_BINARY,REG_DWORD,REG_DWORD_BIG_ENDIAN,
-                  REG_LINK,REG_MULTI_SZ,REG_RESOURCE_LIST,REG_FULL_RESOURCE_DESCRIPTOR,REG_RESOURCE_REQUIREMENTS_LIST,REG_QWORD);
+                  REG_LINK,REG_MULTI_SZ,REG_RESOURCE_LIST,REG_FULL_RESOURCE_DESCRIPTOR,REG_RESOURCE_REQUIREMENTS_LIST,11{REG_QWORD}); //*****UNDO THIS!
 
 type
   TWinRegData = record
@@ -28,7 +28,7 @@
   Dispose(PWinRegData(FSysData));
 end;
 
-Function PrepKey(Const S : String) : String;
+Function PrepKey(Const S : UnicodeString) : UnicodeString;
 
 begin
   Result := S;
@@ -36,7 +36,7 @@
     System.Delete(Result, 1, 1);
 end;
 
-Function RelativeKey(Const S : String) : Boolean;
+Function RelativeKey(Const S : UnicodeString) : Boolean;
 
 begin
   Result:=(S='') or (S[1]<>'\')
@@ -43,7 +43,7 @@
 end;
 
 
-function TRegistry.sysCreateKey(const Key: String): Boolean;
+function TRegistry.sysCreateKey(Key: UnicodeString): Boolean;
 Var
   u: UnicodeString;
   Disposition: Dword;
@@ -52,9 +52,9 @@
 
 begin
   SecurityAttributes := Nil;
-  u:=PrepKey(Key);
+  Key:=PrepKey(Key);
   FLastError:=RegCreateKeyExW(GetBaseKey(RelativeKey(Key)),
-                              PWideChar(u),
+                              PWideChar(Key),
                               0,
                               '',
                               REG_OPTION_NON_VOLATILE,
@@ -66,7 +66,7 @@
   RegCloseKey(Handle);
 end;
 
-function TRegistry.DeleteKey(const Key: String): Boolean;
+function TRegistry.DeleteKey(const Key: UnicodeString): Boolean;
 
 Var
   u: UnicodeString;
@@ -76,21 +76,21 @@
   Result:=FLastError=ERROR_SUCCESS;
 end;
 
-function TRegistry.DeleteValue(const Name: String): Boolean;
+
+function TRegistry.DeleteValue(const Name: UnicodeString): Boolean;
 begin
-  FLastError:= RegDeleteValueW(fCurrentKey, PWideChar(UnicodeString(Name)));
+  FLastError:= RegDeleteValueW(fCurrentKey, PWideChar(Name));
   Result:=FLastError=ERROR_SUCCESS;
 end;
 
-function TRegistry.SysGetData(const Name: String; Buffer: Pointer;
+
+function TRegistry.SysGetData(const Name: UnicodeString; Buffer: Pointer;
           BufSize: Integer; Out RegData: TRegDataType): Integer;
 Var
-  u: UnicodeString;
   RD : DWord;
 
 begin
-  u := Name;
-  FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(u),Nil,
+  FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(Name),Nil,
                       @RD,Buffer,lpdword(@BufSize));
   if (FLastError<>ERROR_SUCCESS) Then
     Result:=-1
@@ -103,17 +103,15 @@
     end;
 end;
 
-function TRegistry.GetDataInfo(const ValueName: String; out Value: TRegDataInfo): Boolean;
+function TRegistry.GetDataInfo(const ValueName: UnicodeString; out Value: TRegDataInfo): Boolean;
 
 Var
-  u: UnicodeString;
   RD : DWord;
 
 begin
-  u:=ValueName;
   With Value do
     begin
-    FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(u),Nil,lpdword(@RegData),Nil,lpdword(@DataSize));
+    FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(ValueName),Nil,lpdword(@RegData),Nil,lpdword(@DataSize));
     Result:=FLastError=ERROR_SUCCESS;
     if Result then
       begin
@@ -131,24 +129,18 @@
 end;
 
 
-function TRegistry.GetKey(const Key: String): HKEY;
+function TRegistry.GetKey(Key: UnicodeString): HKEY;
 var
-  S : string;
-{$ifndef WinCE}
-  u : UnicodeString;
-{$endif}
   Rel : Boolean;
 begin
   Result:=0;
-  S:=Key;
-  Rel:=RelativeKey(S);
+  Rel:=RelativeKey(Key);
   if not(Rel) then
-    Delete(S,1,1);
+    Delete(Key,1,1);
 {$ifdef WinCE}
-  FLastError:=RegOpenKeyEx(GetBaseKey(Rel),PWideChar(WideString(S)),0,FAccess,Result);
+  FLastError:=RegOpenKeyEx(GetBaseKey(Rel),PWideChar(Key),0,FAccess,Result);
 {$else WinCE}
-  u:=UnicodeString(S);
-  FLastError:=RegOpenKeyExW(GetBaseKey(Rel),PWideChar(u),0,FAccess,Result);
+  FLastError:=RegOpenKeyExW(GetBaseKey(Rel),PWideChar(Key),0,FAccess,Result);
 {$endif WinCE}
 end;
 
@@ -174,7 +166,7 @@
 end;
 
 
-function TRegistry.KeyExists(const Key: string): Boolean;
+function TRegistry.KeyExists(const Key: UnicodeString): Boolean;
 var
   KeyHandle : HKEY;
   OldAccess : LONG;
@@ -196,20 +188,20 @@
 end;
 
 
-function TRegistry.LoadKey(const Key, FileName: string): Boolean;
+function TRegistry.LoadKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
 
-function TRegistry.OpenKey(const Key: string; CanCreate: Boolean): Boolean;
 
+function TRegistry.OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
+
 Var
-  u: UnicodeString;
+  u, S: UnicodeString;
   Handle: HKEY;
   Disposition: Integer;
   SecurityAttributes: Pointer; //LPSECURITY_ATTRIBUTES;
-  S: string;
 begin
   SecurityAttributes := Nil;
   u:=PrepKey(Key);
@@ -232,13 +224,14 @@
     if RelativeKey(Key) then
       S:=CurrentPath + Key
     else
-      S:=UTF8Encode(u);
+      S:=u;
     ChangeKey(Handle, S);
   end;
 end;
 
-function TRegistry.OpenKeyReadOnly(const Key: string): Boolean;
 
+function TRegistry.OpenKeyReadOnly(const Key: UnicodeString): Boolean;
+
 Var
   OldAccess: LongWord;
 begin
@@ -251,7 +244,8 @@
   end;
 end;
 
-function TRegistry.RegistryConnect(const UNCName: string): Boolean;
+
+function TRegistry.RegistryConnect(const UNCName: UnicodeString): Boolean;
 {$ifndef WinCE}
 var
   newroot: HKEY;
@@ -260,7 +254,7 @@
 {$ifdef WinCE}
   Result:=False;
 {$else}
-  FLastError:=RegConnectRegistryW(PWideChar(UnicodeString(UNCName)),RootKey,newroot);
+  FLastError:=RegConnectRegistryW(PWideChar(UNCName),RootKey,newroot);
   Result:=FLastError=ERROR_SUCCESS;
   if Result then begin
     RootKey:=newroot;
@@ -269,28 +263,33 @@
 {$endif}
 end;
 
-function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
+
+function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.RestoreKey(const Key, FileName: string): Boolean;
+
+function TRegistry.RestoreKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.SaveKey(const Key, FileName: string): Boolean;
+
+function TRegistry.SaveKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.UnLoadKey(const Key: string): Boolean;
+
+function TRegistry.UnLoadKey(const Key: UnicodeString): Boolean;
 begin
   Result := false;
 end;
 
-function TRegistry.ValueExists(const Name: string): Boolean;
 
+function TRegistry.ValueExists(const Name: UnicodeString): Boolean;
+
 var
   Info : TRegDataInfo;
 
@@ -298,6 +297,7 @@
   Result:=GetDataInfo(Name,Info);
 end;
 
+
 procedure TRegistry.CloseKey;
 begin
   If (CurrentKey<>0) then
@@ -316,7 +316,7 @@
   RegCloseKey(key);
 end;
 
-procedure TRegistry.ChangeKey(Value: HKey; const Path: String);
+procedure TRegistry.ChangeKey(Value: HKey; const Path: UnicodeString);
 begin
   CloseKey;
   FCurrentKey:=Value;
@@ -323,6 +323,7 @@
   FCurrentPath:=Path;
 end;
 
+
 procedure TRegistry.GetKeyNames(Strings: TStrings);
 
 var
@@ -410,12 +411,11 @@
 end;
 
 
-Function TRegistry.SysPutData(const Name: string; Buffer: Pointer;
+Function TRegistry.SysPutData(const Name: UnicodeString; Buffer: Pointer;
   BufSize: Integer; RegData: TRegDataType) : Boolean;
 
 
 Var
-  u: UnicodeString;
   RegDataType: DWORD;
   B : Pchar;
   S : String;
@@ -422,12 +422,11 @@
 
 begin
   RegDataType:=RegDataWords[RegData];
-  u:=UnicodeString(Name);
-  FLastError:=RegSetValueExW(fCurrentKey,PWideChar(u),0,RegDataType,Buffer,BufSize);
+  FLastError:=RegSetValueExW(fCurrentKey,PWideChar(Name),0,RegDataType,Buffer,BufSize);
   Result:=FLastError=ERROR_SUCCESS;
 end;
 
-procedure TRegistry.RenameValue(const OldName, NewName: string);
+procedure TRegistry.RenameValue(const OldName, NewName: UnicodeString);
 
 var
   L: Integer;
Index: packages/fcl-registry/src/xmlreg.pp
===================================================================
--- packages/fcl-registry/src/xmlreg.pp	(revision 41667)
+++ packages/fcl-registry/src/xmlreg.pp	(working copy)
@@ -32,54 +32,54 @@
   Private
     FAutoFlush,
     FDirty : Boolean;
-    FFileName : String;
-    FRootKey : String;
+    FFileName : UnicodeString;
+    FRootKey : UnicodeString;
     FDocument : TXMLDocument;
     FCurrentElement : TDomElement;
-    FCurrentKey : String;
-    Procedure SetFileName(Value : String);
+    FCurrentKey : UnicodeString;
+    Procedure SetFileName(Value : UnicodeString);
   Protected
-    function DoGetValueData(Name: String; out DataType: TDataType; Var Data; Var DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
-    function DoSetValueData(Name: String; DataType: TDataType; const Data; DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
+    function DoGetValueData(Name: UnicodeString; out DataType: TDataType; Var Data; Var DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
+    function DoSetValueData(Name: UnicodeString; DataType: TDataType; const Data; DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
     Procedure LoadFromStream(S : TStream);
-    Function  NormalizeKey(KeyPath : String) : String;
+    Function  NormalizeKey(KeyPath : UnicodeString) : UnicodeString;
     Procedure CreateEmptyDoc;
-    Function  FindKey (S : String) : TDomElement;
-    Function  FindSubKey (S : String; N : TDomElement) : TDomElement;
-    Function  CreateSubKey (S : String; N : TDomElement) : TDomElement;
-    Function  FindValueKey (S : String) : TDomElement;
-    Function  CreateValueKey (S : String) : TDomElement;
+    Function  FindKey (S : UnicodeString) : TDomElement;
+    Function  FindSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
+    Function  CreateSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
+    Function  FindValueKey (S : UnicodeString) : TDomElement;
+    Function  CreateValueKey (S : UnicodeString) : TDomElement;
     Function  BufToHex(Const Buf; Len : Integer) : String;
-    Function  hexToBuf(Const Str : String; Var Buf; Var Len : Integer ) : Integer;
+    Function  HexToBuf(Const Str : UnicodeString; Var Buf; Var Len : Integer ) : Integer;
     Procedure MaybeFlush;
     Property  Document : TXMLDocument Read FDocument;
     Property  Dirty : Boolean Read FDirty write FDirty;
   Public
-    Constructor Create(AFileName : String);
+    Constructor Create(AFileName : UnicodeString);
     Destructor  Destroy;override;
-    Function  SetKey(KeyPath : String; AllowCreate : Boolean) : Boolean ;
-    Procedure SetRootKey(Value : String);
-    Function  DeleteKey(KeyPath : String) : Boolean;
-    Function  CreateKey(KeyPath : String) : Boolean;
-    Function  GetValueSize(Name : String) : Integer;
-    Function  GetValueType(Name : String) : TDataType;
-    Function  GetValueInfo(Name : String; Out Info : TDataInfo; AsUnicode : Boolean = False) : Boolean;
+    Function  SetKey(KeyPath : UnicodeString; AllowCreate : Boolean) : Boolean ;
+    Procedure SetRootKey(Value : UnicodeString);
+    Function  DeleteKey(KeyPath : UnicodeString) : Boolean;
+    Function  CreateKey(KeyPath : UnicodeString) : Boolean;
+    Function  GetValueSize(Name : UnicodeString) : Integer;
+    Function  GetValueType(Name : UnicodeString) : TDataType;
+    Function  GetValueInfo(Name : UnicodeString; Out Info : TDataInfo; AsUnicode : Boolean = False) : Boolean;
     Function  GetKeyInfo(Out Info : TKeyInfo) : Boolean;
     Function  EnumSubKeys(List : TStrings) : Integer;
     Function  EnumValues(List : TStrings) : Integer;
-    Function  KeyExists(KeyPath : String) : Boolean;
-    Function  ValueExists(ValueName : String) : Boolean;
-    Function  RenameValue(Const OldName,NewName : String) : Boolean;
-    Function  DeleteValue(S : String) : Boolean;
+    Function  KeyExists(KeyPath : UnicodeString) : Boolean;
+    Function  ValueExists(ValueName : UnicodeString) : Boolean;
+    Function  RenameValue(Const OldName,NewName : UnicodeString) : Boolean;
+    Function  DeleteValue(S : UnicodeString) : Boolean;
     Procedure Flush;
     Procedure Load;
-    Function GetValueData(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
-    Function SetValueData(Name : String; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
+    Function GetValueData(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
+    Function SetValueData(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
     // These interpret the Data buffer as unicode data
-    Function GetValueDataUnicode(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
-    Function SetValueDataUnicode(Name : String; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
-    Property FileName : String Read FFileName Write SetFileName;
-    Property RootKey : String Read FRootKey Write SetRootkey;
+    Function GetValueDataUnicode(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
+    Function SetValueDataUnicode(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
+    Property FileName : UnicodeString Read FFileName Write SetFileName;
+    Property RootKey : UnicodeString Read FRootKey Write SetRootkey;
     Property AutoFlush : Boolean Read FAutoFlush Write FAutoFlush;
   end;
 
@@ -96,7 +96,7 @@
 Implementation
 
 
-Constructor TXmlRegistry.Create(AFileName : String);
+Constructor TXmlRegistry.Create(AFileName : UnicodeString);
 
 begin
   FFileName:=AFileName;
@@ -113,7 +113,7 @@
   inherited Destroy;
 end;
 
-Procedure TXmlRegistry.SetFileName(Value : String);
+Procedure TXmlRegistry.SetFileName(Value : UnicodeString);
 
 begin
   If Value<>FFileName then
@@ -143,13 +143,13 @@
   end;
 end;
 
-Function TXmlRegistry.NormalizeKey(KeyPath : String) : String;
+Function TXmlRegistry.NormalizeKey(KeyPath : UnicodeString) : UnicodeString;
 
 Var
   L : Integer;
 
 begin
-  Result:=StringReplace(KeyPath,'\','/',[rfReplaceAll]);
+  Result:=UnicodeStringReplace(KeyPath,'\','/',[rfReplaceAll]);
   L:=Length(Result);
   If (L>0) and (Result[L]<>'/') then
     Result:=Result+'/';
@@ -157,10 +157,10 @@
     Result:='/' + Result;
 end;
 
-Function TXmlRegistry.SetKey(KeyPath : String; AllowCreate : Boolean) : boolean;
+Function TXmlRegistry.SetKey(KeyPath : UnicodeString; AllowCreate : Boolean) : boolean;
 
 Var
-  SubKey,ResultKey : String;
+  SubKey,ResultKey : UnicodeString;
   P : Integer;
   Node,Node2 : TDomElement;
 
@@ -218,7 +218,7 @@
   MaybeFlush;
 end;
 
-Procedure TXmlRegistry.SetRootKey(Value : String);
+Procedure TXmlRegistry.SetRootKey(Value : UnicodeString);
 
 begin
   FRootKey:=NormalizeKey(Value);
@@ -228,7 +228,7 @@
   FCurrentElement:=Nil;
 end;
 
-Function TXmlRegistry.DeleteKey(KeyPath : String) : Boolean;
+Function TXmlRegistry.DeleteKey(KeyPath : UnicodeString) : Boolean;
 
 Var
   N : TDomElement;
@@ -244,10 +244,10 @@
    end;
 end;
 
-Function TXmlRegistry.CreateKey(KeyPath : String) : Boolean;
+Function TXmlRegistry.CreateKey(KeyPath : UnicodeString) : Boolean;
 
 Var
-  SubKey : String;
+  SubKey : UnicodeString;
   P : Integer;
   Node,Node2 : TDomElement;
 
@@ -290,7 +290,7 @@
   MaybeFlush;
 end;
 
-Function TXmlRegistry.DoGetValueData(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer; IsUnicode : Boolean) : Boolean;
+Function TXmlRegistry.DoGetValueData(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer; IsUnicode : Boolean) : Boolean;
 
 Type
   PCardinal = ^Cardinal;
@@ -305,17 +305,22 @@
   D : DWord;
   
 begin
+  writeln('TXmlRegistry.DoGetValueData: Name=',Name,' IsUnicode=',IsUnicode);
   Node:=FindValueKey(Name);
   Result:=Node<>Nil;
   If Result then
     begin
+    writeln('TXmlRegistry.DoGetValueData: Node<>nil');
     DataNode:=Node.FirstChild;
     HasData:=Assigned(DataNode) and (DataNode.NodeType=TEXT_NODE);
+    writeln('TXmlRegistry.DoGetValueData: HasData=',hasdata);
     ND:=StrToIntDef(Node[Stype],0);
+    writeln('TXmlRegistry.DoGetValueData: ND=',ND);
     Result:=ND<=Ord(High(TDataType));
     If Result then
       begin
       DataType:=TDataType(ND);
+      writeln('TXmlRegistry.DoGetValueData: DataType=',DataType);
       NS:=0; // Initialize, for optional nodes.
       Case DataType of
         dtDWORD : begin   // DataNode is required
@@ -329,7 +334,7 @@
                      begin
                      if not IsUnicode then
                        begin
-                       S:=UTF8Encode(DataNode.NodeValue); // Convert to ansistring
+                       S:=DataNode.NodeValue; // Convert to ansistring
                        NS:=Length(S);
                        Result:=(DataSize>=NS);
                        if Result then
@@ -350,8 +355,10 @@
                    if HasData then
                      begin
                      BL:=Length(DataNode.NodeValue);
+                     writeln('TXmlRegistry.DoGetValueData: BL=',BL);
                      NS:=BL div 2;
                      Result:=DataSize>=NS;
+                     writeln('TXmlRegistry.DoGetValueData: Result=',Result);
                      If Result then
                        // No need to check for -1, We checked NS before calling.
                        NS:=HexToBuf(DataNode.NodeValue,Data,BL);
@@ -363,7 +370,7 @@
     end;
 end;
 
-Function TXmlRegistry.DoSetValueData(Name : String; DataType : TDataType; Const Data; DataSize : Integer; IsUnicode : Boolean) : Boolean;
+Function TXmlRegistry.DoSetValueData(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer; IsUnicode : Boolean) : Boolean;
 
 Type
   PCardinal = ^Cardinal;
@@ -390,7 +397,7 @@
                    SW:=UnicodeString(PUnicodeChar(@Data))
                  else
                    SW:=UnicodeString(PAnsiChar(@Data));
-                   //S:=UTF8Encode(SW);
+                   //S:=SW;
                  end;
       dtBinary : SW:=BufToHex(Data,DataSize);
       dtStrings : SW:=BufToHex(Data,DataSize);
@@ -416,29 +423,29 @@
     end;
 end;
 
-Function TXmlRegistry.SetValueData(Name : String; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
+Function TXmlRegistry.SetValueData(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
 
 begin
   Result:=DoSetValueData(Name,DataType,Data,DataSize,False);
 end;
 
-Function TXmlRegistry.GetValueData(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
+Function TXmlRegistry.GetValueData(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
 
 begin
   Result:=DoGetValueData(Name,DataType,Data,DataSize,False);
 end;
 
-function TXmlRegistry.GetValueDataUnicode(Name: String; out DataType: TDataType; Var Data; Var DataSize: Integer): Boolean;
+function TXmlRegistry.GetValueDataUnicode(Name: UnicodeString; out DataType: TDataType; Var Data; Var DataSize: Integer): Boolean;
 begin
   Result:=DoGetValueData(Name,DataType,Data,DataSize,True);
 end;
 
-function TXmlRegistry.SetValueDataUnicode(Name: String; DataType: TDataType; const Data; DataSize: Integer): Boolean;
+function TXmlRegistry.SetValueDataUnicode(Name: UnicodeString; DataType: TDataType; const Data; DataSize: Integer): Boolean;
 begin
   Result:=DoSetValueData(Name,DataType,Data,DataSize,True)
 end;
 
-Function TXmlRegistry.FindSubKey (S : String; N : TDomElement) : TDomElement;
+Function TXmlRegistry.FindSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
 
 Var
   Node : TDOMNode;
@@ -451,7 +458,7 @@
     While (Result=Nil) and (Assigned(Node)) do
       begin
       If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SKey) then
-        If CompareText(TDomElement(Node)[SName],S)=0 then
+        If UnicodeCompareText(TDomElement(Node)[SName],S)=0 then
           Result:=TDomElement(Node);
       Node:=Node.NextSibling;
       end;
@@ -458,7 +465,7 @@
     end;
 end;
 
-Function TXmlRegistry.CreateSubKey (S : String; N : TDomElement) : TDomElement;
+Function TXmlRegistry.CreateSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
 
 begin
   Result:=FDocument.CreateElement(SKey);
@@ -468,7 +475,7 @@
   FDirty:=True;
 end;
 
-Function  TXmlRegistry.FindValueKey (S : String) : TDomElement;
+Function  TXmlRegistry.FindValueKey (S : UnicodeString) : TDomElement;
 
 Var
   Node : TDOMNode;
@@ -481,7 +488,7 @@
     While (Result=Nil) and (Assigned(Node)) do
       begin
       If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SValue) then
-        If CompareText(TDomElement(Node)[SName],S)=0 then
+        If UnicodeCompareText(TDomElement(Node)[SName],S)=0 then
           Result:=TDomElement(Node);
       Node:=Node.NextSibling;
       end;
@@ -488,7 +495,7 @@
     end;
 end;
 
-Function  TXmlRegistry.CreateValueKey (S : String) : TDomElement;
+Function  TXmlRegistry.CreateValueKey (S : UnicodeString) : TDomElement;
 
 begin
   If Assigned(FCurrentElement) then
@@ -581,7 +588,7 @@
     end;
 end;
 
-Function TXMLRegistry.hexToBuf(Const Str : String; Var Buf; Var Len : Integer ) : Integer;
+Function TXMLRegistry.HexToBuf(Const Str : UnicodeString; Var Buf; Var Len : Integer ) : Integer;
 
 Var
   NLeN,I : Integer;
@@ -591,17 +598,22 @@
   Code : Integer;
 
 begin
+  writeln('TXMLRegistry.HexToBuf A: Str=',Str,', Len=',Len);
   Result:=0;
   P:=@Buf;
+  writeln('TXMLRegistry.HexToBuf B: (p=nil)=',p=nil);
   NLen:= Length(Str) div 2;
+  writeln('TXMLRegistry.HexToBuf C: NLen=',NLen,', SizeOf(TDateTime)=',SizeOf(TDateTime));
   If (NLen>Len) then
     begin
     Len:=NLen;
     Exit(-1);
     end;
-  For I:=0 to Len-1 do
+  For I:=0 to NLen-1 do
     begin
+    write('TXMLRegistry.HexToBuf: i=',i);
     S:='$'+Copy(Str,(I*2)+1,2);
+    writeln('TXMLRegistry.HexToBuf: S=',S);
     Val(S,B,Code);
     If Code<>0 then
       begin
@@ -612,7 +624,7 @@
     end;
 end;
 
-Function TXMLRegistry.DeleteValue(S : String) : Boolean;
+Function TXMLRegistry.DeleteValue(S : UnicodeString) : Boolean;
 
 Var
   N : TDomElement;
@@ -628,31 +640,31 @@
     end;
 end;
 
-Function TXMLRegistry.GetValueSize(Name : String) : Integer;
+Function TXMLRegistry.GetValueSize(Name : UnicodeString) : Integer;
 
 Var
   Info : TDataInfo;
 
 begin
-  If GetValueInfo(Name,Info) then
+  If GetValueInfo(Name,Info,True) then
     Result:=Info.DataSize
   else
     Result:=-1;
 end;
 
-Function TXMLRegistry.GetValueType(Name : String) : TDataType;
+Function TXMLRegistry.GetValueType(Name : UnicodeString) : TDataType;
 
 Var
   Info : TDataInfo;
 
 begin
-  If GetValueInfo(Name,Info) then
+  If GetValueInfo(Name,Info,True) then
     Result:=Info.DataType
   else
     Result:=dtUnknown;
 end;
 
-function TXmlRegistry.GetValueInfo(Name: String; out Info: TDataInfo; AsUnicode: Boolean): Boolean;
+function TXmlRegistry.GetValueInfo(Name: UnicodeString; out Info: TDataInfo; AsUnicode: Boolean): Boolean;
 
 Var
   N  : TDomElement;
@@ -671,7 +683,7 @@
         L:=Length(DN.NodeValue)*SizeOf(UnicodeChar)
       else
         begin
-        S := UTF8Encode(DN.NodeValue);
+        S := DN.NodeValue;
         L:=Length(S);
         end
       end
@@ -727,7 +739,7 @@
               Case TDataType(StrToIntDef(TDomElement(Node)[SType],0)) of
                 dtUnknown : L:=0;
                 dtDWord   : L:=4;
-                DtString  : L:=Length(UTF8Encode(DataNode.NodeValue));
+                DtString  : L:=Length(String(DataNode.NodeValue));
                 dtBinary  : L:=Length(DataNode.NodeValue) div 2;
               end
             else
@@ -782,13 +794,13 @@
     end;
 end;
 
-Function TXMLRegistry.KeyExists(KeyPath : String) : Boolean;
+Function TXMLRegistry.KeyExists(KeyPath : UnicodeString) : Boolean;
 
 begin
   Result:=FindKey(KeyPath)<>Nil;
 end;
 
-Function TXMLRegistry.RenameValue(Const OldName,NewName : String) : Boolean;
+Function TXMLRegistry.RenameValue(Const OldName,NewName : UnicodeString) : Boolean;
 
 Var
   N : TDomElement;
@@ -804,10 +816,10 @@
     end;
 end;
 
-Function TXMLRegistry.FindKey (S : String) : TDomElement;
+Function TXMLRegistry.FindKey (S : UnicodeString) : TDomElement;
 
 Var
-  SubKey : String;
+  SubKey : UnicodeString;
   P : Integer;
   Node : TDomElement;
 
@@ -840,7 +852,7 @@
   Until (Result=Nil) or (Length(S)=0);
 end;
 
-Function  TXmlRegistry.ValueExists(ValueName : String) : Boolean;
+Function  TXmlRegistry.ValueExists(ValueName : UnicodeString) : Boolean;
 
 begin
   Result:=FindValueKey(ValueName)<>Nil;
Index: packages/fcl-registry/src/xregreg.inc
===================================================================
--- packages/fcl-registry/src/xregreg.inc	(revision 41667)
+++ packages/fcl-registry/src/xregreg.inc	(working copy)
@@ -47,7 +47,7 @@
     Class Var XMLRegistryCache: Tlist;
     Class procedure FreeXMLRegistryCache;
   public
-    constructor Create(AFileName : String);
+    constructor Create(AFileName : UnicodeString);
     Class Function GetXMLRegistry(aFileName: string): TXMLRegistry;
     Class Procedure FreeXMLRegistry(XMLRegistry: TXMLRegistry);
     procedure IncRefCount;
@@ -97,7 +97,7 @@
 
 { TXMLRegistryInstance }
 
-constructor TXMLRegistryInstance.Create(AFileName: String);
+constructor TXMLRegistryInstance.Create(AFileName: UnicodeString);
 begin
   inherited;
   FRefCount := 1;
@@ -117,6 +117,7 @@
 var s : string;
 begin
   s:=includetrailingpathdelimiter(GetAppConfigDir(GlobalXMLFile));
+s:='.\';//**********UNDO THIS
   ForceDirectories(s);
   FSysData:=TXMLRegistryInstance.GetXMLRegistry(s+XFileName);
   TXmlRegistry(FSysData).AutoFlush:=False;
@@ -130,24 +131,24 @@
   TXMLRegistryInstance.FreeXMLRegistry(TXMLRegistry(FSysData));
 end;
 
-function TRegistry.SysCreateKey(const Key: String): Boolean;
+function TRegistry.SysCreateKey(Key: UnicodeString): Boolean;
 
 begin
   Result:=TXmlRegistry(FSysData).CreateKey(Key);
 end;
 
-function TRegistry.DeleteKey(const Key: string): Boolean;
+function TRegistry.DeleteKey(const Key: UnicodeString): Boolean;
 
 begin
   Result:=TXMLRegistry(FSysData).DeleteKey(Key);
 end;
 
-function TRegistry.DeleteValue(const Name: string): Boolean;
+function TRegistry.DeleteValue(const Name: UnicodeString): Boolean;
 begin
   Result:=TXmlRegistry(FSysData).DeleteValue(Name);
 end;
 
-function TRegistry.SysGetData(const Name: String; Buffer: Pointer;
+function TRegistry.SysGetData(const Name: UnicodeString; Buffer: Pointer;
           BufSize: Integer; Out RegData: TRegDataType): Integer;
 
 Var
@@ -160,7 +161,7 @@
     Result:=-1;
 end;
 
-function TRegistry.GetDataInfo(const ValueName: string; out Value: TRegDataInfo): Boolean;
+function TRegistry.GetDataInfo(const ValueName: UnicodeString; out Value: TRegDataInfo): Boolean;
 
 Var
   Info : TDataInfo;
@@ -181,7 +182,7 @@
       end;
 end;
 
-function TRegistry.GetKey(const Key: string): HKEY;
+function TRegistry.GetKey(Key: UnicodeString): HKEY;
 begin
   Result := 0;
 end;
@@ -205,17 +206,17 @@
       end;
 end;
 
-function TRegistry.KeyExists(const Key: string): Boolean;
+function TRegistry.KeyExists(const Key: UnicodeString): Boolean;
 begin
   Result:=TXmlRegistry(FSysData).KeyExists(Key);
 end;
 
-function TRegistry.LoadKey(const Key, FileName: string): Boolean;
+function TRegistry.LoadKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.OpenKey(const Key: string; CanCreate: Boolean): Boolean;
+function TRegistry.OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
 
 begin
   Result:=TXmlRegistry(FSysData).SetKey(Key,CanCreate);
@@ -222,43 +223,43 @@
   FCurrentKey:=1;
 end;
 
-function TRegistry.OpenKeyReadOnly(const Key: string): Boolean;
+function TRegistry.OpenKeyReadOnly(const Key: UnicodeString): Boolean;
 
 begin
   Result:=TXmlRegistry(FSysData).SetKey(Key,False);
 end;
 
-function TRegistry.RegistryConnect(const UNCName: string): Boolean;
+function TRegistry.RegistryConnect(const UNCName: UnicodeString): Boolean;
 begin
   Result := True;
 end;
 
-function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
+function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.RestoreKey(const Key, FileName: string): Boolean;
+function TRegistry.RestoreKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.SaveKey(const Key, FileName: string): Boolean;
+function TRegistry.SaveKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.UnLoadKey(const Key: string): Boolean;
+function TRegistry.UnLoadKey(const Key: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.ValueExists(const Name: string): Boolean;
+function TRegistry.ValueExists(const Name: UnicodeString): Boolean;
 begin
   Result := TXmlRegistry(FSysData).ValueExists(Name);
 end;
 
-procedure TRegistry.ChangeKey(Value: HKey; const Path: string);
+procedure TRegistry.ChangeKey(Value: HKey; const Path: UnicodeString);
 begin
 
 end;
@@ -274,7 +275,7 @@
 end;
 
 
-function TRegistry.SysPutData(const Name: string; Buffer: Pointer;
+function TRegistry.SysPutData(const Name: UnicodeString; Buffer: Pointer;
   BufSize: Integer; RegData: TRegDataType): Boolean;
 
 Var
@@ -285,7 +286,7 @@
   Result:=TXMLRegistry(FSysData).SetValueDataUnicode(Name,DataType,Buffer^,BufSize);
 end;
 
-procedure TRegistry.RenameValue(const OldName, NewName: string);
+procedure TRegistry.RenameValue(const OldName, NewName: UnicodeString);
 begin
   TXMLRegistry(FSysData).RenameValue(OldName,NewName);
 end;

Serge Anvarov

2019-03-16 02:50

reporter   ~0114855

Bart, the RegistryTest from 0034876 still doesn't work with this patch

Bart Broersma

2019-03-16 10:57

reporter   ~0114862

Last edited: 2019-03-16 17:20

View 4 revisions

I'm not finished yet.
Since there is no Unicode version of TStrings (yet), the plan is to implement
TRegistry.ReadStringArray(Name: UnicodeString): TUnicodeStringArray
and the corresponing write method.
These methods will ensure no data loss can happen.

Read/WriteStringList will then call Read/WriteStringArray.
Read/WriteStringList will get an option parameter ForceUtf8: Boolean=False.
If this is True then the List is treated as having Utf8 encoded strings (so Utf8Encode the result wehen reading and Utf8Decode the input when writing).

This then preserves behaviour on plain fpc programs, where by default (on Windows) string is not UTF8 but CP_ACP.
When you need Unicode and you insist on using TStrings, simplye set the boolean parameter to True.
On Lazarus it would not make any difference, since CP_ACP equals CP_UTF8.

So please have a little patience.

[ETA]registry.unicode.part4.diff should work if you set the optional parameter for Read/WriteStringList to True.

Bart Broersma

2019-03-16 12:30

reporter  

registry.unicode.part3.diff (60,913 bytes)
Index: packages/fcl-registry/src/regdef.inc
===================================================================
--- packages/fcl-registry/src/regdef.inc	(revision 41667)
+++ packages/fcl-registry/src/regdef.inc	(working copy)
@@ -2,7 +2,7 @@
   HKEY = THandle;
   PHKEY = ^HKEY;
   
-{$ifdef windows}
+{$if defined(windows) and not defined(XMLREG)}
 
 { Direct mapping to constants in Windows unit }
 
Index: packages/fcl-registry/src/registry.pp
===================================================================
--- packages/fcl-registry/src/registry.pp	(revision 41667)
+++ packages/fcl-registry/src/registry.pp	(working copy)
@@ -1,4 +1,5 @@
 Unit Registry;
+Unit uRegistry;
 
 {$mode objfpc}
 {$H+}
@@ -39,6 +40,8 @@
     DataSize: Integer;
   end;
 
+  TUnicodeStringArray = Array of UnicodeString;
+
 { ---------------------------------------------------------------------
     TRegistry
   ---------------------------------------------------------------------}
@@ -54,22 +57,29 @@
     fCurrentKey: HKEY;
     fRootKey: HKEY;
     fLazyWrite: Boolean;
-    fCurrentPath: string;
+    fCurrentPath: UnicodeString;
     function GetLastErrorMsg: string;
+    function RegMultiSzDataToUnicodeStringArray(U: UnicodeString): TUnicodeStringArray;
     procedure SetRootKey(Value: HKEY);
     Procedure SysRegCreate;
     Procedure SysRegFree;
-    Function  SysGetData(const Name: String; Buffer: Pointer; BufSize: Integer; Out RegData: TRegDataType): Integer;
-    Function  SysPutData(const Name: string; Buffer: Pointer; BufSize: Integer; RegData: TRegDataType) : Boolean;
-    Function  SysCreateKey(const Key: String): Boolean;
+    Function  SysGetData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; Out RegData: TRegDataType): Integer;
+    Function  SysPutData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; RegData: TRegDataType) : Boolean;
+    Function  SysCreateKey(Key: UnicodeString): Boolean;
   protected
     function GetBaseKey(Relative: Boolean): HKey;
-    function GetData(const Name: string; Buffer: Pointer;
+    function GetData(const Name: UnicodeString; Buffer: Pointer;
                   BufSize: Integer; Out RegData: TRegDataType): Integer;
-    function GetKey(const Key: string): HKEY;
-    procedure ChangeKey(Value: HKey; const Path: string);
-    procedure PutData(const Name: string; Buffer: Pointer;
+    function GetData(const Name: String; Buffer: Pointer;
+                  BufSize: Integer; Out RegData: TRegDataType): Integer;
+    function GetKey(Key: UnicodeString): HKEY;
+    function GetKey(Key: String): HKEY;
+    procedure ChangeKey(Value: HKey; const Path: UnicodeString);
+    procedure ChangeKey(Value: HKey; const Path: String);
+    procedure PutData(const Name: UnicodeString; Buffer: Pointer;
                   BufSize: Integer; RegData: TRegDataType);
+    procedure PutData(const Name: String; Buffer: Pointer;
+                  BufSize: Integer; RegData: TRegDataType);
     procedure SetCurrentKey(Value: HKEY);
   public
     constructor Create; overload;
@@ -76,58 +86,89 @@
     constructor Create(aaccess:longword); overload;
     destructor Destroy; override;
 
-    function CreateKey(const Key: string): Boolean;
-    function DeleteKey(const Key: string): Boolean;
-    function DeleteValue(const Name: string): Boolean;
-    function GetDataInfo(const ValueName: string; Out Value: TRegDataInfo): Boolean;
-    function GetDataSize(const ValueName: string): Integer;
-    function GetDataType(const ValueName: string): TRegDataType;
+    function CreateKey(const Key: UnicodeString): Boolean;
+    function CreateKey(const Key: String): Boolean;
+    function DeleteKey(const Key: UnicodeString): Boolean;
+    function DeleteKey(const Key: String): Boolean;
+    function DeleteValue(const Name: UnicodeString): Boolean;
+    function DeleteValue(const Name: String): Boolean;
+    function GetDataInfo(const ValueName: UnicodeString; Out Value: TRegDataInfo): Boolean;
+    function GetDataInfo(const ValueName: String; Out Value: TRegDataInfo): Boolean;
+    function GetDataSize(const ValueName: UnicodeString): Integer;
+    function GetDataSize(const ValueName: String): Integer;
+    function GetDataType(const ValueName: UnicodeString): TRegDataType;
+    function GetDataType(const ValueName: String): TRegDataType;
     function GetKeyInfo(Out Value: TRegKeyInfo): Boolean;
     function HasSubKeys: Boolean;
-    function KeyExists(const Key: string): Boolean;
-    function LoadKey(const Key, FileName: string): Boolean;
-    function OpenKey(const Key: string; CanCreate: Boolean): Boolean;
-    function OpenKeyReadOnly(const Key: string): Boolean;
-    function ReadCurrency(const Name: string): Currency;
-    function ReadBinaryData(const Name: string; var Buffer; BufSize: Integer): Integer;
-    function ReadBool(const Name: string): Boolean;
-    function ReadDate(const Name: string): TDateTime;
-    function ReadDateTime(const Name: string): TDateTime;
-    function ReadFloat(const Name: string): Double;
-    function ReadInteger(const Name: string): Integer;
-    function ReadInt64(const Name: string): Int64;
-    function ReadString(const Name: string): string;
-    procedure ReadStringList(const Name: string; AList: TStrings);
-    function ReadTime(const Name: string): TDateTime;
-    function RegistryConnect(const UNCName: string): Boolean;
-    function ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
-    function RestoreKey(const Key, FileName: string): Boolean;
-    function SaveKey(const Key, FileName: string): Boolean;
-    function UnLoadKey(const Key: string): Boolean;
-    function ValueExists(const Name: string): Boolean;
+    function KeyExists(const Key: UnicodeString): Boolean;
+    function KeyExists(const Key: String): Boolean;
+    function LoadKey(const Key, FileName: UnicodeString): Boolean;
+    function LoadKey(const Key, FileName: String): Boolean;
+    function OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
+    function OpenKey(const Key: String; CanCreate: Boolean): Boolean;
+    function OpenKeyReadOnly(const Key: UnicodeString): Boolean;
+    function OpenKeyReadOnly(const Key: String): Boolean;
+    function ReadCurrency(const Name: UnicodeString): Currency;
+    function ReadCurrency(const Name: String): Currency;
+    function ReadBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer): Integer;
+    function ReadBinaryData(const Name: String; var Buffer; BufSize: Integer): Integer;
+    function ReadBool(const Name: UnicodeString): Boolean;
+    function ReadBool(const Name: String): Boolean;
+    function ReadDate(const Name: UnicodeString): TDateTime;
+    function ReadDate(const Name: String): TDateTime;
+    function ReadDateTime(const Name: UnicodeString): TDateTime;
+    function ReadDateTime(const Name: String): TDateTime;
+    function ReadFloat(const Name: UnicodeString): Double;
+    function ReadFloat(const Name: String): Double;
+    function ReadInteger(const Name: UnicodeString): Integer;
+    function ReadInteger(const Name: String): Integer;
+    function ReadInt64(const Name: UnicodeString): Int64;
+    function ReadInt64(const Name: String): Int64;
+    function ReadString(const Name: UnicodeString): UnicodeString;
+    function ReadString(const Name: String): string;
+    procedure ReadStringList(const Name: UnicodeString; AList: TStrings; ForceUtf8: Boolean=False);
+    procedure ReadStringList(const Name: String; AList: TStrings);
+    function ReadStringArray(const Name: UnicodeString): TUnicodeStringArray;
+    function ReadStringArray(const Name: String): TStringArray;
+    function ReadTime(const Name: UnicodeString): TDateTime;
+    function ReadTime(const Name: String): TDateTime;
+    function RegistryConnect(const UNCName: UnicodeString): Boolean;
+    function RegistryConnect(const UNCName: String): Boolean;
+    function ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
+    function ReplaceKey(const Key, FileName, BackUpFileName: String): Boolean;
+    function RestoreKey(const Key, FileName: UnicodeString): Boolean;
+    function RestoreKey(const Key, FileName: String): Boolean;
+    function SaveKey(const Key, FileName: UnicodeString): Boolean;
+    function SaveKey(const Key, FileName: String): Boolean;
+    function UnLoadKey(const Key: UnicodeString): Boolean;
+    function UnLoadKey(const Key: String): Boolean;
+    function ValueExists(const Name: UnicodeString): Boolean;
+    function ValueExists(const Name: String): Boolean;
 
     procedure CloseKey;
     procedure CloseKey(key:HKEY);
     procedure GetKeyNames(Strings: TStrings);
     procedure GetValueNames(Strings: TStrings);
-    procedure MoveKey(const OldName, NewName: string; Delete: Boolean);
-    procedure RenameValue(const OldName, NewName: string);
-    procedure WriteCurrency(const Name: string; Value: Currency);
-    procedure WriteBinaryData(const Name: string; var Buffer; BufSize: Integer);
-    procedure WriteBool(const Name: string; Value: Boolean);
-    procedure WriteDate(const Name: string; Value: TDateTime);
-    procedure WriteDateTime(const Name: string; Value: TDateTime);
-    procedure WriteFloat(const Name: string; Value: Double);
-    procedure WriteInteger(const Name: string; Value: Integer);
-    procedure WriteInt64(const Name: string; Value: Int64);
-    procedure WriteString(const Name, Value: string);
-    procedure WriteExpandString(const Name, Value: string);
-    procedure WriteStringList(const Name: string; List: TStrings);
-    procedure WriteTime(const Name: string; Value: TDateTime);
+    procedure MoveKey(const OldName, NewName: UnicodeString; Delete: Boolean);
+    procedure RenameValue(const OldName, NewName: UnicodeString);
+    procedure WriteCurrency(const Name: UnicodeString; Value: Currency);
+    procedure WriteBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer);
+    procedure WriteBool(const Name: UnicodeString; Value: Boolean);
+    procedure WriteDate(const Name: UnicodeString; Value: TDateTime);
+    procedure WriteDateTime(const Name: UnicodeString; Value: TDateTime);
+    procedure WriteFloat(const Name: UnicodeString; Value: Double);
+    procedure WriteInteger(const Name: UnicodeString; Value: Integer);
+    procedure WriteInt64(const Name: UnicodeString; Value: Int64);
+    procedure WriteString(const Name, Value: UnicodeString);
+    procedure WriteExpandString(const Name, Value: UnicodeString);
+    procedure WriteStringList(const Name: UnicodeString; List: TStrings; IsUtf8: Boolean=False);
+    procedure WriteStringArray(const Name: UnicodeString; const Arr: TUnicodeStringArray);
+    procedure WriteStringArray(const Name: String; const Arr: TStringArray);
+    procedure WriteTime(const Name: UnicodeString; Value: TDateTime);
 
     property Access: LongWord read fAccess write fAccess;
     property CurrentKey: HKEY read fCurrentKey;
-    property CurrentPath: string read fCurrentPath;
+    property CurrentPath: UnicodeString read fCurrentPath;
     property LazyWrite: Boolean read fLazyWrite write fLazyWrite;
     property RootKey: HKEY read fRootKey write SetRootKey;
     Property StringSizeIncludesNull : Boolean read FStringSizeIncludesNull;
@@ -261,7 +302,7 @@
   inherited Destroy;
 end;
 
-function TRegistry.CreateKey(const Key: string): Boolean;
+function TRegistry.CreateKey(const Key: UnicodeString): Boolean;
 
 begin
   Result:=SysCreateKey(Key);
@@ -269,6 +310,27 @@
     Raise ERegistryException.CreateFmt(SRegCreateFailed, [Key]);
 end;
 
+function TRegistry.CreateKey(const Key: String): Boolean;
+begin
+  Result:=CreateKey(UnicodeString(Key));
+end;
+
+function TRegistry.DeleteKey(const Key: String): Boolean;
+begin
+  Result:=DeleteKey(UnicodeString(Key));
+end;
+
+function TRegistry.DeleteValue(const Name: String): Boolean;
+begin
+  Result:=DeleteValue(UnicodeString(Name));
+end;
+
+function TRegistry.GetDataInfo(const ValueName: String; out Value: TRegDataInfo
+  ): Boolean;
+begin
+  Result:=GetDataInfo(UnicodeString(ValueName), Value);
+end;
+
 function TRegistry.GetBaseKey(Relative: Boolean): HKey;
 begin
   If Relative and (CurrentKey<>0) Then
@@ -277,7 +339,7 @@
     Result := RootKey;
 end;
 
-function TRegistry.GetData(const Name: string; Buffer: Pointer; BufSize: Integer; out RegData: TRegDataType): Integer;
+function TRegistry.GetData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; out RegData: TRegDataType): Integer;
 begin
   Result:=SysGetData(Name,Buffer,BufSize,RegData);
   If (Result=-1) then
@@ -284,7 +346,24 @@
     Raise ERegistryException.CreateFmt(SRegGetDataFailed, [Name]);
 end;
 
-procedure TRegistry.PutData(const Name: string; Buffer: Pointer;
+function TRegistry.GetData(const Name: String; Buffer: Pointer;
+  BufSize: Integer; out RegData: TRegDataType): Integer;
+begin
+  Result:=GetData(UnicodeString(Name), Buffer, BufSize, RegData);
+end;
+
+function TRegistry.GetKey(Key: String): HKEY;
+begin
+  Result:=GetKey(UnicodeString(Key));
+end;
+
+procedure TRegistry.ChangeKey(Value: HKey; const Path: String);
+begin
+  ChangeKey(Value, UnicodeString(Path));
+end;
+
+
+procedure TRegistry.PutData(const Name: UnicodeString; Buffer: Pointer;
   BufSize: Integer; RegData: TRegDataType);
 
 begin
@@ -292,9 +371,15 @@
     Raise ERegistryException.CreateFmt(SRegSetDataFailed, [Name]);
 end;
 
+procedure TRegistry.PutData(const Name: String; Buffer: Pointer;
+  BufSize: Integer; RegData: TRegDataType);
+begin
+  PutData(UnicodeString(Name), Buffer, BufSize, RegData);
+end;
 
-function TRegistry.GetDataSize(const ValueName: string): Integer;
 
+function TRegistry.GetDataSize(const ValueName: UnicodeString): Integer;
+
 Var
   Info: TRegDataInfo;
 
@@ -305,8 +390,13 @@
     Result := -1;
 end;
 
-function TRegistry.GetDataType(const ValueName: string): TRegDataType;
+function TRegistry.GetDataSize(const ValueName: String): Integer;
+begin
+  Result:=GetDataSize(UnicodeString(ValueName));
+end;
 
+function TRegistry.GetDataType(const ValueName: UnicodeString): TRegDataType;
+
 Var
   Info: TRegDataInfo;
 
@@ -315,6 +405,32 @@
   Result:=Info.RegData;
 end;
 
+function TRegistry.GetDataType(const ValueName: String): TRegDataType;
+begin
+  Result:=GetDataType(UnicodeString(ValueName));
+end;
+
+
+function TRegistry.KeyExists(const Key: String): Boolean;
+begin
+  Result:=KeyExists(UnicodeString(Key));
+end;
+
+function TRegistry.LoadKey(const Key, FileName: String): Boolean;
+begin
+  Result:=LoadKey(UnicodeString(Key), UnicodeString(FileName));
+end;
+
+function TRegistry.OpenKey(const Key: String; CanCreate: Boolean): Boolean;
+begin
+  Result:=OpenKey(UnicodeString(Key), CanCreate);
+end;
+
+function TRegistry.OpenKeyReadOnly(const Key: String): Boolean;
+begin
+  Result:=OpenKeyReadOnly(UnicodeString(Key));
+end;
+
 function TRegistry.HasSubKeys: Boolean;
 
 Var
@@ -326,7 +442,7 @@
     Result:=(Info.NumSubKeys>0);
 end;
 
-function TRegistry.ReadBinaryData(const Name: string; var Buffer; BufSize: Integer): Integer;
+function TRegistry.ReadBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer): Integer;
 
 Var
   RegDataType: TRegDataType;
@@ -337,8 +453,14 @@
     Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
 end;
 
-function TRegistry.ReadInteger(const Name: string): Integer;
+function TRegistry.ReadBinaryData(const Name: String; var Buffer;
+  BufSize: Integer): Integer;
+begin
+  Result:=ReadBinaryData(UnicodeString(Name), Buffer, BufSize);
+end;
 
+function TRegistry.ReadInteger(const Name: UnicodeString): Integer;
+
 Var
   RegDataType: TRegDataType;
 
@@ -348,8 +470,13 @@
     Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
 end;
 
-function TRegistry.ReadInt64(const Name: string): Int64;
+function TRegistry.ReadInteger(const Name: String): Integer;
+begin
+  Result:=ReadInteger(UnicodeString(Name));
+end;
 
+function TRegistry.ReadInt64(const Name: UnicodeString): Int64;
+
 Var
   RegDataType: TRegDataType;
 
@@ -359,21 +486,36 @@
     Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
 end;
 
-function TRegistry.ReadBool(const Name: string): Boolean;
+function TRegistry.ReadInt64(const Name: String): Int64;
+begin
+  Result:=ReadInt64(UnicodeString(Name));
+end;
 
+function TRegistry.ReadBool(const Name: UnicodeString): Boolean;
+
 begin
   Result:=ReadInteger(Name)<>0;
 end;
 
-function TRegistry.ReadCurrency(const Name: string): Currency;
+function TRegistry.ReadBool(const Name: String): Boolean;
+begin
+  Result:=ReadBool(UnicodeString(Name));
+end;
 
+function TRegistry.ReadCurrency(const Name: UnicodeString): Currency;
+
 begin
   Result:=Default(Currency);
   ReadBinaryData(Name, Result, SizeOf(Currency));
 end;
 
-function TRegistry.ReadDate(const Name: string): TDateTime;
+function TRegistry.ReadCurrency(const Name: String): Currency;
+begin
+  Result:=ReadCurrency(UnicodeString(Name));
+end;
 
+function TRegistry.ReadDate(const Name: UnicodeString): TDateTime;
+
 begin
   Result:=Default(TDateTime);
   ReadBinaryData(Name, Result, SizeOf(TDateTime));
@@ -380,22 +522,37 @@
   Result:=Trunc(Result);
 end;
 
-function TRegistry.ReadDateTime(const Name: string): TDateTime;
+function TRegistry.ReadDate(const Name: String): TDateTime;
+begin
+  Result:=ReadDate(UnicodeString(Name));
+end;
 
+function TRegistry.ReadDateTime(const Name: UnicodeString): TDateTime;
+
 begin
   Result:=Default(TDateTime);
   ReadBinaryData(Name, Result, SizeOf(TDateTime));
 end;
 
-function TRegistry.ReadFloat(const Name: string): Double;
+function TRegistry.ReadDateTime(const Name: String): TDateTime;
+begin
+  Result:=ReadDateTime(UnicodeString(Name));
+end;
 
+function TRegistry.ReadFloat(const Name: UnicodeString): Double;
+
 begin
   Result:=Default(Double);
   ReadBinaryData(Name,Result,SizeOf(Double));
 end;
 
-function TRegistry.ReadString(const Name: string): string;
+function TRegistry.ReadFloat(const Name: String): Double;
+begin
+  Result:=ReadFloat(UnicodeString(Name));
+end;
 
+function TRegistry.ReadString(const Name: UnicodeString): UnicodeString;
+
 Var
   Info : TRegDataInfo;
   ReadDataSize: Integer;
@@ -421,27 +578,54 @@
       if StringSizeIncludesNull and
          (u[Length(u)] = WideChar(0)) then
         SetLength(u,Length(u)-1);
-      Result:=UTF8Encode(u);
+      Result:=u;
     end;
   end;
 end;
 
-procedure TRegistry.ReadStringList(const Name: string; AList: TStrings);
+function TRegistry.ReadString(const Name: String): string;
+begin
+  Result:=ReadString(UnicodeString(Name));
+end;
 
+//**************************REMOVE
+function DbgS(const S: UnicodeString): String;
+var
+  C: WideChar;
+begin
+  Result := format('[%5d] ',[StringCodePage((S))]);
+  for C in S do Result := Result + IntToHex(Word(C),4) + #32;
+  Result := TrimRight(Result);
+end;
+
+procedure TRegistry.ReadStringList(const Name: UnicodeString; AList: TStrings; ForceUtf8: Boolean=False);
+
 Var
   Info : TRegDataInfo;
-  ReadDataSize: Integer;
-  Data: string;
+  ReadDataSize, i: Integer;
+  Data: UnicodeString;
+  UArr: TUnicodeStringArray;
 
 begin
   AList.Clear;
+  UArr := ReadStringArray(Name);
+  for i := Low(UArr) to High(UArr) do
+  begin
+    if ForceUtf8 then
+      AList.Add(Utf8Encode(UArr[i]))
+    else
+      AList.Add(String(UArr[i]));
+  end;
+{
   GetDataInfo(Name,Info);
+  writeln('TRegistry.ReadStringList: datasize=',info.datasize);
   if info.datasize>0 then
     begin
      If Not (Info.RegData in [rdMultiString]) then
        Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
      SetLength(Data,Info.DataSize);
-     ReadDataSize := GetData(Name,PChar(Data),Info.DataSize,Info.RegData);
+     ReadDataSize := GetData(Name,PWideChar(Data),Info.DataSize,Info.RegData) div SizeOf(WideChar);
+     writeln('TRegistry.ReadStringList: ReadDataSize=',ReadDataSize);
      if ReadDataSize > 0 then
      begin
        // If the data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type,
@@ -454,95 +638,253 @@
            Dec(ReadDataSize);
        end;
        SetLength(Data, ReadDataSize);
-       Data := StringReplace(Data, #0, LineEnding, [rfReplaceAll]);
+       writeln('Data=',dbgs(data));
+       Data := UnicodeStringReplace(Data, #0, AList.LineBreak, [rfReplaceAll]);
        AList.Text := Data;
      end
    end
+}
 end;
 
-function TRegistry.ReadTime(const Name: string): TDateTime;
+procedure TRegistry.ReadStringList(const Name: String; AList: TStrings);
+begin
+  ReadStringList(UnicodeString(Name), AList);
+end;
 
+function TRegistry.RegMultiSzDataToUnicodeStringArray(U: UnicodeString): TUnicodeStringArray;
+var
+  Len, i, p: Integer;
+  Sub: UnicodeString;
 begin
+  Result := nil;
+  if (U = '') then Exit;
+  Len := 1;
+  for i := 1 to Length(U) do if (U[i] = #0) then Inc(Len);
+  SetLength(Result, Len);
+  i := 0;
+
+  while (U <> '') and (i < Length(Result)) do
+  begin
+    p := Pos(#0, U);
+    if (p = 0) then p := Length(U) + 1;
+    Sub := Copy(U, 1, p - 1);
+    Result[i] := Sub;
+    System.Delete(U, 1, p);
+    Inc(i);
+  end;
+end;
+
+function TRegistry.ReadStringArray(const Name: UnicodeString): TUnicodeStringArray;
+Var
+  Info : TRegDataInfo;
+  ReadDataSize, i: Integer;
+  Data: UnicodeString;
+
+begin
+  Result := nil;
+  GetDataInfo(Name,Info);
+  writeln('TRegistry.ReadStringArray: datasize=',info.datasize);
+  if info.datasize>0 then
+    begin
+     If Not (Info.RegData in [rdMultiString]) then
+       Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
+     SetLength(Data,Info.DataSize);
+     ReadDataSize := GetData(Name,PWideChar(Data),Info.DataSize,Info.RegData) div SizeOf(WideChar);
+     writeln('TRegistry.ReadStringArray: ReadDataSize=',ReadDataSize);
+     if ReadDataSize > 0 then
+     begin
+       // Windows returns the data with or without trailing zero's, so just strip all trailing null characters
+        while (Data[ReadDataSize] = #0) do Dec(ReadDataSize);
+       SetLength(Data, ReadDataSize);
+       writeln('Data=',dbgs(data));
+       //Data := UnicodeStringReplace(Data, #0, AList.LineBreak, [rfReplaceAll]);
+       //AList.Text := Data;
+       Result := RegMultiSzDataToUnicodeStringArray(Data);
+     end
+   end
+end;
+
+function TRegistry.ReadStringArray(const Name: String): TStringArray;
+var
+  UArr: TUnicodeStringArray;
+  i: Integer;
+begin
+  Result := nil;
+  UArr := ReadStringArray(UnicodeString(Name));
+  SetLength(Result, Length(UArr));
+  for i := Low(UArr) to High(UArr) do Result[i] := UArr[i];
+end;
+
+function TRegistry.ReadTime(const Name: UnicodeString): TDateTime;
+
+begin
   Result:=Default(TDateTime);
   ReadBinaryData(Name, Result, SizeOf(TDateTime));
   Result:=Frac(Result);
 end;
 
-procedure TRegistry.WriteBinaryData(const Name: string; var Buffer; BufSize: Integer);
+function TRegistry.ReadTime(const Name: String): TDateTime;
 begin
+  Result:=ReadTime(UnicodeString(Name));
+end;
+
+function TRegistry.RegistryConnect(const UNCName: String): Boolean;
+begin
+  Result:=RegistryConnect(UnicodeString(UNCName));
+end;
+
+function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: String): Boolean;
+begin
+  Result:=ReplaceKey(UnicodeString(Key), UnicodeString(FileName), UnicodeString(BackUpFileName))
+end;
+
+function TRegistry.RestoreKey(const Key, FileName: String): Boolean;
+begin
+  Result:=RestoreKey(UnicodeString(Key), UnicodeString(FileName));
+end;
+
+function TRegistry.SaveKey(const Key, FileName: String): Boolean;
+begin
+  Result:=SaveKey(UnicodeString(Key), UnicodeString(FileName));
+end;
+
+function TRegistry.UnLoadKey(const Key: String): Boolean;
+begin
+  Result:=UnloadKey(UnicodeString(Key));
+end;
+
+function TRegistry.ValueExists(const Name: String): Boolean;
+begin
+  Result:=ValueExists(UnicodeString(Name));
+end;
+
+procedure TRegistry.WriteBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer);
+begin
   PutData(Name, @Buffer, BufSize, rdBinary);
 end;
 
-procedure TRegistry.WriteBool(const Name: string; Value: Boolean);
+procedure TRegistry.WriteBool(const Name: UnicodeString; Value: Boolean);
 
 begin
   WriteInteger(Name,Ord(Value));
 end;
 
-procedure TRegistry.WriteCurrency(const Name: string; Value: Currency);
+procedure TRegistry.WriteCurrency(const Name: UnicodeString; Value: Currency);
 begin
   WriteBinaryData(Name, Value, SizeOf(Currency));
 end;
 
-procedure TRegistry.WriteDate(const Name: string; Value: TDateTime);
+procedure TRegistry.WriteDate(const Name: UnicodeString; Value: TDateTime);
 begin
   WriteBinarydata(Name, Value, SizeOf(TDateTime));
 end;
 
-procedure TRegistry.WriteTime(const Name: string; Value: TDateTime);
+procedure TRegistry.WriteTime(const Name: UnicodeString; Value: TDateTime);
 begin
   WriteBinaryData(Name, Value, SizeOf(TDateTime));
 end;
 
-procedure TRegistry.WriteDateTime(const Name: string; Value: TDateTime);
+procedure TRegistry.WriteDateTime(const Name: UnicodeString; Value: TDateTime);
 begin
   WriteBinaryData(Name, Value, SizeOf(TDateTime));
 end;
 
-procedure TRegistry.WriteExpandString(const Name, Value: string);
-var
-  u: UnicodeString;
-
+procedure TRegistry.WriteExpandString(const Name, Value: UnicodeString);
 begin
-  u:=Value;
-  PutData(Name, PWideChar(u), ByteLength(u), rdExpandString);
+  PutData(Name, PWideChar(Value), ByteLength(Value), rdExpandString);
 end;
 
-procedure TRegistry.WriteStringList(const Name: string; List: TStrings);
 
+procedure TRegistry.WriteStringList(const Name: UnicodeString; List: TStrings; IsUtf8: Boolean=False);
+
 Var
-  Data: string;
+  Data: UnicodeString;
+  u: UnicodeString;
+  UArr: TUnicodeStringArray;
+  i, Len: Integer;
+begin
+  Data := '';
+  UArr := nil;
+  //REG_MULTI_SZ data cannot contain empty strings
+  Len := List.Count;
+  SetLength(UArr, Len);
+  for i := 0 to List.Count - 1 do
+  begin
+    if IsUtf8 then
+      u := Utf8Decode(List[i])
+    else
+      u := List[i];
+    if (u>'') then
+    begin
+      if (Data>'') then
+        Data := Data + #0 + u
+      else
+        Data := Data + u;
+    end
+    else
+      Dec(Len);
+  end;
+  if (Len <> List.Count) then SetLength(UArr, Len);
+  WriteStringArray(Name, UArr);
+end;
 
+procedure TRegistry.WriteStringArray(const Name: UnicodeString; const Arr: TUnicodeStringArray);
+Var
+  Data: UnicodeString;
+  u: UnicodeString;
+  i: Integer;
 begin
-  Data := StringReplace(List.Text, LineEnding, #0, [rfReplaceAll]) + #0#0;
-  PutData(Name, PChar(Data), Length(Data),rdMultiString);
+  Data := '';
+  //REG_MULTI_SZ data cannot contain empty strings
+  for i := Low(Arr) to High(Arr) do
+  begin
+    u := Arr[i];
+    if (u>'') then
+    begin
+      if (Data>'') then
+        Data := Data + #0 + u
+      else
+        Data := Data + u;
+    end;
+  end;
+  if StringSizeIncludesNull then
+    Data := Data + #0#0;
+  //writeln('Data=',Dbgs(Data));
+  PutData(Name, PWideChar(Data), ByteLength(Data), rdMultiString);
 end;
 
-procedure TRegistry.WriteFloat(const Name: string; Value: Double);
+procedure TRegistry.WriteStringArray(const Name: String; const Arr: TStringArray);
+var
+  UArr: TUnicodeStringArray;
+  i: Integer;
 begin
+  UArr := nil;
+  SetLength(UArr, Length(Arr));
+  for i := Low(Arr) to High(Arr) do UArr[i] := Arr[i];
+  WriteStringArray(UnicodeString(Name), UArr);
+end;
+
+procedure TRegistry.WriteFloat(const Name: UnicodeString; Value: Double);
+begin
   WriteBinaryData(Name, Value, SizeOf(Double));
 end;
 
-procedure TRegistry.WriteInteger(const Name: string; Value: Integer);
+procedure TRegistry.WriteInteger(const Name: UnicodeString; Value: Integer);
 begin
   PutData(Name, @Value, SizeOf(Integer), rdInteger);
 end;
 
-procedure TRegistry.WriteInt64(const Name: string; Value: Int64);
+procedure TRegistry.WriteInt64(const Name: UnicodeString; Value: Int64);
 begin
   PutData(Name, @Value, SizeOf(Int64), rdInt64);
 end;
 
-procedure TRegistry.WriteString(const Name, Value: string);
-var
-  u: UnicodeString;
-
+procedure TRegistry.WriteString(const Name, Value: UnicodeString);
 begin
-  u:=Value;
-  PutData(Name, PWideChar(u), ByteLength(u), rdString);
+  PutData(Name, PWideChar(Value), ByteLength(Value), rdString);
 end;
 
-procedure TRegistry.MoveKey(const OldName, NewName: string; Delete: Boolean);
+procedure TRegistry.MoveKey(const OldName, NewName: UnicodeString; Delete: Boolean);
 begin
 
 end;
@@ -583,7 +925,7 @@
   Value: TStream): Integer;
 begin
   result:=-1; // unimplemented
- // 
+ //
 end;
 
 function TRegistryIniFile.ReadDate(const Section, Name: string;
Index: packages/fcl-registry/src/winreg.inc
===================================================================
--- packages/fcl-registry/src/winreg.inc	(revision 41667)
+++ packages/fcl-registry/src/winreg.inc	(working copy)
@@ -1,7 +1,7 @@
 Const
   RegDataWords : Array [TRegDataType] of DWORD
                = (REG_NONE,REG_SZ,REG_EXPAND_SZ,REG_BINARY,REG_DWORD,REG_DWORD_BIG_ENDIAN,
-                  REG_LINK,REG_MULTI_SZ,REG_RESOURCE_LIST,REG_FULL_RESOURCE_DESCRIPTOR,REG_RESOURCE_REQUIREMENTS_LIST,REG_QWORD);
+                  REG_LINK,REG_MULTI_SZ,REG_RESOURCE_LIST,REG_FULL_RESOURCE_DESCRIPTOR,REG_RESOURCE_REQUIREMENTS_LIST,11{REG_QWORD}); //*****UNDO THIS!
 
 type
   TWinRegData = record
@@ -28,7 +28,7 @@
   Dispose(PWinRegData(FSysData));
 end;
 
-Function PrepKey(Const S : String) : String;
+Function PrepKey(Const S : UnicodeString) : UnicodeString;
 
 begin
   Result := S;
@@ -36,7 +36,7 @@
     System.Delete(Result, 1, 1);
 end;
 
-Function RelativeKey(Const S : String) : Boolean;
+Function RelativeKey(Const S : UnicodeString) : Boolean;
 
 begin
   Result:=(S='') or (S[1]<>'\')
@@ -43,7 +43,7 @@
 end;
 
 
-function TRegistry.sysCreateKey(const Key: String): Boolean;
+function TRegistry.sysCreateKey(Key: UnicodeString): Boolean;
 Var
   u: UnicodeString;
   Disposition: Dword;
@@ -52,9 +52,9 @@
 
 begin
   SecurityAttributes := Nil;
-  u:=PrepKey(Key);
+  Key:=PrepKey(Key);
   FLastError:=RegCreateKeyExW(GetBaseKey(RelativeKey(Key)),
-                              PWideChar(u),
+                              PWideChar(Key),
                               0,
                               '',
                               REG_OPTION_NON_VOLATILE,
@@ -66,7 +66,7 @@
   RegCloseKey(Handle);
 end;
 
-function TRegistry.DeleteKey(const Key: String): Boolean;
+function TRegistry.DeleteKey(const Key: UnicodeString): Boolean;
 
 Var
   u: UnicodeString;
@@ -76,21 +76,21 @@
   Result:=FLastError=ERROR_SUCCESS;
 end;
 
-function TRegistry.DeleteValue(const Name: String): Boolean;
+
+function TRegistry.DeleteValue(const Name: UnicodeString): Boolean;
 begin
-  FLastError:= RegDeleteValueW(fCurrentKey, PWideChar(UnicodeString(Name)));
+  FLastError:= RegDeleteValueW(fCurrentKey, PWideChar(Name));
   Result:=FLastError=ERROR_SUCCESS;
 end;
 
-function TRegistry.SysGetData(const Name: String; Buffer: Pointer;
+
+function TRegistry.SysGetData(const Name: UnicodeString; Buffer: Pointer;
           BufSize: Integer; Out RegData: TRegDataType): Integer;
 Var
-  u: UnicodeString;
   RD : DWord;
 
 begin
-  u := Name;
-  FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(u),Nil,
+  FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(Name),Nil,
                       @RD,Buffer,lpdword(@BufSize));
   if (FLastError<>ERROR_SUCCESS) Then
     Result:=-1
@@ -103,17 +103,15 @@
     end;
 end;
 
-function TRegistry.GetDataInfo(const ValueName: String; out Value: TRegDataInfo): Boolean;
+function TRegistry.GetDataInfo(const ValueName: UnicodeString; out Value: TRegDataInfo): Boolean;
 
 Var
-  u: UnicodeString;
   RD : DWord;
 
 begin
-  u:=ValueName;
   With Value do
     begin
-    FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(u),Nil,lpdword(@RegData),Nil,lpdword(@DataSize));
+    FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(ValueName),Nil,lpdword(@RegData),Nil,lpdword(@DataSize));
     Result:=FLastError=ERROR_SUCCESS;
     if Result then
       begin
@@ -131,24 +129,18 @@
 end;
 
 
-function TRegistry.GetKey(const Key: String): HKEY;
+function TRegistry.GetKey(Key: UnicodeString): HKEY;
 var
-  S : string;
-{$ifndef WinCE}
-  u : UnicodeString;
-{$endif}
   Rel : Boolean;
 begin
   Result:=0;
-  S:=Key;
-  Rel:=RelativeKey(S);
+  Rel:=RelativeKey(Key);
   if not(Rel) then
-    Delete(S,1,1);
+    Delete(Key,1,1);
 {$ifdef WinCE}
-  FLastError:=RegOpenKeyEx(GetBaseKey(Rel),PWideChar(WideString(S)),0,FAccess,Result);
+  FLastError:=RegOpenKeyEx(GetBaseKey(Rel),PWideChar(Key),0,FAccess,Result);
 {$else WinCE}
-  u:=UnicodeString(S);
-  FLastError:=RegOpenKeyExW(GetBaseKey(Rel),PWideChar(u),0,FAccess,Result);
+  FLastError:=RegOpenKeyExW(GetBaseKey(Rel),PWideChar(Key),0,FAccess,Result);
 {$endif WinCE}
 end;
 
@@ -174,7 +166,7 @@
 end;
 
 
-function TRegistry.KeyExists(const Key: string): Boolean;
+function TRegistry.KeyExists(const Key: UnicodeString): Boolean;
 var
   KeyHandle : HKEY;
   OldAccess : LONG;
@@ -196,20 +188,20 @@
 end;
 
 
-function TRegistry.LoadKey(const Key, FileName: string): Boolean;
+function TRegistry.LoadKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
 
-function TRegistry.OpenKey(const Key: string; CanCreate: Boolean): Boolean;
 
+function TRegistry.OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
+
 Var
-  u: UnicodeString;
+  u, S: UnicodeString;
   Handle: HKEY;
   Disposition: Integer;
   SecurityAttributes: Pointer; //LPSECURITY_ATTRIBUTES;
-  S: string;
 begin
   SecurityAttributes := Nil;
   u:=PrepKey(Key);
@@ -232,13 +224,14 @@
     if RelativeKey(Key) then
       S:=CurrentPath + Key
     else
-      S:=UTF8Encode(u);
+      S:=u;
     ChangeKey(Handle, S);
   end;
 end;
 
-function TRegistry.OpenKeyReadOnly(const Key: string): Boolean;
 
+function TRegistry.OpenKeyReadOnly(const Key: UnicodeString): Boolean;
+
 Var
   OldAccess: LongWord;
 begin
@@ -251,7 +244,8 @@
   end;
 end;
 
-function TRegistry.RegistryConnect(const UNCName: string): Boolean;
+
+function TRegistry.RegistryConnect(const UNCName: UnicodeString): Boolean;
 {$ifndef WinCE}
 var
   newroot: HKEY;
@@ -260,7 +254,7 @@
 {$ifdef WinCE}
   Result:=False;
 {$else}
-  FLastError:=RegConnectRegistryW(PWideChar(UnicodeString(UNCName)),RootKey,newroot);
+  FLastError:=RegConnectRegistryW(PWideChar(UNCName),RootKey,newroot);
   Result:=FLastError=ERROR_SUCCESS;
   if Result then begin
     RootKey:=newroot;
@@ -269,28 +263,33 @@
 {$endif}
 end;
 
-function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
+
+function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.RestoreKey(const Key, FileName: string): Boolean;
+
+function TRegistry.RestoreKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.SaveKey(const Key, FileName: string): Boolean;
+
+function TRegistry.SaveKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.UnLoadKey(const Key: string): Boolean;
+
+function TRegistry.UnLoadKey(const Key: UnicodeString): Boolean;
 begin
   Result := false;
 end;
 
-function TRegistry.ValueExists(const Name: string): Boolean;
 
+function TRegistry.ValueExists(const Name: UnicodeString): Boolean;
+
 var
   Info : TRegDataInfo;
 
@@ -298,6 +297,7 @@
   Result:=GetDataInfo(Name,Info);
 end;
 
+
 procedure TRegistry.CloseKey;
 begin
   If (CurrentKey<>0) then
@@ -316,7 +316,7 @@
   RegCloseKey(key);
 end;
 
-procedure TRegistry.ChangeKey(Value: HKey; const Path: String);
+procedure TRegistry.ChangeKey(Value: HKey; const Path: UnicodeString);
 begin
   CloseKey;
   FCurrentKey:=Value;
@@ -323,6 +323,7 @@
   FCurrentPath:=Path;
 end;
 
+
 procedure TRegistry.GetKeyNames(Strings: TStrings);
 
 var
@@ -410,12 +411,11 @@
 end;
 
 
-Function TRegistry.SysPutData(const Name: string; Buffer: Pointer;
+Function TRegistry.SysPutData(const Name: UnicodeString; Buffer: Pointer;
   BufSize: Integer; RegData: TRegDataType) : Boolean;
 
 
 Var
-  u: UnicodeString;
   RegDataType: DWORD;
   B : Pchar;
   S : String;
@@ -422,12 +422,11 @@
 
 begin
   RegDataType:=RegDataWords[RegData];
-  u:=UnicodeString(Name);
-  FLastError:=RegSetValueExW(fCurrentKey,PWideChar(u),0,RegDataType,Buffer,BufSize);
+  FLastError:=RegSetValueExW(fCurrentKey,PWideChar(Name),0,RegDataType,Buffer,BufSize);
   Result:=FLastError=ERROR_SUCCESS;
 end;
 
-procedure TRegistry.RenameValue(const OldName, NewName: string);
+procedure TRegistry.RenameValue(const OldName, NewName: UnicodeString);
 
 var
   L: Integer;
Index: packages/fcl-registry/src/xmlreg.pp
===================================================================
--- packages/fcl-registry/src/xmlreg.pp	(revision 41667)
+++ packages/fcl-registry/src/xmlreg.pp	(working copy)
@@ -32,54 +32,54 @@
   Private
     FAutoFlush,
     FDirty : Boolean;
-    FFileName : String;
-    FRootKey : String;
+    FFileName : UnicodeString;
+    FRootKey : UnicodeString;
     FDocument : TXMLDocument;
     FCurrentElement : TDomElement;
-    FCurrentKey : String;
-    Procedure SetFileName(Value : String);
+    FCurrentKey : UnicodeString;
+    Procedure SetFileName(Value : UnicodeString);
   Protected
-    function DoGetValueData(Name: String; out DataType: TDataType; Var Data; Var DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
-    function DoSetValueData(Name: String; DataType: TDataType; const Data; DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
+    function DoGetValueData(Name: UnicodeString; out DataType: TDataType; Var Data; Var DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
+    function DoSetValueData(Name: UnicodeString; DataType: TDataType; const Data; DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
     Procedure LoadFromStream(S : TStream);
-    Function  NormalizeKey(KeyPath : String) : String;
+    Function  NormalizeKey(KeyPath : UnicodeString) : UnicodeString;
     Procedure CreateEmptyDoc;
-    Function  FindKey (S : String) : TDomElement;
-    Function  FindSubKey (S : String; N : TDomElement) : TDomElement;
-    Function  CreateSubKey (S : String; N : TDomElement) : TDomElement;
-    Function  FindValueKey (S : String) : TDomElement;
-    Function  CreateValueKey (S : String) : TDomElement;
+    Function  FindKey (S : UnicodeString) : TDomElement;
+    Function  FindSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
+    Function  CreateSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
+    Function  FindValueKey (S : UnicodeString) : TDomElement;
+    Function  CreateValueKey (S : UnicodeString) : TDomElement;
     Function  BufToHex(Const Buf; Len : Integer) : String;
-    Function  hexToBuf(Const Str : String; Var Buf; Var Len : Integer ) : Integer;
+    Function  HexToBuf(Const Str : UnicodeString; Var Buf; Var Len : Integer ) : Integer;
     Procedure MaybeFlush;
     Property  Document : TXMLDocument Read FDocument;
     Property  Dirty : Boolean Read FDirty write FDirty;
   Public
-    Constructor Create(AFileName : String);
+    Constructor Create(AFileName : UnicodeString);
     Destructor  Destroy;override;
-    Function  SetKey(KeyPath : String; AllowCreate : Boolean) : Boolean ;
-    Procedure SetRootKey(Value : String);
-    Function  DeleteKey(KeyPath : String) : Boolean;
-    Function  CreateKey(KeyPath : String) : Boolean;
-    Function  GetValueSize(Name : String) : Integer;
-    Function  GetValueType(Name : String) : TDataType;
-    Function  GetValueInfo(Name : String; Out Info : TDataInfo; AsUnicode : Boolean = False) : Boolean;
+    Function  SetKey(KeyPath : UnicodeString; AllowCreate : Boolean) : Boolean ;
+    Procedure SetRootKey(Value : UnicodeString);
+    Function  DeleteKey(KeyPath : UnicodeString) : Boolean;
+    Function  CreateKey(KeyPath : UnicodeString) : Boolean;
+    Function  GetValueSize(Name : UnicodeString) : Integer;
+    Function  GetValueType(Name : UnicodeString) : TDataType;
+    Function  GetValueInfo(Name : UnicodeString; Out Info : TDataInfo; AsUnicode : Boolean = False) : Boolean;
     Function  GetKeyInfo(Out Info : TKeyInfo) : Boolean;
     Function  EnumSubKeys(List : TStrings) : Integer;
     Function  EnumValues(List : TStrings) : Integer;
-    Function  KeyExists(KeyPath : String) : Boolean;
-    Function  ValueExists(ValueName : String) : Boolean;
-    Function  RenameValue(Const OldName,NewName : String) : Boolean;
-    Function  DeleteValue(S : String) : Boolean;
+    Function  KeyExists(KeyPath : UnicodeString) : Boolean;
+    Function  ValueExists(ValueName : UnicodeString) : Boolean;
+    Function  RenameValue(Const OldName,NewName : UnicodeString) : Boolean;
+    Function  DeleteValue(S : UnicodeString) : Boolean;
     Procedure Flush;
     Procedure Load;
-    Function GetValueData(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
-    Function SetValueData(Name : String; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
+    Function GetValueData(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
+    Function SetValueData(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
     // These interpret the Data buffer as unicode data
-    Function GetValueDataUnicode(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
-    Function SetValueDataUnicode(Name : String; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
-    Property FileName : String Read FFileName Write SetFileName;
-    Property RootKey : String Read FRootKey Write SetRootkey;
+    Function GetValueDataUnicode(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
+    Function SetValueDataUnicode(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
+    Property FileName : UnicodeString Read FFileName Write SetFileName;
+    Property RootKey : UnicodeString Read FRootKey Write SetRootkey;
     Property AutoFlush : Boolean Read FAutoFlush Write FAutoFlush;
   end;
 
@@ -96,7 +96,7 @@
 Implementation
 
 
-Constructor TXmlRegistry.Create(AFileName : String);
+Constructor TXmlRegistry.Create(AFileName : UnicodeString);
 
 begin
   FFileName:=AFileName;
@@ -113,7 +113,7 @@
   inherited Destroy;
 end;
 
-Procedure TXmlRegistry.SetFileName(Value : String);
+Procedure TXmlRegistry.SetFileName(Value : UnicodeString);
 
 begin
   If Value<>FFileName then
@@ -143,13 +143,13 @@
   end;
 end;
 
-Function TXmlRegistry.NormalizeKey(KeyPath : String) : String;
+Function TXmlRegistry.NormalizeKey(KeyPath : UnicodeString) : UnicodeString;
 
 Var
   L : Integer;
 
 begin
-  Result:=StringReplace(KeyPath,'\','/',[rfReplaceAll]);
+  Result:=UnicodeStringReplace(KeyPath,'\','/',[rfReplaceAll]);
   L:=Length(Result);
   If (L>0) and (Result[L]<>'/') then
     Result:=Result+'/';
@@ -157,10 +157,10 @@
     Result:='/' + Result;
 end;
 
-Function TXmlRegistry.SetKey(KeyPath : String; AllowCreate : Boolean) : boolean;
+Function TXmlRegistry.SetKey(KeyPath : UnicodeString; AllowCreate : Boolean) : boolean;
 
 Var
-  SubKey,ResultKey : String;
+  SubKey,ResultKey : UnicodeString;
   P : Integer;
   Node,Node2 : TDomElement;
 
@@ -218,7 +218,7 @@
   MaybeFlush;
 end;
 
-Procedure TXmlRegistry.SetRootKey(Value : String);
+Procedure TXmlRegistry.SetRootKey(Value : UnicodeString);
 
 begin
   FRootKey:=NormalizeKey(Value);
@@ -228,7 +228,7 @@
   FCurrentElement:=Nil;
 end;
 
-Function TXmlRegistry.DeleteKey(KeyPath : String) : Boolean;
+Function TXmlRegistry.DeleteKey(KeyPath : UnicodeString) : Boolean;
 
 Var
   N : TDomElement;
@@ -244,10 +244,10 @@
    end;
 end;
 
-Function TXmlRegistry.CreateKey(KeyPath : String) : Boolean;
+Function TXmlRegistry.CreateKey(KeyPath : UnicodeString) : Boolean;
 
 Var
-  SubKey : String;
+  SubKey : UnicodeString;
   P : Integer;
   Node,Node2 : TDomElement;
 
@@ -290,7 +290,7 @@
   MaybeFlush;
 end;
 
-Function TXmlRegistry.DoGetValueData(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer; IsUnicode : Boolean) : Boolean;
+Function TXmlRegistry.DoGetValueData(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer; IsUnicode : Boolean) : Boolean;
 
 Type
   PCardinal = ^Cardinal;
@@ -305,22 +305,27 @@
   D : DWord;
   
 begin
+  //writeln('TXmlRegistry.DoGetValueData: Name=',Name,' IsUnicode=',IsUnicode);
   Node:=FindValueKey(Name);
   Result:=Node<>Nil;
   If Result then
     begin
+    //writeln('TXmlRegistry.DoGetValueData: Node<>nil');
     DataNode:=Node.FirstChild;
     HasData:=Assigned(DataNode) and (DataNode.NodeType=TEXT_NODE);
-    ND:=StrToIntDef(Node[Stype],0);
+    //writeln('TXmlRegistry.DoGetValueData: HasData=',hasdata);
+    ND:=StrToIntDef(String(Node[Stype]),0);
+    //writeln('TXmlRegistry.DoGetValueData: ND=',ND);
     Result:=ND<=Ord(High(TDataType));
     If Result then
       begin
       DataType:=TDataType(ND);
+      //writeln('TXmlRegistry.DoGetValueData: DataType=',DataType);
       NS:=0; // Initialize, for optional nodes.
       Case DataType of
         dtDWORD : begin   // DataNode is required
                   NS:=SizeOf(Cardinal);
-                  Result:=HasData and TryStrToDWord(DataNode.NodeValue,D) and (DataSize>=NS);
+                  Result:=HasData and TryStrToDWord(String(DataNode.NodeValue),D) and (DataSize>=NS);
                   if Result then
                     PCardinal(@Data)^:=D;
                   end;
@@ -329,7 +334,7 @@
                      begin
                      if not IsUnicode then
                        begin
-                       S:=UTF8Encode(DataNode.NodeValue); // Convert to ansistring
+                       S:=DataNode.NodeValue; // Convert to ansistring
                        NS:=Length(S);
                        Result:=(DataSize>=NS);
                        if Result then
@@ -350,8 +355,10 @@
                    if HasData then
                      begin
                      BL:=Length(DataNode.NodeValue);
+                     //writeln('TXmlRegistry.DoGetValueData: BL=',BL);
                      NS:=BL div 2;
                      Result:=DataSize>=NS;
+                     //writeln('TXmlRegistry.DoGetValueData: Result=',Result);
                      If Result then
                        // No need to check for -1, We checked NS before calling.
                        NS:=HexToBuf(DataNode.NodeValue,Data,BL);
@@ -363,7 +370,7 @@
     end;
 end;
 
-Function TXmlRegistry.DoSetValueData(Name : String; DataType : TDataType; Const Data; DataSize : Integer; IsUnicode : Boolean) : Boolean;
+Function TXmlRegistry.DoSetValueData(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer; IsUnicode : Boolean) : Boolean;
 
 Type
   PCardinal = ^Cardinal;
@@ -374,6 +381,7 @@
   SW : UnicodeString;
 
 begin
+  writeln('TXmlRegistry.DoSetValueData A: Name=',Name,', DataType=',DataType,', DataSize=',DataSize,', IsUnicode=',IsUnicode);
   Node:=FindValueKey(Name);
   If Node=Nil then
     Node:=CreateValueKey(Name);
@@ -380,20 +388,20 @@
   Result:=(Node<>Nil);
   If Result then
     begin
-    Node[SType]:=IntToStr(Ord(DataType));
+    Node[SType]:=UnicodeString(IntToStr(Ord(DataType)));
     DataNode:=Node.FirstChild;
 
     Case DataType of
-      dtDWORD : SW:=IntToStr(PCardinal(@Data)^);
+      dtDWORD : SW:=UnicodeString(IntToStr(PCardinal(@Data)^));
       dtString : begin
                  if IsUnicode then
                    SW:=UnicodeString(PUnicodeChar(@Data))
                  else
                    SW:=UnicodeString(PAnsiChar(@Data));
-                   //S:=UTF8Encode(SW);
+                   //S:=SW;
                  end;
-      dtBinary : SW:=BufToHex(Data,DataSize);
-      dtStrings : SW:=BufToHex(Data,DataSize);
+      dtBinary : SW:=UnicodeString(BufToHex(Data,DataSize));
+      dtStrings : SW:=UnicodeString(BufToHex(Data,DataSize));
     else
       sw:='';
     end;
@@ -416,29 +424,29 @@
     end;
 end;
 
-Function TXmlRegistry.SetValueData(Name : String; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
+Function TXmlRegistry.SetValueData(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
 
 begin
   Result:=DoSetValueData(Name,DataType,Data,DataSize,False);
 end;
 
-Function TXmlRegistry.GetValueData(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
+Function TXmlRegistry.GetValueData(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
 
 begin
   Result:=DoGetValueData(Name,DataType,Data,DataSize,False);
 end;
 
-function TXmlRegistry.GetValueDataUnicode(Name: String; out DataType: TDataType; Var Data; Var DataSize: Integer): Boolean;
+function TXmlRegistry.GetValueDataUnicode(Name: UnicodeString; out DataType: TDataType; Var Data; Var DataSize: Integer): Boolean;
 begin
   Result:=DoGetValueData(Name,DataType,Data,DataSize,True);
 end;
 
-function TXmlRegistry.SetValueDataUnicode(Name: String; DataType: TDataType; const Data; DataSize: Integer): Boolean;
+function TXmlRegistry.SetValueDataUnicode(Name: UnicodeString; DataType: TDataType; const Data; DataSize: Integer): Boolean;
 begin
   Result:=DoSetValueData(Name,DataType,Data,DataSize,True)
 end;
 
-Function TXmlRegistry.FindSubKey (S : String; N : TDomElement) : TDomElement;
+Function TXmlRegistry.FindSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
 
 Var
   Node : TDOMNode;
@@ -451,7 +459,7 @@
     While (Result=Nil) and (Assigned(Node)) do
       begin
       If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SKey) then
-        If CompareText(TDomElement(Node)[SName],S)=0 then
+        If UnicodeCompareText(TDomElement(Node)[SName],S)=0 then
           Result:=TDomElement(Node);
       Node:=Node.NextSibling;
       end;
@@ -458,7 +466,7 @@
     end;
 end;
 
-Function TXmlRegistry.CreateSubKey (S : String; N : TDomElement) : TDomElement;
+Function TXmlRegistry.CreateSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
 
 begin
   Result:=FDocument.CreateElement(SKey);
@@ -468,7 +476,7 @@
   FDirty:=True;
 end;
 
-Function  TXmlRegistry.FindValueKey (S : String) : TDomElement;
+Function  TXmlRegistry.FindValueKey (S : UnicodeString) : TDomElement;
 
 Var
   Node : TDOMNode;
@@ -481,7 +489,7 @@
     While (Result=Nil) and (Assigned(Node)) do
       begin
       If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SValue) then
-        If CompareText(TDomElement(Node)[SName],S)=0 then
+        If UnicodeCompareText(TDomElement(Node)[SName],S)=0 then
           Result:=TDomElement(Node);
       Node:=Node.NextSibling;
       end;
@@ -488,7 +496,7 @@
     end;
 end;
 
-Function  TXmlRegistry.CreateValueKey (S : String) : TDomElement;
+Function  TXmlRegistry.CreateValueKey (S : UnicodeString) : TDomElement;
 
 begin
   If Assigned(FCurrentElement) then
@@ -581,38 +589,47 @@
     end;
 end;
 
-Function TXMLRegistry.hexToBuf(Const Str : String; Var Buf; Var Len : Integer ) : Integer;
+Function TXMLRegistry.HexToBuf(Const Str : UnicodeString; Var Buf; Var Len : Integer ) : Integer;
 
 Var
   NLeN,I : Integer;
   P : PByte;
-  S : String;
+  S : UnicodeString;
   B : Byte;
   Code : Integer;
 
 begin
+  writeln('TXMLRegistry.HexToBuf A: Str=',Str,', Len=',Len);
   Result:=0;
   P:=@Buf;
+  //writeln('TXMLRegistry.HexToBuf B: (p=nil)=',p=nil);
   NLen:= Length(Str) div 2;
+  //writeln('TXMLRegistry.HexToBuf C: NLen=',NLen,', SizeOf(TDateTime)=',SizeOf(TDateTime));
   If (NLen>Len) then
     begin
     Len:=NLen;
     Exit(-1);
     end;
-  For I:=0 to Len-1 do
+  For I:=0 to NLen-1 do
     begin
+    write('TXMLRegistry.HexToBuf: i=',i);
     S:='$'+Copy(Str,(I*2)+1,2);
+    write(', S=',S);
     Val(S,B,Code);
+    writeln(', Code=',Code);
     If Code<>0 then
-      begin
-      Inc(Result);
-      B:=0;
+      begin    //This means invalid data in the registry, why continue and increment result? Why not Exit(-1)?
+      //Inc(Result);   //the whole function only worked because this was called as often as when Code=0, so by change
+      //B:=0;          //it causes AV's
+      Exit(-1);
       end;
+    Inc(Result);
     P[I]:=B;
     end;
+  writeln('TXMLRegistry.HexToBuf End: Result=',Result);
 end;
 
-Function TXMLRegistry.DeleteValue(S : String) : Boolean;
+Function TXMLRegistry.DeleteValue(S : UnicodeString) : Boolean;
 
 Var
   N : TDomElement;
@@ -628,31 +645,31 @@
     end;
 end;
 
-Function TXMLRegistry.GetValueSize(Name : String) : Integer;
+Function TXMLRegistry.GetValueSize(Name : UnicodeString) : Integer;
 
 Var
   Info : TDataInfo;
 
 begin
-  If GetValueInfo(Name,Info) then
+  If GetValueInfo(Name,Info,True) then
     Result:=Info.DataSize
   else
     Result:=-1;
 end;
 
-Function TXMLRegistry.GetValueType(Name : String) : TDataType;
+Function TXMLRegistry.GetValueType(Name : UnicodeString) : TDataType;
 
 Var
   Info : TDataInfo;
 
 begin
-  If GetValueInfo(Name,Info) then
+  If GetValueInfo(Name,Info,True) then
     Result:=Info.DataType
   else
     Result:=dtUnknown;
 end;
 
-function TXmlRegistry.GetValueInfo(Name: String; out Info: TDataInfo; AsUnicode: Boolean): Boolean;
+function TXmlRegistry.GetValueInfo(Name: UnicodeString; out Info: TDataInfo; AsUnicode: Boolean): Boolean;
 
 Var
   N  : TDomElement;
@@ -671,7 +688,7 @@
         L:=Length(DN.NodeValue)*SizeOf(UnicodeChar)
       else
         begin
-        S := UTF8Encode(DN.NodeValue);
+        S := DN.NodeValue;
         L:=Length(S);
         end
       end
@@ -679,7 +696,7 @@
       L:=0;
     With Info do
       begin
-      DataType:=TDataType(StrToIntDef(N[SType],0));
+      DataType:=TDataType(StrToIntDef(String(N[SType]),0));
       Case DataType of
         dtUnknown : DataSize:=0;
         dtDword   : Datasize:=SizeOf(Cardinal);
@@ -724,10 +741,10 @@
               ValueLen:=L;
             DataNode:=TDomElement(Node).FirstChild;
             If (DataNode<>Nil) and (DataNode is TDomText) then
-              Case TDataType(StrToIntDef(TDomElement(Node)[SType],0)) of
+              Case TDataType(StrToIntDef(String(TDomElement(Node)[SType]),0)) of
                 dtUnknown : L:=0;
                 dtDWord   : L:=4;
-                DtString  : L:=Length(UTF8Encode(DataNode.NodeValue));
+                DtString  : L:=Length(String(DataNode.NodeValue));
                 dtBinary  : L:=Length(DataNode.NodeValue) div 2;
               end
             else
@@ -782,13 +799,13 @@
     end;
 end;
 
-Function TXMLRegistry.KeyExists(KeyPath : String) : Boolean;
+Function TXMLRegistry.KeyExists(KeyPath : UnicodeString) : Boolean;
 
 begin
   Result:=FindKey(KeyPath)<>Nil;
 end;
 
-Function TXMLRegistry.RenameValue(Const OldName,NewName : String) : Boolean;
+Function TXMLRegistry.RenameValue(Const OldName,NewName : UnicodeString) : Boolean;
 
 Var
   N : TDomElement;
@@ -804,10 +821,10 @@
     end;
 end;
 
-Function TXMLRegistry.FindKey (S : String) : TDomElement;
+Function TXMLRegistry.FindKey (S : UnicodeString) : TDomElement;
 
 Var
-  SubKey : String;
+  SubKey : UnicodeString;
   P : Integer;
   Node : TDomElement;
 
@@ -840,7 +857,7 @@
   Until (Result=Nil) or (Length(S)=0);
 end;
 
-Function  TXmlRegistry.ValueExists(ValueName : String) : Boolean;
+Function  TXmlRegistry.ValueExists(ValueName : UnicodeString) : Boolean;
 
 begin
   Result:=FindValueKey(ValueName)<>Nil;
Index: packages/fcl-registry/src/xregreg.inc
===================================================================
--- packages/fcl-registry/src/xregreg.inc	(revision 41667)
+++ packages/fcl-registry/src/xregreg.inc	(working copy)
@@ -47,7 +47,7 @@
     Class Var XMLRegistryCache: Tlist;
     Class procedure FreeXMLRegistryCache;
   public
-    constructor Create(AFileName : String);
+    constructor Create(AFileName : UnicodeString);
     Class Function GetXMLRegistry(aFileName: string): TXMLRegistry;
     Class Procedure FreeXMLRegistry(XMLRegistry: TXMLRegistry);
     procedure IncRefCount;
@@ -97,7 +97,7 @@
 
 { TXMLRegistryInstance }
 
-constructor TXMLRegistryInstance.Create(AFileName: String);
+constructor TXMLRegistryInstance.Create(AFileName: UnicodeString);
 begin
   inherited;
   FRefCount := 1;
@@ -116,7 +116,9 @@
 procedure TRegistry.SysRegCreate;
 var s : string;
 begin
+  FStringSizeIncludesNull:=False;
   s:=includetrailingpathdelimiter(GetAppConfigDir(GlobalXMLFile));
+s:='.\';//**********UNDO THIS
   ForceDirectories(s);
   FSysData:=TXMLRegistryInstance.GetXMLRegistry(s+XFileName);
   TXmlRegistry(FSysData).AutoFlush:=False;
@@ -130,24 +132,24 @@
   TXMLRegistryInstance.FreeXMLRegistry(TXMLRegistry(FSysData));
 end;
 
-function TRegistry.SysCreateKey(const Key: String): Boolean;
+function TRegistry.SysCreateKey(Key: UnicodeString): Boolean;
 
 begin
   Result:=TXmlRegistry(FSysData).CreateKey(Key);
 end;
 
-function TRegistry.DeleteKey(const Key: string): Boolean;
+function TRegistry.DeleteKey(const Key: UnicodeString): Boolean;
 
 begin
   Result:=TXMLRegistry(FSysData).DeleteKey(Key);
 end;
 
-function TRegistry.DeleteValue(const Name: string): Boolean;
+function TRegistry.DeleteValue(const Name: UnicodeString): Boolean;
 begin
   Result:=TXmlRegistry(FSysData).DeleteValue(Name);
 end;
 
-function TRegistry.SysGetData(const Name: String; Buffer: Pointer;
+function TRegistry.SysGetData(const Name: UnicodeString; Buffer: Pointer;
           BufSize: Integer; Out RegData: TRegDataType): Integer;
 
 Var
@@ -160,7 +162,7 @@
     Result:=-1;
 end;
 
-function TRegistry.GetDataInfo(const ValueName: string; out Value: TRegDataInfo): Boolean;
+function TRegistry.GetDataInfo(const ValueName: UnicodeString; out Value: TRegDataInfo): Boolean;
 
 Var
   Info : TDataInfo;
@@ -181,7 +183,7 @@
       end;
 end;
 
-function TRegistry.GetKey(const Key: string): HKEY;
+function TRegistry.GetKey(Key: UnicodeString): HKEY;
 begin
   Result := 0;
 end;
@@ -205,17 +207,17 @@
       end;
 end;
 
-function TRegistry.KeyExists(const Key: string): Boolean;
+function TRegistry.KeyExists(const Key: UnicodeString): Boolean;
 begin
   Result:=TXmlRegistry(FSysData).KeyExists(Key);
 end;
 
-function TRegistry.LoadKey(const Key, FileName: string): Boolean;
+function TRegistry.LoadKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.OpenKey(const Key: string; CanCreate: Boolean): Boolean;
+function TRegistry.OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
 
 begin
   Result:=TXmlRegistry(FSysData).SetKey(Key,CanCreate);
@@ -222,43 +224,43 @@
   FCurrentKey:=1;
 end;
 
-function TRegistry.OpenKeyReadOnly(const Key: string): Boolean;
+function TRegistry.OpenKeyReadOnly(const Key: UnicodeString): Boolean;
 
 begin
   Result:=TXmlRegistry(FSysData).SetKey(Key,False);
 end;
 
-function TRegistry.RegistryConnect(const UNCName: string): Boolean;
+function TRegistry.RegistryConnect(const UNCName: UnicodeString): Boolean;
 begin
   Result := True;
 end;
 
-function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
+function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.RestoreKey(const Key, FileName: string): Boolean;
+function TRegistry.RestoreKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.SaveKey(const Key, FileName: string): Boolean;
+function TRegistry.SaveKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.UnLoadKey(const Key: string): Boolean;
+function TRegistry.UnLoadKey(const Key: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.ValueExists(const Name: string): Boolean;
+function TRegistry.ValueExists(const Name: UnicodeString): Boolean;
 begin
   Result := TXmlRegistry(FSysData).ValueExists(Name);
 end;
 
-procedure TRegistry.ChangeKey(Value: HKey; const Path: string);
+procedure TRegistry.ChangeKey(Value: HKey; const Path: UnicodeString);
 begin
 
 end;
@@ -274,7 +276,7 @@
 end;
 
 
-function TRegistry.SysPutData(const Name: string; Buffer: Pointer;
+function TRegistry.SysPutData(const Name: UnicodeString; Buffer: Pointer;
   BufSize: Integer; RegData: TRegDataType): Boolean;
 
 Var
@@ -281,11 +283,13 @@
   DataType : TDataType;
 
 begin
+  //writeln('TRegistry.SysPutData: Name=',Name,', RegData=',RegData,', BufSize=',BufSize);
   DataType:=RegDataTypeToXmlDataType(RegData);
+
   Result:=TXMLRegistry(FSysData).SetValueDataUnicode(Name,DataType,Buffer^,BufSize);
 end;
 
-procedure TRegistry.RenameValue(const OldName, NewName: string);
+procedure TRegistry.RenameValue(const OldName, NewName: UnicodeString);
 begin
   TXMLRegistry(FSysData).RenameValue(OldName,NewName);
 end;

Bart Broersma

2019-03-16 17:18

reporter  

registry.unicode.part4.diff (64,132 bytes)
Index: packages/fcl-registry/src/regdef.inc
===================================================================
--- packages/fcl-registry/src/regdef.inc	(revision 41667)
+++ packages/fcl-registry/src/regdef.inc	(working copy)
@@ -2,7 +2,7 @@
   HKEY = THandle;
   PHKEY = ^HKEY;
   
-{$ifdef windows}
+{$if defined(windows) and not defined(XMLREG)}
 
 { Direct mapping to constants in Windows unit }
 
Index: packages/fcl-registry/src/registry.pp
===================================================================
--- packages/fcl-registry/src/registry.pp	(revision 41667)
+++ packages/fcl-registry/src/registry.pp	(working copy)
@@ -39,6 +39,8 @@
     DataSize: Integer;
   end;
 
+  TUnicodeStringArray = Array of UnicodeString;
+
 { ---------------------------------------------------------------------
     TRegistry
   ---------------------------------------------------------------------}
@@ -54,22 +56,31 @@
     fCurrentKey: HKEY;
     fRootKey: HKEY;
     fLazyWrite: Boolean;
-    fCurrentPath: string;
+    fCurrentPath: UnicodeString;
     function GetLastErrorMsg: string;
+    function RegMultiSzDataToUnicodeStringArray(U: UnicodeString): TUnicodeStringArray;
+    function ListToArray(List: TStrings; IsUtf8: Boolean): TUnicodeStringArray;
+    procedure ArrayToList(const Arr: TUnicodeStringArray; List: TStrings; ForceUtf8: Boolean);
     procedure SetRootKey(Value: HKEY);
     Procedure SysRegCreate;
     Procedure SysRegFree;
-    Function  SysGetData(const Name: String; Buffer: Pointer; BufSize: Integer; Out RegData: TRegDataType): Integer;
-    Function  SysPutData(const Name: string; Buffer: Pointer; BufSize: Integer; RegData: TRegDataType) : Boolean;
-    Function  SysCreateKey(const Key: String): Boolean;
+    Function  SysGetData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; Out RegData: TRegDataType): Integer;
+    Function  SysPutData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; RegData: TRegDataType) : Boolean;
+    Function  SysCreateKey(Key: UnicodeString): Boolean;
   protected
     function GetBaseKey(Relative: Boolean): HKey;
-    function GetData(const Name: string; Buffer: Pointer;
+    function GetData(const Name: UnicodeString; Buffer: Pointer;
                   BufSize: Integer; Out RegData: TRegDataType): Integer;
-    function GetKey(const Key: string): HKEY;
-    procedure ChangeKey(Value: HKey; const Path: string);
-    procedure PutData(const Name: string; Buffer: Pointer;
+    function GetData(const Name: String; Buffer: Pointer;
+                  BufSize: Integer; Out RegData: TRegDataType): Integer;
+    function GetKey(Key: UnicodeString): HKEY;
+    function GetKey(Key: String): HKEY;
+    procedure ChangeKey(Value: HKey; const Path: UnicodeString);
+    procedure ChangeKey(Value: HKey; const Path: String);
+    procedure PutData(const Name: UnicodeString; Buffer: Pointer;
                   BufSize: Integer; RegData: TRegDataType);
+    procedure PutData(const Name: String; Buffer: Pointer;
+                  BufSize: Integer; RegData: TRegDataType);
     procedure SetCurrentKey(Value: HKEY);
   public
     constructor Create; overload;
@@ -76,58 +87,106 @@
     constructor Create(aaccess:longword); overload;
     destructor Destroy; override;
 
-    function CreateKey(const Key: string): Boolean;
-    function DeleteKey(const Key: string): Boolean;
-    function DeleteValue(const Name: string): Boolean;
-    function GetDataInfo(const ValueName: string; Out Value: TRegDataInfo): Boolean;
-    function GetDataSize(const ValueName: string): Integer;
-    function GetDataType(const ValueName: string): TRegDataType;
+    function CreateKey(const Key: UnicodeString): Boolean;
+    function CreateKey(const Key: String): Boolean;
+    function DeleteKey(const Key: UnicodeString): Boolean;
+    function DeleteKey(const Key: String): Boolean;
+    function DeleteValue(const Name: UnicodeString): Boolean;
+    function DeleteValue(const Name: String): Boolean;
+    function GetDataInfo(const ValueName: UnicodeString; Out Value: TRegDataInfo): Boolean;
+    function GetDataInfo(const ValueName: String; Out Value: TRegDataInfo): Boolean;
+    function GetDataSize(const ValueName: UnicodeString): Integer;
+    function GetDataSize(const ValueName: String): Integer;
+    function GetDataType(const ValueName: UnicodeString): TRegDataType;
+    function GetDataType(const ValueName: String): TRegDataType;
     function GetKeyInfo(Out Value: TRegKeyInfo): Boolean;
     function HasSubKeys: Boolean;
-    function KeyExists(const Key: string): Boolean;
-    function LoadKey(const Key, FileName: string): Boolean;
-    function OpenKey(const Key: string; CanCreate: Boolean): Boolean;
-    function OpenKeyReadOnly(const Key: string): Boolean;
-    function ReadCurrency(const Name: string): Currency;
-    function ReadBinaryData(const Name: string; var Buffer; BufSize: Integer): Integer;
-    function ReadBool(const Name: string): Boolean;
-    function ReadDate(const Name: string): TDateTime;
-    function ReadDateTime(const Name: string): TDateTime;
-    function ReadFloat(const Name: string): Double;
-    function ReadInteger(const Name: string): Integer;
-    function ReadInt64(const Name: string): Int64;
-    function ReadString(const Name: string): string;
-    procedure ReadStringList(const Name: string; AList: TStrings);
-    function ReadTime(const Name: string): TDateTime;
-    function RegistryConnect(const UNCName: string): Boolean;
-    function ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
-    function RestoreKey(const Key, FileName: string): Boolean;
-    function SaveKey(const Key, FileName: string): Boolean;
-    function UnLoadKey(const Key: string): Boolean;
-    function ValueExists(const Name: string): Boolean;
+    function KeyExists(const Key: UnicodeString): Boolean;
+    function KeyExists(const Key: String): Boolean;
+    function LoadKey(const Key, FileName: UnicodeString): Boolean;
+    function LoadKey(const Key, FileName: String): Boolean;
+    function OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
+    function OpenKey(const Key: String; CanCreate: Boolean): Boolean;
+    function OpenKeyReadOnly(const Key: UnicodeString): Boolean;
+    function OpenKeyReadOnly(const Key: String): Boolean;
+    function ReadCurrency(const Name: UnicodeString): Currency;
+    function ReadCurrency(const Name: String): Currency;
+    function ReadBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer): Integer;
+    function ReadBinaryData(const Name: String; var Buffer; BufSize: Integer): Integer;
+    function ReadBool(const Name: UnicodeString): Boolean;
+    function ReadBool(const Name: String): Boolean;
+    function ReadDate(const Name: UnicodeString): TDateTime;
+    function ReadDate(const Name: String): TDateTime;
+    function ReadDateTime(const Name: UnicodeString): TDateTime;
+    function ReadDateTime(const Name: String): TDateTime;
+    function ReadFloat(const Name: UnicodeString): Double;
+    function ReadFloat(const Name: String): Double;
+    function ReadInteger(const Name: UnicodeString): Integer;
+    function ReadInteger(const Name: String): Integer;
+    function ReadInt64(const Name: UnicodeString): Int64;
+    function ReadInt64(const Name: String): Int64;
+    function ReadString(const Name: UnicodeString): UnicodeString;
+    function ReadString(const Name: String): string;
+    procedure ReadStringList(const Name: UnicodeString; AList: TStrings; ForceUtf8: Boolean=False);
+    procedure ReadStringList(const Name: String; AList: TStrings);
+    function ReadStringArray(const Name: UnicodeString): TUnicodeStringArray;
+    function ReadStringArray(const Name: String): TStringArray;
+    function ReadTime(const Name: UnicodeString): TDateTime;
+    function ReadTime(const Name: String): TDateTime;
+    function RegistryConnect(const UNCName: UnicodeString): Boolean;
+    function RegistryConnect(const UNCName: String): Boolean;
+    function ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
+    function ReplaceKey(const Key, FileName, BackUpFileName: String): Boolean;
+    function RestoreKey(const Key, FileName: UnicodeString): Boolean;
+    function RestoreKey(const Key, FileName: String): Boolean;
+    function SaveKey(const Key, FileName: UnicodeString): Boolean;
+    function SaveKey(const Key, FileName: String): Boolean;
+    function UnLoadKey(const Key: UnicodeString): Boolean;
+    function UnLoadKey(const Key: String): Boolean;
+    function ValueExists(const Name: UnicodeString): Boolean;
+    function ValueExists(const Name: String): Boolean;
 
     procedure CloseKey;
     procedure CloseKey(key:HKEY);
     procedure GetKeyNames(Strings: TStrings);
+    //ToDo
+    //function GetKeyNames: TUnicodeStringArray;
     procedure GetValueNames(Strings: TStrings);
-    procedure MoveKey(const OldName, NewName: string; Delete: Boolean);
-    procedure RenameValue(const OldName, NewName: string);
-    procedure WriteCurrency(const Name: string; Value: Currency);
-    procedure WriteBinaryData(const Name: string; var Buffer; BufSize: Integer);
-    procedure WriteBool(const Name: string; Value: Boolean);
-    procedure WriteDate(const Name: string; Value: TDateTime);
-    procedure WriteDateTime(const Name: string; Value: TDateTime);
-    procedure WriteFloat(const Name: string; Value: Double);
-    procedure WriteInteger(const Name: string; Value: Integer);
-    procedure WriteInt64(const Name: string; Value: Int64);
-    procedure WriteString(const Name, Value: string);
-    procedure WriteExpandString(const Name, Value: string);
-    procedure WriteStringList(const Name: string; List: TStrings);
-    procedure WriteTime(const Name: string; Value: TDateTime);
+    //ToDo
+    //function GetValueNames: TUnicodeStringArray;
+    procedure MoveKey(const OldName, NewName: UnicodeString; Delete: Boolean);
+    procedure MoveKey(const OldName, NewName: String; Delete: Boolean);
+    procedure RenameValue(const OldName, NewName: UnicodeString);
+    procedure RenameValue(const OldName, NewName: String);
+    procedure WriteCurrency(const Name: UnicodeString; Value: Currency);
+    procedure WriteCurrency(const Name: String; Value: Currency);
+    procedure WriteBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer);
+    procedure WriteBinaryData(const Name: String; var Buffer; BufSize: Integer);
+    procedure WriteBool(const Name: UnicodeString; Value: Boolean);
+    procedure WriteBool(const Name: String; Value: Boolean);
+    procedure WriteDate(const Name: UnicodeString; Value: TDateTime);
+    procedure WriteDate(const Name: String; Value: TDateTime);
+    procedure WriteDateTime(const Name: UnicodeString; Value: TDateTime);
+    procedure WriteDateTime(const Name: String; Value: TDateTime);
+    procedure WriteFloat(const Name: UnicodeString; Value: Double);
+    procedure WriteFloat(const Name: String; Value: Double);
+    procedure WriteInteger(const Name: UnicodeString; Value: Integer);
+    procedure WriteInteger(const Name: String; Value: Integer);
+    procedure WriteInt64(const Name: UnicodeString; Value: Int64);
+    procedure WriteInt64(const Name: String; Value: Int64);
+    procedure WriteString(const Name, Value: UnicodeString);
+    procedure WriteString(const Name, Value: String);
+    procedure WriteExpandString(const Name, Value: UnicodeString);
+    procedure WriteExpandString(const Name, Value: String);
+    procedure WriteStringList(const Name: UnicodeString; List: TStrings; IsUtf8: Boolean=False);
+    procedure WriteStringArray(const Name: UnicodeString; const Arr: TUnicodeStringArray);
+    procedure WriteStringArray(const Name: String; const Arr: TStringArray);
+    procedure WriteTime(const Name: UnicodeString; Value: TDateTime);
+    procedure WriteTime(const Name: String; Value: TDateTime);
 
     property Access: LongWord read fAccess write fAccess;
     property CurrentKey: HKEY read fCurrentKey;
-    property CurrentPath: string read fCurrentPath;
+    property CurrentPath: UnicodeString read fCurrentPath;
     property LazyWrite: Boolean read fLazyWrite write fLazyWrite;
     property RootKey: HKEY read fRootKey write SetRootKey;
     Property StringSizeIncludesNull : Boolean read FStringSizeIncludesNull;
@@ -235,6 +294,16 @@
     Generic, implementation-independent code.
   ---------------------------------------------------------------------}
 
+{$ifdef DebugRegistry}
+function DbgS(const S: UnicodeString): String;
+var
+  C: WideChar;
+begin
+  Result := '';
+  for C in S do Result := Result + IntToHex(Word(C),4) + #32;
+  Result := TrimRight(Result);
+end;
+{$endif}
 
 constructor TRegistry.Create;
 
@@ -261,7 +330,7 @@
   inherited Destroy;
 end;
 
-function TRegistry.CreateKey(const Key: string): Boolean;
+function TRegistry.CreateKey(const Key: UnicodeString): Boolean;
 
 begin
   Result:=SysCreateKey(Key);
@@ -269,6 +338,27 @@
     Raise ERegistryException.CreateFmt(SRegCreateFailed, [Key]);
 end;
 
+function TRegistry.CreateKey(const Key: String): Boolean;
+begin
+  Result:=CreateKey(UnicodeString(Key));
+end;
+
+function TRegistry.DeleteKey(const Key: String): Boolean;
+begin
+  Result:=DeleteKey(UnicodeString(Key));
+end;
+
+function TRegistry.DeleteValue(const Name: String): Boolean;
+begin
+  Result:=DeleteValue(UnicodeString(Name));
+end;
+
+function TRegistry.GetDataInfo(const ValueName: String; out Value: TRegDataInfo
+  ): Boolean;
+begin
+  Result:=GetDataInfo(UnicodeString(ValueName), Value);
+end;
+
 function TRegistry.GetBaseKey(Relative: Boolean): HKey;
 begin
   If Relative and (CurrentKey<>0) Then
@@ -277,7 +367,7 @@
     Result := RootKey;
 end;
 
-function TRegistry.GetData(const Name: string; Buffer: Pointer; BufSize: Integer; out RegData: TRegDataType): Integer;
+function TRegistry.GetData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; out RegData: TRegDataType): Integer;
 begin
   Result:=SysGetData(Name,Buffer,BufSize,RegData);
   If (Result=-1) then
@@ -284,7 +374,24 @@
     Raise ERegistryException.CreateFmt(SRegGetDataFailed, [Name]);
 end;
 
-procedure TRegistry.PutData(const Name: string; Buffer: Pointer;
+function TRegistry.GetData(const Name: String; Buffer: Pointer;
+  BufSize: Integer; out RegData: TRegDataType): Integer;
+begin
+  Result:=GetData(UnicodeString(Name), Buffer, BufSize, RegData);
+end;
+
+function TRegistry.GetKey(Key: String): HKEY;
+begin
+  Result:=GetKey(UnicodeString(Key));
+end;
+
+procedure TRegistry.ChangeKey(Value: HKey; const Path: String);
+begin
+  ChangeKey(Value, UnicodeString(Path));
+end;
+
+
+procedure TRegistry.PutData(const Name: UnicodeString; Buffer: Pointer;
   BufSize: Integer; RegData: TRegDataType);
 
 begin
@@ -292,9 +399,15 @@
     Raise ERegistryException.CreateFmt(SRegSetDataFailed, [Name]);
 end;
 
+procedure TRegistry.PutData(const Name: String; Buffer: Pointer;
+  BufSize: Integer; RegData: TRegDataType);
+begin
+  PutData(UnicodeString(Name), Buffer, BufSize, RegData);
+end;
 
-function TRegistry.GetDataSize(const ValueName: string): Integer;
 
+function TRegistry.GetDataSize(const ValueName: UnicodeString): Integer;
+
 Var
   Info: TRegDataInfo;
 
@@ -305,8 +418,13 @@
     Result := -1;
 end;
 
-function TRegistry.GetDataType(const ValueName: string): TRegDataType;
+function TRegistry.GetDataSize(const ValueName: String): Integer;
+begin
+  Result:=GetDataSize(UnicodeString(ValueName));
+end;
 
+function TRegistry.GetDataType(const ValueName: UnicodeString): TRegDataType;
+
 Var
   Info: TRegDataInfo;
 
@@ -315,6 +433,32 @@
   Result:=Info.RegData;
 end;
 
+function TRegistry.GetDataType(const ValueName: String): TRegDataType;
+begin
+  Result:=GetDataType(UnicodeString(ValueName));
+end;
+
+
+function TRegistry.KeyExists(const Key: String): Boolean;
+begin
+  Result:=KeyExists(UnicodeString(Key));
+end;
+
+function TRegistry.LoadKey(const Key, FileName: String): Boolean;
+begin
+  Result:=LoadKey(UnicodeString(Key), UnicodeString(FileName));
+end;
+
+function TRegistry.OpenKey(const Key: String; CanCreate: Boolean): Boolean;
+begin
+  Result:=OpenKey(UnicodeString(Key), CanCreate);
+end;
+
+function TRegistry.OpenKeyReadOnly(const Key: String): Boolean;
+begin
+  Result:=OpenKeyReadOnly(UnicodeString(Key));
+end;
+
 function TRegistry.HasSubKeys: Boolean;
 
 Var
@@ -326,7 +470,7 @@
     Result:=(Info.NumSubKeys>0);
 end;
 
-function TRegistry.ReadBinaryData(const Name: string; var Buffer; BufSize: Integer): Integer;
+function TRegistry.ReadBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer): Integer;
 
 Var
   RegDataType: TRegDataType;
@@ -337,8 +481,14 @@
     Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
 end;
 
-function TRegistry.ReadInteger(const Name: string): Integer;
+function TRegistry.ReadBinaryData(const Name: String; var Buffer;
+  BufSize: Integer): Integer;
+begin
+  Result:=ReadBinaryData(UnicodeString(Name), Buffer, BufSize);
+end;
 
+function TRegistry.ReadInteger(const Name: UnicodeString): Integer;
+
 Var
   RegDataType: TRegDataType;
 
@@ -348,8 +498,13 @@
     Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
 end;
 
-function TRegistry.ReadInt64(const Name: string): Int64;
+function TRegistry.ReadInteger(const Name: String): Integer;
+begin
+  Result:=ReadInteger(UnicodeString(Name));
+end;
 
+function TRegistry.ReadInt64(const Name: UnicodeString): Int64;
+
 Var
   RegDataType: TRegDataType;
 
@@ -359,21 +514,36 @@
     Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
 end;
 
-function TRegistry.ReadBool(const Name: string): Boolean;
+function TRegistry.ReadInt64(const Name: String): Int64;
+begin
+  Result:=ReadInt64(UnicodeString(Name));
+end;
 
+function TRegistry.ReadBool(const Name: UnicodeString): Boolean;
+
 begin
   Result:=ReadInteger(Name)<>0;
 end;
 
-function TRegistry.ReadCurrency(const Name: string): Currency;
+function TRegistry.ReadBool(const Name: String): Boolean;
+begin
+  Result:=ReadBool(UnicodeString(Name));
+end;
 
+function TRegistry.ReadCurrency(const Name: UnicodeString): Currency;
+
 begin
   Result:=Default(Currency);
   ReadBinaryData(Name, Result, SizeOf(Currency));
 end;
 
-function TRegistry.ReadDate(const Name: string): TDateTime;
+function TRegistry.ReadCurrency(const Name: String): Currency;
+begin
+  Result:=ReadCurrency(UnicodeString(Name));
+end;
 
+function TRegistry.ReadDate(const Name: UnicodeString): TDateTime;
+
 begin
   Result:=Default(TDateTime);
   ReadBinaryData(Name, Result, SizeOf(TDateTime));
@@ -380,22 +550,37 @@
   Result:=Trunc(Result);
 end;
 
-function TRegistry.ReadDateTime(const Name: string): TDateTime;
+function TRegistry.ReadDate(const Name: String): TDateTime;
+begin
+  Result:=ReadDate(UnicodeString(Name));
+end;
 
+function TRegistry.ReadDateTime(const Name: UnicodeString): TDateTime;
+
 begin
   Result:=Default(TDateTime);
   ReadBinaryData(Name, Result, SizeOf(TDateTime));
 end;
 
-function TRegistry.ReadFloat(const Name: string): Double;
+function TRegistry.ReadDateTime(const Name: String): TDateTime;
+begin
+  Result:=ReadDateTime(UnicodeString(Name));
+end;
 
+function TRegistry.ReadFloat(const Name: UnicodeString): Double;
+
 begin
   Result:=Default(Double);
   ReadBinaryData(Name,Result,SizeOf(Double));
 end;
 
-function TRegistry.ReadString(const Name: string): string;
+function TRegistry.ReadFloat(const Name: String): Double;
+begin
+  Result:=ReadFloat(UnicodeString(Name));
+end;
 
+function TRegistry.ReadString(const Name: UnicodeString): UnicodeString;
+
 Var
   Info : TRegDataInfo;
   ReadDataSize: Integer;
@@ -421,47 +606,142 @@
       if StringSizeIncludesNull and
          (u[Length(u)] = WideChar(0)) then
         SetLength(u,Length(u)-1);
-      Result:=UTF8Encode(u);
+      Result:=u;
     end;
   end;
 end;
 
-procedure TRegistry.ReadStringList(const Name: string; AList: TStrings);
+function TRegistry.ReadString(const Name: String): string;
+begin
+  Result:=ReadString(UnicodeString(Name));
+end;
 
+
+procedure TRegistry.ReadStringList(const Name: UnicodeString; AList: TStrings; ForceUtf8: Boolean=False);
+
 Var
   Info : TRegDataInfo;
-  ReadDataSize: Integer;
-  Data: string;
+  ReadDataSize, i: Integer;
+  Data: UnicodeString;
+  UArr: TUnicodeStringArray;
 
 begin
-  AList.Clear;
+  UArr := ReadStringArray(Name);
+  ArrayToList(UArr, AList, ForceUtf8);
+end;
+
+procedure TRegistry.ReadStringList(const Name: String; AList: TStrings);
+begin
+  ReadStringList(UnicodeString(Name), AList);
+end;
+
+function TRegistry.RegMultiSzDataToUnicodeStringArray(U: UnicodeString): TUnicodeStringArray;
+var
+  Len, i, p: Integer;
+  Sub: UnicodeString;
+begin
+  Result := nil;
+  if (U = '') then Exit;
+  Len := 1;
+  for i := 1 to Length(U) do if (U[i] = #0) then Inc(Len);
+  SetLength(Result, Len);
+  i := 0;
+
+  while (U <> '') and (i < Length(Result)) do
+  begin
+    p := Pos(#0, U);
+    if (p = 0) then p := Length(U) + 1;
+    Sub := Copy(U, 1, p - 1);
+    Result[i] := Sub;
+    System.Delete(U, 1, p);
+    Inc(i);
+  end;
+end;
+
+function TRegistry.ListToArray(List: TStrings; IsUtf8: Boolean): TUnicodeStringArray;
+var
+  i, curr, Len: Integer;
+  u: UnicodeString;
+begin
+  Result := nil;
+  Len := List.Count;
+  SetLength(Result, Len);
+  //REG_MULTI_SZ data cannot contain empty strings
+  curr := 0;
+  for i := 0 to List.Count - 1 do
+  begin
+    if IsUtf8 then
+      u := Utf8Decode(List[i])
+    else
+      u := List[i];
+    if (u>'') then
+    begin
+      Result[curr] := u;
+      inc(curr);
+    end
+    else
+      Dec(Len);
+  end;
+  if (Len <> List.Count) then SetLength(Result, Len);
+end;
+
+procedure TRegistry.ArrayToList(const Arr: TUnicodeStringArray; List: TStrings; ForceUtf8: Boolean);
+var
+  i: Integer;
+begin
+  List.Clear;
+  for i := Low(Arr) to High(Arr) do
+  begin
+    if ForceUtf8 then
+      List.Add(Utf8Encode(Arr[i]))
+    else
+      List.Add(String(Arr[i]));
+  end;
+end;
+
+function TRegistry.ReadStringArray(const Name: UnicodeString): TUnicodeStringArray;
+Var
+  Info : TRegDataInfo;
+  ReadDataSize, i: Integer;
+  Data: UnicodeString;
+
+begin
+  Result := nil;
   GetDataInfo(Name,Info);
+  //writeln('TRegistry.ReadStringArray: datasize=',info.datasize);
   if info.datasize>0 then
     begin
      If Not (Info.RegData in [rdMultiString]) then
        Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
      SetLength(Data,Info.DataSize);
-     ReadDataSize := GetData(Name,PChar(Data),Info.DataSize,Info.RegData);
+     ReadDataSize := GetData(Name,PWideChar(Data),Info.DataSize,Info.RegData) div SizeOf(WideChar);
+     //writeln('TRegistry.ReadStringArray: ReadDataSize=',ReadDataSize);
      if ReadDataSize > 0 then
      begin
-       // If the data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type,
-       // the size includes any terminating null character or characters
-       // unless the data was stored without them! (RegQueryValueEx @ MSDN)
-       if StringSizeIncludesNull then begin
-         if Data[ReadDataSize] = #0 then
-           Dec(ReadDataSize);
-         if Data[ReadDataSize] = #0 then
-           Dec(ReadDataSize);
-       end;
+       // Windows returns the data with or without trailing zero's, so just strip all trailing null characters
+        while (Data[ReadDataSize] = #0) do Dec(ReadDataSize);
        SetLength(Data, ReadDataSize);
-       Data := StringReplace(Data, #0, LineEnding, [rfReplaceAll]);
-       AList.Text := Data;
+       //writeln('Data=',dbgs(data));
+       //Data := UnicodeStringReplace(Data, #0, AList.LineBreak, [rfReplaceAll]);
+       //AList.Text := Data;
+       Result := RegMultiSzDataToUnicodeStringArray(Data);
      end
    end
 end;
 
-function TRegistry.ReadTime(const Name: string): TDateTime;
+function TRegistry.ReadStringArray(const Name: String): TStringArray;
+var
+  UArr: TUnicodeStringArray;
+  i: Integer;
+begin
+  Result := nil;
+  UArr := ReadStringArray(UnicodeString(Name));
+  SetLength(Result, Length(UArr));
+  for i := Low(UArr) to High(UArr) do Result[i] := UArr[i];
+end;
 
+function TRegistry.ReadTime(const Name: UnicodeString): TDateTime;
+
 begin
   Result:=Default(TDateTime);
   ReadBinaryData(Name, Result, SizeOf(TDateTime));
@@ -468,85 +748,214 @@
   Result:=Frac(Result);
 end;
 
-procedure TRegistry.WriteBinaryData(const Name: string; var Buffer; BufSize: Integer);
+function TRegistry.ReadTime(const Name: String): TDateTime;
 begin
+  Result:=ReadTime(UnicodeString(Name));
+end;
+
+function TRegistry.RegistryConnect(const UNCName: String): Boolean;
+begin
+  Result:=RegistryConnect(UnicodeString(UNCName));
+end;
+
+function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: String): Boolean;
+begin
+  Result:=ReplaceKey(UnicodeString(Key), UnicodeString(FileName), UnicodeString(BackUpFileName))
+end;
+
+function TRegistry.RestoreKey(const Key, FileName: String): Boolean;
+begin
+  Result:=RestoreKey(UnicodeString(Key), UnicodeString(FileName));
+end;
+
+function TRegistry.SaveKey(const Key, FileName: String): Boolean;
+begin
+  Result:=SaveKey(UnicodeString(Key), UnicodeString(FileName));
+end;
+
+function TRegistry.UnLoadKey(const Key: String): Boolean;
+begin
+  Result:=UnloadKey(UnicodeString(Key));
+end;
+
+function TRegistry.ValueExists(const Name: String): Boolean;
+begin
+  Result:=ValueExists(UnicodeString(Name));
+end;
+
+procedure TRegistry.WriteBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer);
+begin
   PutData(Name, @Buffer, BufSize, rdBinary);
 end;
 
-procedure TRegistry.WriteBool(const Name: string; Value: Boolean);
+procedure TRegistry.WriteBinaryData(const Name: String; var Buffer;
+  BufSize: Integer);
+begin
+  WriteBinaryData(UnicodeString(Name), Buffer, BufSize);
+end;
 
+procedure TRegistry.WriteBool(const Name: UnicodeString; Value: Boolean);
+
 begin
   WriteInteger(Name,Ord(Value));
 end;
 
-procedure TRegistry.WriteCurrency(const Name: string; Value: Currency);
+procedure TRegistry.WriteBool(const Name: String; Value: Boolean);
 begin
+  WriteBool(UnicodeString(Name), Value);
+end;
+
+procedure TRegistry.WriteCurrency(const Name: UnicodeString; Value: Currency);
+begin
   WriteBinaryData(Name, Value, SizeOf(Currency));
 end;
 
-procedure TRegistry.WriteDate(const Name: string; Value: TDateTime);
+procedure TRegistry.WriteCurrency(const Name: String; Value: Currency);
 begin
+  WriteCurrency(UnicodeString(Name), Value);
+end;
+
+procedure TRegistry.WriteDate(const Name: UnicodeString; Value: TDateTime);
+begin
   WriteBinarydata(Name, Value, SizeOf(TDateTime));
 end;
 
-procedure TRegistry.WriteTime(const Name: string; Value: TDateTime);
+procedure TRegistry.WriteDate(const Name: String; Value: TDateTime);
 begin
+  WriteDate(UnicodeString(Name), Value);
+end;
+
+procedure TRegistry.WriteTime(const Name: UnicodeString; Value: TDateTime);
+begin
   WriteBinaryData(Name, Value, SizeOf(TDateTime));
 end;
 
-procedure TRegistry.WriteDateTime(const Name: string; Value: TDateTime);
+procedure TRegistry.WriteTime(const Name: String; Value: TDateTime);
 begin
+  WriteTime(UnicodeString(Name), Value);
+end;
+
+procedure TRegistry.WriteDateTime(const Name: UnicodeString; Value: TDateTime);
+begin
   WriteBinaryData(Name, Value, SizeOf(TDateTime));
 end;
 
-procedure TRegistry.WriteExpandString(const Name, Value: string);
-var
-  u: UnicodeString;
+procedure TRegistry.WriteDateTime(const Name: String; Value: TDateTime);
+begin
+  WriteDateTime(UnicodeString(Name), Value);
+end;
 
+procedure TRegistry.WriteExpandString(const Name, Value: UnicodeString);
 begin
-  u:=Value;
-  PutData(Name, PWideChar(u), ByteLength(u), rdExpandString);
+  PutData(Name, PWideChar(Value), ByteLength(Value), rdExpandString);
 end;
 
-procedure TRegistry.WriteStringList(const Name: string; List: TStrings);
+procedure TRegistry.WriteExpandString(const Name, Value: String);
+begin
+  WriteExpandString(UnicodeString(Name), UnicodeString(Value));
+end;
 
+
+procedure TRegistry.WriteStringList(const Name: UnicodeString; List: TStrings; IsUtf8: Boolean=False);
+
 Var
-  Data: string;
+  UArr: TUnicodeStringArray;
+begin
+  UArr := ListToArray(List, IsUtf8);
+  WriteStringArray(Name, UArr);
+end;
 
+procedure TRegistry.WriteStringArray(const Name: UnicodeString; const Arr: TUnicodeStringArray);
+Var
+  Data: UnicodeString;
+  u: UnicodeString;
+  i: Integer;
 begin
-  Data := StringReplace(List.Text, LineEnding, #0, [rfReplaceAll]) + #0#0;
-  PutData(Name, PChar(Data), Length(Data),rdMultiString);
+  Data := '';
+  //REG_MULTI_SZ data cannot contain empty strings
+  for i := Low(Arr) to High(Arr) do
+  begin
+    u := Arr[i];
+    if (u>'') then
+    begin
+      if (Data>'') then
+        Data := Data + #0 + u
+      else
+        Data := Data + u;
+    end;
+  end;
+  if StringSizeIncludesNull then
+    Data := Data + #0#0;
+  //writeln('Data=',Dbgs(Data));
+  PutData(Name, PWideChar(Data), ByteLength(Data), rdMultiString);
 end;
 
-procedure TRegistry.WriteFloat(const Name: string; Value: Double);
+procedure TRegistry.WriteStringArray(const Name: String; const Arr: TStringArray);
+var
+  UArr: TUnicodeStringArray;
+  i: Integer;
 begin
+  UArr := nil;
+  SetLength(UArr, Length(Arr));
+  for i := Low(Arr) to High(Arr) do UArr[i] := Arr[i];
+  WriteStringArray(UnicodeString(Name), UArr);
+end;
+
+procedure TRegistry.WriteFloat(const Name: UnicodeString; Value: Double);
+begin
   WriteBinaryData(Name, Value, SizeOf(Double));
 end;
 
-procedure TRegistry.WriteInteger(const Name: string; Value: Integer);
+procedure TRegistry.WriteFloat(const Name: String; Value: Double);
 begin
+  WriteFloat(UnicodeString(Name), Value);
+end;
+
+procedure TRegistry.WriteInteger(const Name: UnicodeString; Value: Integer);
+begin
   PutData(Name, @Value, SizeOf(Integer), rdInteger);
 end;
 
-procedure TRegistry.WriteInt64(const Name: string; Value: Int64);
+procedure TRegistry.WriteInteger(const Name: String; Value: Integer);
 begin
+  WriteInteger(UnicodeString(Name), Value);
+end;
+
+procedure TRegistry.WriteInt64(const Name: UnicodeString; Value: Int64);
+begin
   PutData(Name, @Value, SizeOf(Int64), rdInt64);
 end;
 
-procedure TRegistry.WriteString(const Name, Value: string);
-var
-  u: UnicodeString;
+procedure TRegistry.WriteInt64(const Name: String; Value: Int64);
+begin
+  WriteInt64(UnicodeString(Name), Value);
+end;
 
+procedure TRegistry.WriteString(const Name, Value: UnicodeString);
 begin
-  u:=Value;
-  PutData(Name, PWideChar(u), ByteLength(u), rdString);
+  PutData(Name, PWideChar(Value), ByteLength(Value), rdString);
 end;
 
-procedure TRegistry.MoveKey(const OldName, NewName: string; Delete: Boolean);
+procedure TRegistry.WriteString(const Name, Value: String);
 begin
+  WriteString(UnicodeString(Name), UnicodeString(Value));
+end;
 
+procedure TRegistry.MoveKey(const OldName, NewName: UnicodeString; Delete: Boolean);
+begin
+
 end;
 
+procedure TRegistry.MoveKey(const OldName, NewName: String; Delete: Boolean);
+begin
+  MoveKey(UnicodeString(OldName), UnicodeString(NewName), Delete);
+end;
+
+procedure TRegistry.RenameValue(const OldName, NewName: String);
+begin
+  RenameValue(UnicodeString(OldName), UnicodeString(NewName));
+end;
+
 { ---------------------------------------------------------------------
     Include TRegIniFile implementation
   ---------------------------------------------------------------------}
@@ -583,7 +992,7 @@
   Value: TStream): Integer;
 begin
   result:=-1; // unimplemented
- // 
+ //
 end;
 
 function TRegistryIniFile.ReadDate(const Section, Name: string;
Index: packages/fcl-registry/src/winreg.inc
===================================================================
--- packages/fcl-registry/src/winreg.inc	(revision 41667)
+++ packages/fcl-registry/src/winreg.inc	(working copy)
@@ -1,7 +1,7 @@
 Const
   RegDataWords : Array [TRegDataType] of DWORD
                = (REG_NONE,REG_SZ,REG_EXPAND_SZ,REG_BINARY,REG_DWORD,REG_DWORD_BIG_ENDIAN,
-                  REG_LINK,REG_MULTI_SZ,REG_RESOURCE_LIST,REG_FULL_RESOURCE_DESCRIPTOR,REG_RESOURCE_REQUIREMENTS_LIST,REG_QWORD);
+                  REG_LINK,REG_MULTI_SZ,REG_RESOURCE_LIST,REG_FULL_RESOURCE_DESCRIPTOR,REG_RESOURCE_REQUIREMENTS_LIST,11{REG_QWORD}); //*****UNDO THIS!
 
 type
   TWinRegData = record
@@ -28,7 +28,7 @@
   Dispose(PWinRegData(FSysData));
 end;
 
-Function PrepKey(Const S : String) : String;
+Function PrepKey(Const S : UnicodeString) : UnicodeString;
 
 begin
   Result := S;
@@ -36,7 +36,7 @@
     System.Delete(Result, 1, 1);
 end;
 
-Function RelativeKey(Const S : String) : Boolean;
+Function RelativeKey(Const S : UnicodeString) : Boolean;
 
 begin
   Result:=(S='') or (S[1]<>'\')
@@ -43,7 +43,7 @@
 end;
 
 
-function TRegistry.sysCreateKey(const Key: String): Boolean;
+function TRegistry.sysCreateKey(Key: UnicodeString): Boolean;
 Var
   u: UnicodeString;
   Disposition: Dword;
@@ -52,9 +52,9 @@
 
 begin
   SecurityAttributes := Nil;
-  u:=PrepKey(Key);
+  Key:=PrepKey(Key);
   FLastError:=RegCreateKeyExW(GetBaseKey(RelativeKey(Key)),
-                              PWideChar(u),
+                              PWideChar(Key),
                               0,
                               '',
                               REG_OPTION_NON_VOLATILE,
@@ -66,7 +66,7 @@
   RegCloseKey(Handle);
 end;
 
-function TRegistry.DeleteKey(const Key: String): Boolean;
+function TRegistry.DeleteKey(const Key: UnicodeString): Boolean;
 
 Var
   u: UnicodeString;
@@ -76,21 +76,21 @@
   Result:=FLastError=ERROR_SUCCESS;
 end;
 
-function TRegistry.DeleteValue(const Name: String): Boolean;
+
+function TRegistry.DeleteValue(const Name: UnicodeString): Boolean;
 begin
-  FLastError:= RegDeleteValueW(fCurrentKey, PWideChar(UnicodeString(Name)));
+  FLastError:= RegDeleteValueW(fCurrentKey, PWideChar(Name));
   Result:=FLastError=ERROR_SUCCESS;
 end;
 
-function TRegistry.SysGetData(const Name: String; Buffer: Pointer;
+
+function TRegistry.SysGetData(const Name: UnicodeString; Buffer: Pointer;
           BufSize: Integer; Out RegData: TRegDataType): Integer;
 Var
-  u: UnicodeString;
   RD : DWord;
 
 begin
-  u := Name;
-  FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(u),Nil,
+  FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(Name),Nil,
                       @RD,Buffer,lpdword(@BufSize));
   if (FLastError<>ERROR_SUCCESS) Then
     Result:=-1
@@ -103,17 +103,15 @@
     end;
 end;
 
-function TRegistry.GetDataInfo(const ValueName: String; out Value: TRegDataInfo): Boolean;
+function TRegistry.GetDataInfo(const ValueName: UnicodeString; out Value: TRegDataInfo): Boolean;
 
 Var
-  u: UnicodeString;
   RD : DWord;
 
 begin
-  u:=ValueName;
   With Value do
     begin
-    FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(u),Nil,lpdword(@RegData),Nil,lpdword(@DataSize));
+    FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(ValueName),Nil,lpdword(@RegData),Nil,lpdword(@DataSize));
     Result:=FLastError=ERROR_SUCCESS;
     if Result then
       begin
@@ -131,24 +129,18 @@
 end;
 
 
-function TRegistry.GetKey(const Key: String): HKEY;
+function TRegistry.GetKey(Key: UnicodeString): HKEY;
 var
-  S : string;
-{$ifndef WinCE}
-  u : UnicodeString;
-{$endif}
   Rel : Boolean;
 begin
   Result:=0;
-  S:=Key;
-  Rel:=RelativeKey(S);
+  Rel:=RelativeKey(Key);
   if not(Rel) then
-    Delete(S,1,1);
+    Delete(Key,1,1);
 {$ifdef WinCE}
-  FLastError:=RegOpenKeyEx(GetBaseKey(Rel),PWideChar(WideString(S)),0,FAccess,Result);
+  FLastError:=RegOpenKeyEx(GetBaseKey(Rel),PWideChar(Key),0,FAccess,Result);
 {$else WinCE}
-  u:=UnicodeString(S);
-  FLastError:=RegOpenKeyExW(GetBaseKey(Rel),PWideChar(u),0,FAccess,Result);
+  FLastError:=RegOpenKeyExW(GetBaseKey(Rel),PWideChar(Key),0,FAccess,Result);
 {$endif WinCE}
 end;
 
@@ -174,7 +166,7 @@
 end;
 
 
-function TRegistry.KeyExists(const Key: string): Boolean;
+function TRegistry.KeyExists(const Key: UnicodeString): Boolean;
 var
   KeyHandle : HKEY;
   OldAccess : LONG;
@@ -196,20 +188,20 @@
 end;
 
 
-function TRegistry.LoadKey(const Key, FileName: string): Boolean;
+function TRegistry.LoadKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
 
-function TRegistry.OpenKey(const Key: string; CanCreate: Boolean): Boolean;
 
+function TRegistry.OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
+
 Var
-  u: UnicodeString;
+  u, S: UnicodeString;
   Handle: HKEY;
   Disposition: Integer;
   SecurityAttributes: Pointer; //LPSECURITY_ATTRIBUTES;
-  S: string;
 begin
   SecurityAttributes := Nil;
   u:=PrepKey(Key);
@@ -232,13 +224,14 @@
     if RelativeKey(Key) then
       S:=CurrentPath + Key
     else
-      S:=UTF8Encode(u);
+      S:=u;
     ChangeKey(Handle, S);
   end;
 end;
 
-function TRegistry.OpenKeyReadOnly(const Key: string): Boolean;
 
+function TRegistry.OpenKeyReadOnly(const Key: UnicodeString): Boolean;
+
 Var
   OldAccess: LongWord;
 begin
@@ -251,7 +244,8 @@
   end;
 end;
 
-function TRegistry.RegistryConnect(const UNCName: string): Boolean;
+
+function TRegistry.RegistryConnect(const UNCName: UnicodeString): Boolean;
 {$ifndef WinCE}
 var
   newroot: HKEY;
@@ -260,7 +254,7 @@
 {$ifdef WinCE}
   Result:=False;
 {$else}
-  FLastError:=RegConnectRegistryW(PWideChar(UnicodeString(UNCName)),RootKey,newroot);
+  FLastError:=RegConnectRegistryW(PWideChar(UNCName),RootKey,newroot);
   Result:=FLastError=ERROR_SUCCESS;
   if Result then begin
     RootKey:=newroot;
@@ -269,28 +263,33 @@
 {$endif}
 end;
 
-function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
+
+function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.RestoreKey(const Key, FileName: string): Boolean;
+
+function TRegistry.RestoreKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.SaveKey(const Key, FileName: string): Boolean;
+
+function TRegistry.SaveKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.UnLoadKey(const Key: string): Boolean;
+
+function TRegistry.UnLoadKey(const Key: UnicodeString): Boolean;
 begin
   Result := false;
 end;
 
-function TRegistry.ValueExists(const Name: string): Boolean;
 
+function TRegistry.ValueExists(const Name: UnicodeString): Boolean;
+
 var
   Info : TRegDataInfo;
 
@@ -298,6 +297,7 @@
   Result:=GetDataInfo(Name,Info);
 end;
 
+
 procedure TRegistry.CloseKey;
 begin
   If (CurrentKey<>0) then
@@ -316,7 +316,7 @@
   RegCloseKey(key);
 end;
 
-procedure TRegistry.ChangeKey(Value: HKey; const Path: String);
+procedure TRegistry.ChangeKey(Value: HKey; const Path: UnicodeString);
 begin
   CloseKey;
   FCurrentKey:=Value;
@@ -323,6 +323,7 @@
   FCurrentPath:=Path;
 end;
 
+
 procedure TRegistry.GetKeyNames(Strings: TStrings);
 
 var
@@ -410,12 +411,11 @@
 end;
 
 
-Function TRegistry.SysPutData(const Name: string; Buffer: Pointer;
+Function TRegistry.SysPutData(const Name: UnicodeString; Buffer: Pointer;
   BufSize: Integer; RegData: TRegDataType) : Boolean;
 
 
 Var
-  u: UnicodeString;
   RegDataType: DWORD;
   B : Pchar;
   S : String;
@@ -422,12 +422,11 @@
 
 begin
   RegDataType:=RegDataWords[RegData];
-  u:=UnicodeString(Name);
-  FLastError:=RegSetValueExW(fCurrentKey,PWideChar(u),0,RegDataType,Buffer,BufSize);
+  FLastError:=RegSetValueExW(fCurrentKey,PWideChar(Name),0,RegDataType,Buffer,BufSize);
   Result:=FLastError=ERROR_SUCCESS;
 end;
 
-procedure TRegistry.RenameValue(const OldName, NewName: string);
+procedure TRegistry.RenameValue(const OldName, NewName: UnicodeString);
 
 var
   L: Integer;
Index: packages/fcl-registry/src/xmlreg.pp
===================================================================
--- packages/fcl-registry/src/xmlreg.pp	(revision 41667)
+++ packages/fcl-registry/src/xmlreg.pp	(working copy)
@@ -32,54 +32,54 @@
   Private
     FAutoFlush,
     FDirty : Boolean;
-    FFileName : String;
-    FRootKey : String;
+    FFileName : UnicodeString;
+    FRootKey : UnicodeString;
     FDocument : TXMLDocument;
     FCurrentElement : TDomElement;
-    FCurrentKey : String;
-    Procedure SetFileName(Value : String);
+    FCurrentKey : UnicodeString;
+    Procedure SetFileName(Value : UnicodeString);
   Protected
-    function DoGetValueData(Name: String; out DataType: TDataType; Var Data; Var DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
-    function DoSetValueData(Name: String; DataType: TDataType; const Data; DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
+    function DoGetValueData(Name: UnicodeString; out DataType: TDataType; Var Data; Var DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
+    function DoSetValueData(Name: UnicodeString; DataType: TDataType; const Data; DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
     Procedure LoadFromStream(S : TStream);
-    Function  NormalizeKey(KeyPath : String) : String;
+    Function  NormalizeKey(KeyPath : UnicodeString) : UnicodeString;
     Procedure CreateEmptyDoc;
-    Function  FindKey (S : String) : TDomElement;
-    Function  FindSubKey (S : String; N : TDomElement) : TDomElement;
-    Function  CreateSubKey (S : String; N : TDomElement) : TDomElement;
-    Function  FindValueKey (S : String) : TDomElement;
-    Function  CreateValueKey (S : String) : TDomElement;
+    Function  FindKey (S : UnicodeString) : TDomElement;
+    Function  FindSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
+    Function  CreateSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
+    Function  FindValueKey (S : UnicodeString) : TDomElement;
+    Function  CreateValueKey (S : UnicodeString) : TDomElement;
     Function  BufToHex(Const Buf; Len : Integer) : String;
-    Function  hexToBuf(Const Str : String; Var Buf; Var Len : Integer ) : Integer;
+    Function  HexToBuf(Const Str : UnicodeString; Var Buf; Var Len : Integer ) : Integer;
     Procedure MaybeFlush;
     Property  Document : TXMLDocument Read FDocument;
     Property  Dirty : Boolean Read FDirty write FDirty;
   Public
-    Constructor Create(AFileName : String);
+    Constructor Create(AFileName : UnicodeString);
     Destructor  Destroy;override;
-    Function  SetKey(KeyPath : String; AllowCreate : Boolean) : Boolean ;
-    Procedure SetRootKey(Value : String);
-    Function  DeleteKey(KeyPath : String) : Boolean;
-    Function  CreateKey(KeyPath : String) : Boolean;
-    Function  GetValueSize(Name : String) : Integer;
-    Function  GetValueType(Name : String) : TDataType;
-    Function  GetValueInfo(Name : String; Out Info : TDataInfo; AsUnicode : Boolean = False) : Boolean;
+    Function  SetKey(KeyPath : UnicodeString; AllowCreate : Boolean) : Boolean ;
+    Procedure SetRootKey(Value : UnicodeString);
+    Function  DeleteKey(KeyPath : UnicodeString) : Boolean;
+    Function  CreateKey(KeyPath : UnicodeString) : Boolean;
+    Function  GetValueSize(Name : UnicodeString) : Integer;
+    Function  GetValueType(Name : UnicodeString) : TDataType;
+    Function  GetValueInfo(Name : UnicodeString; Out Info : TDataInfo; AsUnicode : Boolean = False) : Boolean;
     Function  GetKeyInfo(Out Info : TKeyInfo) : Boolean;
     Function  EnumSubKeys(List : TStrings) : Integer;
     Function  EnumValues(List : TStrings) : Integer;
-    Function  KeyExists(KeyPath : String) : Boolean;
-    Function  ValueExists(ValueName : String) : Boolean;
-    Function  RenameValue(Const OldName,NewName : String) : Boolean;
-    Function  DeleteValue(S : String) : Boolean;
+    Function  KeyExists(KeyPath : UnicodeString) : Boolean;
+    Function  ValueExists(ValueName : UnicodeString) : Boolean;
+    Function  RenameValue(Const OldName,NewName : UnicodeString) : Boolean;
+    Function  DeleteValue(S : UnicodeString) : Boolean;
     Procedure Flush;
     Procedure Load;
-    Function GetValueData(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
-    Function SetValueData(Name : String; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
+    Function GetValueData(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
+    Function SetValueData(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
     // These interpret the Data buffer as unicode data
-    Function GetValueDataUnicode(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
-    Function SetValueDataUnicode(Name : String; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
-    Property FileName : String Read FFileName Write SetFileName;
-    Property RootKey : String Read FRootKey Write SetRootkey;
+    Function GetValueDataUnicode(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
+    Function SetValueDataUnicode(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
+    Property FileName : UnicodeString Read FFileName Write SetFileName;
+    Property RootKey : UnicodeString Read FRootKey Write SetRootkey;
     Property AutoFlush : Boolean Read FAutoFlush Write FAutoFlush;
   end;
 
@@ -96,7 +96,7 @@
 Implementation
 
 
-Constructor TXmlRegistry.Create(AFileName : String);
+Constructor TXmlRegistry.Create(AFileName : UnicodeString);
 
 begin
   FFileName:=AFileName;
@@ -113,7 +113,7 @@
   inherited Destroy;
 end;
 
-Procedure TXmlRegistry.SetFileName(Value : String);
+Procedure TXmlRegistry.SetFileName(Value : UnicodeString);
 
 begin
   If Value<>FFileName then
@@ -143,13 +143,13 @@
   end;
 end;
 
-Function TXmlRegistry.NormalizeKey(KeyPath : String) : String;
+Function TXmlRegistry.NormalizeKey(KeyPath : UnicodeString) : UnicodeString;
 
 Var
   L : Integer;
 
 begin
-  Result:=StringReplace(KeyPath,'\','/',[rfReplaceAll]);
+  Result:=UnicodeStringReplace(KeyPath,'\','/',[rfReplaceAll]);
   L:=Length(Result);
   If (L>0) and (Result[L]<>'/') then
     Result:=Result+'/';
@@ -157,10 +157,10 @@
     Result:='/' + Result;
 end;
 
-Function TXmlRegistry.SetKey(KeyPath : String; AllowCreate : Boolean) : boolean;
+Function TXmlRegistry.SetKey(KeyPath : UnicodeString; AllowCreate : Boolean) : boolean;
 
 Var
-  SubKey,ResultKey : String;
+  SubKey,ResultKey : UnicodeString;
   P : Integer;
   Node,Node2 : TDomElement;
 
@@ -218,7 +218,7 @@
   MaybeFlush;
 end;
 
-Procedure TXmlRegistry.SetRootKey(Value : String);
+Procedure TXmlRegistry.SetRootKey(Value : UnicodeString);
 
 begin
   FRootKey:=NormalizeKey(Value);
@@ -228,7 +228,7 @@
   FCurrentElement:=Nil;
 end;
 
-Function TXmlRegistry.DeleteKey(KeyPath : String) : Boolean;
+Function TXmlRegistry.DeleteKey(KeyPath : UnicodeString) : Boolean;
 
 Var
   N : TDomElement;
@@ -244,10 +244,10 @@
    end;
 end;
 
-Function TXmlRegistry.CreateKey(KeyPath : String) : Boolean;
+Function TXmlRegistry.CreateKey(KeyPath : UnicodeString) : Boolean;
 
 Var
-  SubKey : String;
+  SubKey : UnicodeString;
   P : Integer;
   Node,Node2 : TDomElement;
 
@@ -290,7 +290,7 @@
   MaybeFlush;
 end;
 
-Function TXmlRegistry.DoGetValueData(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer; IsUnicode : Boolean) : Boolean;
+Function TXmlRegistry.DoGetValueData(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer; IsUnicode : Boolean) : Boolean;
 
 Type
   PCardinal = ^Cardinal;
@@ -305,22 +305,27 @@
   D : DWord;
   
 begin
+  //writeln('TXmlRegistry.DoGetValueData: Name=',Name,' IsUnicode=',IsUnicode);
   Node:=FindValueKey(Name);
   Result:=Node<>Nil;
   If Result then
     begin
+    //writeln('TXmlRegistry.DoGetValueData: Node<>nil');
     DataNode:=Node.FirstChild;
     HasData:=Assigned(DataNode) and (DataNode.NodeType=TEXT_NODE);
-    ND:=StrToIntDef(Node[Stype],0);
+    //writeln('TXmlRegistry.DoGetValueData: HasData=',hasdata);
+    ND:=StrToIntDef(String(Node[Stype]),0);
+    //writeln('TXmlRegistry.DoGetValueData: ND=',ND);
     Result:=ND<=Ord(High(TDataType));
     If Result then
       begin
       DataType:=TDataType(ND);
+      //writeln('TXmlRegistry.DoGetValueData: DataType=',DataType);
       NS:=0; // Initialize, for optional nodes.
       Case DataType of
         dtDWORD : begin   // DataNode is required
                   NS:=SizeOf(Cardinal);
-                  Result:=HasData and TryStrToDWord(DataNode.NodeValue,D) and (DataSize>=NS);
+                  Result:=HasData and TryStrToDWord(String(DataNode.NodeValue),D) and (DataSize>=NS);
                   if Result then
                     PCardinal(@Data)^:=D;
                   end;
@@ -329,7 +334,7 @@
                      begin
                      if not IsUnicode then
                        begin
-                       S:=UTF8Encode(DataNode.NodeValue); // Convert to ansistring
+                       S:=DataNode.NodeValue; // Convert to ansistring
                        NS:=Length(S);
                        Result:=(DataSize>=NS);
                        if Result then
@@ -350,8 +355,10 @@
                    if HasData then
                      begin
                      BL:=Length(DataNode.NodeValue);
+                     //writeln('TXmlRegistry.DoGetValueData: BL=',BL);
                      NS:=BL div 2;
                      Result:=DataSize>=NS;
+                     //writeln('TXmlRegistry.DoGetValueData: Result=',Result);
                      If Result then
                        // No need to check for -1, We checked NS before calling.
                        NS:=HexToBuf(DataNode.NodeValue,Data,BL);
@@ -363,7 +370,7 @@
     end;
 end;
 
-Function TXmlRegistry.DoSetValueData(Name : String; DataType : TDataType; Const Data; DataSize : Integer; IsUnicode : Boolean) : Boolean;
+Function TXmlRegistry.DoSetValueData(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer; IsUnicode : Boolean) : Boolean;
 
 Type
   PCardinal = ^Cardinal;
@@ -374,6 +381,7 @@
   SW : UnicodeString;
 
 begin
+  //writeln('TXmlRegistry.DoSetValueData A: Name=',Name,', DataType=',DataType,', DataSize=',DataSize,', IsUnicode=',IsUnicode);
   Node:=FindValueKey(Name);
   If Node=Nil then
     Node:=CreateValueKey(Name);
@@ -380,20 +388,20 @@
   Result:=(Node<>Nil);
   If Result then
     begin
-    Node[SType]:=IntToStr(Ord(DataType));
+    Node[SType]:=UnicodeString(IntToStr(Ord(DataType)));
     DataNode:=Node.FirstChild;
 
     Case DataType of
-      dtDWORD : SW:=IntToStr(PCardinal(@Data)^);
+      dtDWORD : SW:=UnicodeString(IntToStr(PCardinal(@Data)^));
       dtString : begin
                  if IsUnicode then
                    SW:=UnicodeString(PUnicodeChar(@Data))
                  else
                    SW:=UnicodeString(PAnsiChar(@Data));
-                   //S:=UTF8Encode(SW);
+                   //S:=SW;
                  end;
-      dtBinary : SW:=BufToHex(Data,DataSize);
-      dtStrings : SW:=BufToHex(Data,DataSize);
+      dtBinary : SW:=UnicodeString(BufToHex(Data,DataSize));
+      dtStrings : SW:=UnicodeString(BufToHex(Data,DataSize));
     else
       sw:='';
     end;
@@ -416,29 +424,29 @@
     end;
 end;
 
-Function TXmlRegistry.SetValueData(Name : String; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
+Function TXmlRegistry.SetValueData(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
 
 begin
   Result:=DoSetValueData(Name,DataType,Data,DataSize,False);
 end;
 
-Function TXmlRegistry.GetValueData(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
+Function TXmlRegistry.GetValueData(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
 
 begin
   Result:=DoGetValueData(Name,DataType,Data,DataSize,False);
 end;
 
-function TXmlRegistry.GetValueDataUnicode(Name: String; out DataType: TDataType; Var Data; Var DataSize: Integer): Boolean;
+function TXmlRegistry.GetValueDataUnicode(Name: UnicodeString; out DataType: TDataType; Var Data; Var DataSize: Integer): Boolean;
 begin
   Result:=DoGetValueData(Name,DataType,Data,DataSize,True);
 end;
 
-function TXmlRegistry.SetValueDataUnicode(Name: String; DataType: TDataType; const Data; DataSize: Integer): Boolean;
+function TXmlRegistry.SetValueDataUnicode(Name: UnicodeString; DataType: TDataType; const Data; DataSize: Integer): Boolean;
 begin
   Result:=DoSetValueData(Name,DataType,Data,DataSize,True)
 end;
 
-Function TXmlRegistry.FindSubKey (S : String; N : TDomElement) : TDomElement;
+Function TXmlRegistry.FindSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
 
 Var
   Node : TDOMNode;
@@ -451,7 +459,7 @@
     While (Result=Nil) and (Assigned(Node)) do
       begin
       If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SKey) then
-        If CompareText(TDomElement(Node)[SName],S)=0 then
+        If UnicodeCompareText(TDomElement(Node)[SName],S)=0 then
           Result:=TDomElement(Node);
       Node:=Node.NextSibling;
       end;
@@ -458,7 +466,7 @@
     end;
 end;
 
-Function TXmlRegistry.CreateSubKey (S : String; N : TDomElement) : TDomElement;
+Function TXmlRegistry.CreateSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
 
 begin
   Result:=FDocument.CreateElement(SKey);
@@ -468,7 +476,7 @@
   FDirty:=True;
 end;
 
-Function  TXmlRegistry.FindValueKey (S : String) : TDomElement;
+Function  TXmlRegistry.FindValueKey (S : UnicodeString) : TDomElement;
 
 Var
   Node : TDOMNode;
@@ -481,7 +489,7 @@
     While (Result=Nil) and (Assigned(Node)) do
       begin
       If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SValue) then
-        If CompareText(TDomElement(Node)[SName],S)=0 then
+        If UnicodeCompareText(TDomElement(Node)[SName],S)=0 then
           Result:=TDomElement(Node);
       Node:=Node.NextSibling;
       end;
@@ -488,7 +496,7 @@
     end;
 end;
 
-Function  TXmlRegistry.CreateValueKey (S : String) : TDomElement;
+Function  TXmlRegistry.CreateValueKey (S : UnicodeString) : TDomElement;
 
 begin
   If Assigned(FCurrentElement) then
@@ -581,38 +589,47 @@
     end;
 end;
 
-Function TXMLRegistry.hexToBuf(Const Str : String; Var Buf; Var Len : Integer ) : Integer;
+Function TXMLRegistry.HexToBuf(Const Str : UnicodeString; Var Buf; Var Len : Integer ) : Integer;
 
 Var
   NLeN,I : Integer;
   P : PByte;
-  S : String;
+  S : UnicodeString;
   B : Byte;
   Code : Integer;
 
 begin
+  //writeln('TXMLRegistry.HexToBuf A: Str=',Str,', Len=',Len);
   Result:=0;
   P:=@Buf;
+  //writeln('TXMLRegistry.HexToBuf B: (p=nil)=',p=nil);
   NLen:= Length(Str) div 2;
+  //writeln('TXMLRegistry.HexToBuf C: NLen=',NLen,', SizeOf(TDateTime)=',SizeOf(TDateTime));
   If (NLen>Len) then
     begin
     Len:=NLen;
     Exit(-1);
     end;
-  For I:=0 to Len-1 do
+  For I:=0 to NLen-1 do
     begin
+    //write('TXMLRegistry.HexToBuf: i=',i);
     S:='$'+Copy(Str,(I*2)+1,2);
+    //write(', S=',S);
     Val(S,B,Code);
+    //writeln(', Code=',Code);
     If Code<>0 then
-      begin
-      Inc(Result);
-      B:=0;
+      begin    //This means invalid data in the registry, why continue and increment result? Why not Exit(-1)?
+      //Inc(Result);   //the whole function only worked because this was called as often as when Code=0, so by change
+      //B:=0;          //it causes AV's
+      Exit(-1);
       end;
+    Inc(Result);
     P[I]:=B;
     end;
+  //writeln('TXMLRegistry.HexToBuf End: Result=',Result);
 end;
 
-Function TXMLRegistry.DeleteValue(S : String) : Boolean;
+Function TXMLRegistry.DeleteValue(S : UnicodeString) : Boolean;
 
 Var
   N : TDomElement;
@@ -628,31 +645,31 @@
     end;
 end;
 
-Function TXMLRegistry.GetValueSize(Name : String) : Integer;
+Function TXMLRegistry.GetValueSize(Name : UnicodeString) : Integer;
 
 Var
   Info : TDataInfo;
 
 begin
-  If GetValueInfo(Name,Info) then
+  If GetValueInfo(Name,Info,True) then
     Result:=Info.DataSize
   else
     Result:=-1;
 end;
 
-Function TXMLRegistry.GetValueType(Name : String) : TDataType;
+Function TXMLRegistry.GetValueType(Name : UnicodeString) : TDataType;
 
 Var
   Info : TDataInfo;
 
 begin
-  If GetValueInfo(Name,Info) then
+  If GetValueInfo(Name,Info,True) then
     Result:=Info.DataType
   else
     Result:=dtUnknown;
 end;
 
-function TXmlRegistry.GetValueInfo(Name: String; out Info: TDataInfo; AsUnicode: Boolean): Boolean;
+function TXmlRegistry.GetValueInfo(Name: UnicodeString; out Info: TDataInfo; AsUnicode: Boolean): Boolean;
 
 Var
   N  : TDomElement;
@@ -671,7 +688,7 @@
         L:=Length(DN.NodeValue)*SizeOf(UnicodeChar)
       else
         begin
-        S := UTF8Encode(DN.NodeValue);
+        S := DN.NodeValue;
         L:=Length(S);
         end
       end
@@ -679,7 +696,7 @@
       L:=0;
     With Info do
       begin
-      DataType:=TDataType(StrToIntDef(N[SType],0));
+      DataType:=TDataType(StrToIntDef(String(N[SType]),0));
       Case DataType of
         dtUnknown : DataSize:=0;
         dtDword   : Datasize:=SizeOf(Cardinal);
@@ -724,10 +741,10 @@
               ValueLen:=L;
             DataNode:=TDomElement(Node).FirstChild;
             If (DataNode<>Nil) and (DataNode is TDomText) then
-              Case TDataType(StrToIntDef(TDomElement(Node)[SType],0)) of
+              Case TDataType(StrToIntDef(String(TDomElement(Node)[SType]),0)) of
                 dtUnknown : L:=0;
                 dtDWord   : L:=4;
-                DtString  : L:=Length(UTF8Encode(DataNode.NodeValue));
+                DtString  : L:=Length(String(DataNode.NodeValue));
                 dtBinary  : L:=Length(DataNode.NodeValue) div 2;
               end
             else
@@ -782,13 +799,13 @@
     end;
 end;
 
-Function TXMLRegistry.KeyExists(KeyPath : String) : Boolean;
+Function TXMLRegistry.KeyExists(KeyPath : UnicodeString) : Boolean;
 
 begin
   Result:=FindKey(KeyPath)<>Nil;
 end;
 
-Function TXMLRegistry.RenameValue(Const OldName,NewName : String) : Boolean;
+Function TXMLRegistry.RenameValue(Const OldName,NewName : UnicodeString) : Boolean;
 
 Var
   N : TDomElement;
@@ -804,10 +821,10 @@
     end;
 end;
 
-Function TXMLRegistry.FindKey (S : String) : TDomElement;
+Function TXMLRegistry.FindKey (S : UnicodeString) : TDomElement;
 
 Var
-  SubKey : String;
+  SubKey : UnicodeString;
   P : Integer;
   Node : TDomElement;
 
@@ -840,7 +857,7 @@
   Until (Result=Nil) or (Length(S)=0);
 end;
 
-Function  TXmlRegistry.ValueExists(ValueName : String) : Boolean;
+Function  TXmlRegistry.ValueExists(ValueName : UnicodeString) : Boolean;
 
 begin
   Result:=FindValueKey(ValueName)<>Nil;
Index: packages/fcl-registry/src/xregreg.inc
===================================================================
--- packages/fcl-registry/src/xregreg.inc	(revision 41667)
+++ packages/fcl-registry/src/xregreg.inc	(working copy)
@@ -47,7 +47,7 @@
     Class Var XMLRegistryCache: Tlist;
     Class procedure FreeXMLRegistryCache;
   public
-    constructor Create(AFileName : String);
+    constructor Create(AFileName : UnicodeString);
     Class Function GetXMLRegistry(aFileName: string): TXMLRegistry;
     Class Procedure FreeXMLRegistry(XMLRegistry: TXMLRegistry);
     procedure IncRefCount;
@@ -97,7 +97,7 @@
 
 { TXMLRegistryInstance }
 
-constructor TXMLRegistryInstance.Create(AFileName: String);
+constructor TXMLRegistryInstance.Create(AFileName: UnicodeString);
 begin
   inherited;
   FRefCount := 1;
@@ -116,7 +116,11 @@
 procedure TRegistry.SysRegCreate;
 var s : string;
 begin
+  FStringSizeIncludesNull:=False;
   s:=includetrailingpathdelimiter(GetAppConfigDir(GlobalXMLFile));
+  {$ifdef XMLRegfile_in_CurDir}
+  s:='.' + PathDelim;
+  {$endif}
   ForceDirectories(s);
   FSysData:=TXMLRegistryInstance.GetXMLRegistry(s+XFileName);
   TXmlRegistry(FSysData).AutoFlush:=False;
@@ -130,24 +134,24 @@
   TXMLRegistryInstance.FreeXMLRegistry(TXMLRegistry(FSysData));
 end;
 
-function TRegistry.SysCreateKey(const Key: String): Boolean;
+function TRegistry.SysCreateKey(Key: UnicodeString): Boolean;
 
 begin
   Result:=TXmlRegistry(FSysData).CreateKey(Key);
 end;
 
-function TRegistry.DeleteKey(const Key: string): Boolean;
+function TRegistry.DeleteKey(const Key: UnicodeString): Boolean;
 
 begin
   Result:=TXMLRegistry(FSysData).DeleteKey(Key);
 end;
 
-function TRegistry.DeleteValue(const Name: string): Boolean;
+function TRegistry.DeleteValue(const Name: UnicodeString): Boolean;
 begin
   Result:=TXmlRegistry(FSysData).DeleteValue(Name);
 end;
 
-function TRegistry.SysGetData(const Name: String; Buffer: Pointer;
+function TRegistry.SysGetData(const Name: UnicodeString; Buffer: Pointer;
           BufSize: Integer; Out RegData: TRegDataType): Integer;
 
 Var
@@ -160,7 +164,7 @@
     Result:=-1;
 end;
 
-function TRegistry.GetDataInfo(const ValueName: string; out Value: TRegDataInfo): Boolean;
+function TRegistry.GetDataInfo(const ValueName: UnicodeString; out Value: TRegDataInfo): Boolean;
 
 Var
   Info : TDataInfo;
@@ -181,7 +185,7 @@
       end;
 end;
 
-function TRegistry.GetKey(const Key: string): HKEY;
+function TRegistry.GetKey(Key: UnicodeString): HKEY;
 begin
   Result := 0;
 end;
@@ -205,17 +209,17 @@
       end;
 end;
 
-function TRegistry.KeyExists(const Key: string): Boolean;
+function TRegistry.KeyExists(const Key: UnicodeString): Boolean;
 begin
   Result:=TXmlRegistry(FSysData).KeyExists(Key);
 end;
 
-function TRegistry.LoadKey(const Key, FileName: string): Boolean;
+function TRegistry.LoadKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.OpenKey(const Key: string; CanCreate: Boolean): Boolean;
+function TRegistry.OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
 
 begin
   Result:=TXmlRegistry(FSysData).SetKey(Key,CanCreate);
@@ -222,43 +226,43 @@
   FCurrentKey:=1;
 end;
 
-function TRegistry.OpenKeyReadOnly(const Key: string): Boolean;
+function TRegistry.OpenKeyReadOnly(const Key: UnicodeString): Boolean;
 
 begin
   Result:=TXmlRegistry(FSysData).SetKey(Key,False);
 end;
 
-function TRegistry.RegistryConnect(const UNCName: string): Boolean;
+function TRegistry.RegistryConnect(const UNCName: UnicodeString): Boolean;
 begin
   Result := True;
 end;
 
-function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
+function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.RestoreKey(const Key, FileName: string): Boolean;
+function TRegistry.RestoreKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.SaveKey(const Key, FileName: string): Boolean;
+function TRegistry.SaveKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.UnLoadKey(const Key: string): Boolean;
+function TRegistry.UnLoadKey(const Key: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.ValueExists(const Name: string): Boolean;
+function TRegistry.ValueExists(const Name: UnicodeString): Boolean;
 begin
   Result := TXmlRegistry(FSysData).ValueExists(Name);
 end;
 
-procedure TRegistry.ChangeKey(Value: HKey; const Path: string);
+procedure TRegistry.ChangeKey(Value: HKey; const Path: UnicodeString);
 begin
 
 end;
@@ -274,7 +278,7 @@
 end;
 
 
-function TRegistry.SysPutData(const Name: string; Buffer: Pointer;
+function TRegistry.SysPutData(const Name: UnicodeString; Buffer: Pointer;
   BufSize: Integer; RegData: TRegDataType): Boolean;
 
 Var
@@ -281,15 +285,18 @@
   DataType : TDataType;
 
 begin
+  //writeln('TRegistry.SysPutData: Name=',Name,', RegData=',RegData,', BufSize=',BufSize);
   DataType:=RegDataTypeToXmlDataType(RegData);
+
   Result:=TXMLRegistry(FSysData).SetValueDataUnicode(Name,DataType,Buffer^,BufSize);
 end;
 
-procedure TRegistry.RenameValue(const OldName, NewName: string);
+procedure TRegistry.RenameValue(const OldName, NewName: UnicodeString);
 begin
   TXMLRegistry(FSysData).RenameValue(OldName,NewName);
 end;
 
+
 procedure TRegistry.SetCurrentKey(Value: HKEY);
 begin
   fCurrentKey := Value;

Bart Broersma

2019-03-17 12:38

reporter  

registry.unicode.part5.diff (67,948 bytes)
Index: packages/fcl-registry/src/regdef.inc
===================================================================
--- packages/fcl-registry/src/regdef.inc	(revision 41667)
+++ packages/fcl-registry/src/regdef.inc	(working copy)
@@ -2,7 +2,7 @@
   HKEY = THandle;
   PHKEY = ^HKEY;
   
-{$ifdef windows}
+{$if defined(windows) and not defined(XMLREG)}
 
 { Direct mapping to constants in Windows unit }
 
Index: packages/fcl-registry/src/registry.pp
===================================================================
--- packages/fcl-registry/src/registry.pp	(revision 41667)
+++ packages/fcl-registry/src/registry.pp	(working copy)
@@ -39,6 +39,8 @@
     DataSize: Integer;
   end;
 
+  TUnicodeStringArray = Array of UnicodeString;
+
 { ---------------------------------------------------------------------
     TRegistry
   ---------------------------------------------------------------------}
@@ -54,22 +56,31 @@
     fCurrentKey: HKEY;
     fRootKey: HKEY;
     fLazyWrite: Boolean;
-    fCurrentPath: string;
+    fCurrentPath: UnicodeString;
     function GetLastErrorMsg: string;
+    function RegMultiSzDataToUnicodeStringArray(U: UnicodeString): TUnicodeStringArray;
+    function ListToArray(List: TStrings; IsUtf8: Boolean): TUnicodeStringArray;
+    procedure ArrayToList(const Arr: TUnicodeStringArray; List: TStrings; ForceUtf8: Boolean);
     procedure SetRootKey(Value: HKEY);
     Procedure SysRegCreate;
     Procedure SysRegFree;
-    Function  SysGetData(const Name: String; Buffer: Pointer; BufSize: Integer; Out RegData: TRegDataType): Integer;
-    Function  SysPutData(const Name: string; Buffer: Pointer; BufSize: Integer; RegData: TRegDataType) : Boolean;
-    Function  SysCreateKey(const Key: String): Boolean;
+    Function  SysGetData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; Out RegData: TRegDataType): Integer;
+    Function  SysPutData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; RegData: TRegDataType) : Boolean;
+    Function  SysCreateKey(Key: UnicodeString): Boolean;
   protected
     function GetBaseKey(Relative: Boolean): HKey;
-    function GetData(const Name: string; Buffer: Pointer;
+    function GetData(const Name: UnicodeString; Buffer: Pointer;
                   BufSize: Integer; Out RegData: TRegDataType): Integer;
-    function GetKey(const Key: string): HKEY;
-    procedure ChangeKey(Value: HKey; const Path: string);
-    procedure PutData(const Name: string; Buffer: Pointer;
+    function GetData(const Name: String; Buffer: Pointer;
+                  BufSize: Integer; Out RegData: TRegDataType): Integer;
+    function GetKey(Key: UnicodeString): HKEY;
+    function GetKey(Key: String): HKEY;
+    procedure ChangeKey(Value: HKey; const Path: UnicodeString);
+    procedure ChangeKey(Value: HKey; const Path: String);
+    procedure PutData(const Name: UnicodeString; Buffer: Pointer;
                   BufSize: Integer; RegData: TRegDataType);
+    procedure PutData(const Name: String; Buffer: Pointer;
+                  BufSize: Integer; RegData: TRegDataType);
     procedure SetCurrentKey(Value: HKEY);
   public
     constructor Create; overload;
@@ -76,58 +87,105 @@
     constructor Create(aaccess:longword); overload;
     destructor Destroy; override;
 
-    function CreateKey(const Key: string): Boolean;
-    function DeleteKey(const Key: string): Boolean;
-    function DeleteValue(const Name: string): Boolean;
-    function GetDataInfo(const ValueName: string; Out Value: TRegDataInfo): Boolean;
-    function GetDataSize(const ValueName: string): Integer;
-    function GetDataType(const ValueName: string): TRegDataType;
+    function CreateKey(const Key: UnicodeString): Boolean;
+    function CreateKey(const Key: String): Boolean;
+    function DeleteKey(const Key: UnicodeString): Boolean;
+    function DeleteKey(const Key: String): Boolean;
+    function DeleteValue(const Name: UnicodeString): Boolean;
+    function DeleteValue(const Name: String): Boolean;
+    function GetDataInfo(const ValueName: UnicodeString; Out Value: TRegDataInfo): Boolean;
+    function GetDataInfo(const ValueName: String; Out Value: TRegDataInfo): Boolean;
+    function GetDataSize(const ValueName: UnicodeString): Integer;
+    function GetDataSize(const ValueName: String): Integer;
+    function GetDataType(const ValueName: UnicodeString): TRegDataType;
+    function GetDataType(const ValueName: String): TRegDataType;
     function GetKeyInfo(Out Value: TRegKeyInfo): Boolean;
     function HasSubKeys: Boolean;
-    function KeyExists(const Key: string): Boolean;
-    function LoadKey(const Key, FileName: string): Boolean;
-    function OpenKey(const Key: string; CanCreate: Boolean): Boolean;
-    function OpenKeyReadOnly(const Key: string): Boolean;
-    function ReadCurrency(const Name: string): Currency;
-    function ReadBinaryData(const Name: string; var Buffer; BufSize: Integer): Integer;
-    function ReadBool(const Name: string): Boolean;
-    function ReadDate(const Name: string): TDateTime;
-    function ReadDateTime(const Name: string): TDateTime;
-    function ReadFloat(const Name: string): Double;
-    function ReadInteger(const Name: string): Integer;
-    function ReadInt64(const Name: string): Int64;
-    function ReadString(const Name: string): string;
-    procedure ReadStringList(const Name: string; AList: TStrings);
-    function ReadTime(const Name: string): TDateTime;
-    function RegistryConnect(const UNCName: string): Boolean;
-    function ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
-    function RestoreKey(const Key, FileName: string): Boolean;
-    function SaveKey(const Key, FileName: string): Boolean;
-    function UnLoadKey(const Key: string): Boolean;
-    function ValueExists(const Name: string): Boolean;
+    function KeyExists(const Key: UnicodeString): Boolean;
+    function KeyExists(const Key: String): Boolean;
+    function LoadKey(const Key, FileName: UnicodeString): Boolean;
+    function LoadKey(const Key, FileName: String): Boolean;
+    function OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
+    function OpenKey(const Key: String; CanCreate: Boolean): Boolean;
+    function OpenKeyReadOnly(const Key: UnicodeString): Boolean;
+    function OpenKeyReadOnly(const Key: String): Boolean;
+    function ReadCurrency(const Name: UnicodeString): Currency;
+    function ReadCurrency(const Name: String): Currency;
+    function ReadBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer): Integer;
+    function ReadBinaryData(const Name: String; var Buffer; BufSize: Integer): Integer;
+    function ReadBool(const Name: UnicodeString): Boolean;
+    function ReadBool(const Name: String): Boolean;
+    function ReadDate(const Name: UnicodeString): TDateTime;
+    function ReadDate(const Name: String): TDateTime;
+    function ReadDateTime(const Name: UnicodeString): TDateTime;
+    function ReadDateTime(const Name: String): TDateTime;
+    function ReadFloat(const Name: UnicodeString): Double;
+    function ReadFloat(const Name: String): Double;
+    function ReadInteger(const Name: UnicodeString): Integer;
+    function ReadInteger(const Name: String): Integer;
+    function ReadInt64(const Name: UnicodeString): Int64;
+    function ReadInt64(const Name: String): Int64;
+    function ReadString(const Name: UnicodeString): UnicodeString;
+    function ReadString(const Name: String): string;
+    procedure ReadStringList(const Name: UnicodeString; AList: TStrings; ForceUtf8: Boolean=False);
+    procedure ReadStringList(const Name: String; AList: TStrings);
+    function ReadStringArray(const Name: UnicodeString): TUnicodeStringArray;
+    function ReadStringArray(const Name: String): TStringArray;
+    function ReadTime(const Name: UnicodeString): TDateTime;
+    function ReadTime(const Name: String): TDateTime;
+    function RegistryConnect(const UNCName: UnicodeString): Boolean;
+    function RegistryConnect(const UNCName: String): Boolean;
+    function ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
+    function ReplaceKey(const Key, FileName, BackUpFileName: String): Boolean;
+    function RestoreKey(const Key, FileName: UnicodeString): Boolean;
+    function RestoreKey(const Key, FileName: String): Boolean;
+    function SaveKey(const Key, FileName: UnicodeString): Boolean;
+    function SaveKey(const Key, FileName: String): Boolean;
+    function UnLoadKey(const Key: UnicodeString): Boolean;
+    function UnLoadKey(const Key: String): Boolean;
+    function ValueExists(const Name: UnicodeString): Boolean;
+    function ValueExists(const Name: String): Boolean;
 
     procedure CloseKey;
     procedure CloseKey(key:HKEY);
     procedure GetKeyNames(Strings: TStrings);
+    function GetKeyNames: TUnicodeStringArray;
     procedure GetValueNames(Strings: TStrings);
-    procedure MoveKey(const OldName, NewName: string; Delete: Boolean);
-    procedure RenameValue(const OldName, NewName: string);
-    procedure WriteCurrency(const Name: string; Value: Currency);
-    procedure WriteBinaryData(const Name: string; var Buffer; BufSize: Integer);
-    procedure WriteBool(const Name: string; Value: Boolean);
-    procedure WriteDate(const Name: string; Value: TDateTime);
-    procedure WriteDateTime(const Name: string; Value: TDateTime);
-    procedure WriteFloat(const Name: string; Value: Double);
-    procedure WriteInteger(const Name: string; Value: Integer);
-    procedure WriteInt64(const Name: string; Value: Int64);
-    procedure WriteString(const Name, Value: string);
-    procedure WriteExpandString(const Name, Value: string);
-    procedure WriteStringList(const Name: string; List: TStrings);
-    procedure WriteTime(const Name: string; Value: TDateTime);
+    //ToDo
+    function GetValueNames: TUnicodeStringArray;
+    procedure MoveKey(const OldName, NewName: UnicodeString; Delete: Boolean);
+    procedure MoveKey(const OldName, NewName: String; Delete: Boolean);
+    procedure RenameValue(const OldName, NewName: UnicodeString);
+    procedure RenameValue(const OldName, NewName: String);
+    procedure WriteCurrency(const Name: UnicodeString; Value: Currency);
+    procedure WriteCurrency(const Name: String; Value: Currency);
+    procedure WriteBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer);
+    procedure WriteBinaryData(const Name: String; var Buffer; BufSize: Integer);
+    procedure WriteBool(const Name: UnicodeString; Value: Boolean);
+    procedure WriteBool(const Name: String; Value: Boolean);
+    procedure WriteDate(const Name: UnicodeString; Value: TDateTime);
+    procedure WriteDate(const Name: String; Value: TDateTime);
+    procedure WriteDateTime(const Name: UnicodeString; Value: TDateTime);
+    procedure WriteDateTime(const Name: String; Value: TDateTime);
+    procedure WriteFloat(const Name: UnicodeString; Value: Double);
+    procedure WriteFloat(const Name: String; Value: Double);
+    procedure WriteInteger(const Name: UnicodeString; Value: Integer);
+    procedure WriteInteger(const Name: String; Value: Integer);
+    procedure WriteInt64(const Name: UnicodeString; Value: Int64);
+    procedure WriteInt64(const Name: String; Value: Int64);
+    procedure WriteString(const Name, Value: UnicodeString);
+    procedure WriteString(const Name, Value: String);
+    procedure WriteExpandString(const Name, Value: UnicodeString);
+    procedure WriteExpandString(const Name, Value: String);
+    procedure WriteStringList(const Name: UnicodeString; List: TStrings; IsUtf8: Boolean=False);
+    procedure WriteStringArray(const Name: UnicodeString; const Arr: TUnicodeStringArray);
+    procedure WriteStringArray(const Name: String; const Arr: TStringArray);
+    procedure WriteTime(const Name: UnicodeString; Value: TDateTime);
+    procedure WriteTime(const Name: String; Value: TDateTime);
 
     property Access: LongWord read fAccess write fAccess;
     property CurrentKey: HKEY read fCurrentKey;
-    property CurrentPath: string read fCurrentPath;
+    property CurrentPath: UnicodeString read fCurrentPath;
     property LazyWrite: Boolean read fLazyWrite write fLazyWrite;
     property RootKey: HKEY read fRootKey write SetRootKey;
     Property StringSizeIncludesNull : Boolean read FStringSizeIncludesNull;
@@ -235,6 +293,16 @@
     Generic, implementation-independent code.
   ---------------------------------------------------------------------}
 
+{$ifdef DebugRegistry}
+function DbgS(const S: UnicodeString): String;
+var
+  C: WideChar;
+begin
+  Result := '';
+  for C in S do Result := Result + IntToHex(Word(C),4) + #32;
+  Result := TrimRight(Result);
+end;
+{$endif}
 
 constructor TRegistry.Create;
 
@@ -261,7 +329,7 @@
   inherited Destroy;
 end;
 
-function TRegistry.CreateKey(const Key: string): Boolean;
+function TRegistry.CreateKey(const Key: UnicodeString): Boolean;
 
 begin
   Result:=SysCreateKey(Key);
@@ -269,6 +337,27 @@
     Raise ERegistryException.CreateFmt(SRegCreateFailed, [Key]);
 end;
 
+function TRegistry.CreateKey(const Key: String): Boolean;
+begin
+  Result:=CreateKey(UnicodeString(Key));
+end;
+
+function TRegistry.DeleteKey(const Key: String): Boolean;
+begin
+  Result:=DeleteKey(UnicodeString(Key));
+end;
+
+function TRegistry.DeleteValue(const Name: String): Boolean;
+begin
+  Result:=DeleteValue(UnicodeString(Name));
+end;
+
+function TRegistry.GetDataInfo(const ValueName: String; out Value: TRegDataInfo
+  ): Boolean;
+begin
+  Result:=GetDataInfo(UnicodeString(ValueName), Value);
+end;
+
 function TRegistry.GetBaseKey(Relative: Boolean): HKey;
 begin
   If Relative and (CurrentKey<>0) Then
@@ -277,7 +366,7 @@
     Result := RootKey;
 end;
 
-function TRegistry.GetData(const Name: string; Buffer: Pointer; BufSize: Integer; out RegData: TRegDataType): Integer;
+function TRegistry.GetData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; out RegData: TRegDataType): Integer;
 begin
   Result:=SysGetData(Name,Buffer,BufSize,RegData);
   If (Result=-1) then
@@ -284,7 +373,24 @@
     Raise ERegistryException.CreateFmt(SRegGetDataFailed, [Name]);
 end;
 
-procedure TRegistry.PutData(const Name: string; Buffer: Pointer;
+function TRegistry.GetData(const Name: String; Buffer: Pointer;
+  BufSize: Integer; out RegData: TRegDataType): Integer;
+begin
+  Result:=GetData(UnicodeString(Name), Buffer, BufSize, RegData);
+end;
+
+function TRegistry.GetKey(Key: String): HKEY;
+begin
+  Result:=GetKey(UnicodeString(Key));
+end;
+
+procedure TRegistry.ChangeKey(Value: HKey; const Path: String);
+begin
+  ChangeKey(Value, UnicodeString(Path));
+end;
+
+
+procedure TRegistry.PutData(const Name: UnicodeString; Buffer: Pointer;
   BufSize: Integer; RegData: TRegDataType);
 
 begin
@@ -292,9 +398,15 @@
     Raise ERegistryException.CreateFmt(SRegSetDataFailed, [Name]);
 end;
 
+procedure TRegistry.PutData(const Name: String; Buffer: Pointer;
+  BufSize: Integer; RegData: TRegDataType);
+begin
+  PutData(UnicodeString(Name), Buffer, BufSize, RegData);
+end;
 
-function TRegistry.GetDataSize(const ValueName: string): Integer;
 
+function TRegistry.GetDataSize(const ValueName: UnicodeString): Integer;
+
 Var
   Info: TRegDataInfo;
 
@@ -305,8 +417,13 @@
     Result := -1;
 end;
 
-function TRegistry.GetDataType(const ValueName: string): TRegDataType;
+function TRegistry.GetDataSize(const ValueName: String): Integer;
+begin
+  Result:=GetDataSize(UnicodeString(ValueName));
+end;
 
+function TRegistry.GetDataType(const ValueName: UnicodeString): TRegDataType;
+
 Var
   Info: TRegDataInfo;
 
@@ -315,6 +432,32 @@
   Result:=Info.RegData;
 end;
 
+function TRegistry.GetDataType(const ValueName: String): TRegDataType;
+begin
+  Result:=GetDataType(UnicodeString(ValueName));
+end;
+
+
+function TRegistry.KeyExists(const Key: String): Boolean;
+begin
+  Result:=KeyExists(UnicodeString(Key));
+end;
+
+function TRegistry.LoadKey(const Key, FileName: String): Boolean;
+begin
+  Result:=LoadKey(UnicodeString(Key), UnicodeString(FileName));
+end;
+
+function TRegistry.OpenKey(const Key: String; CanCreate: Boolean): Boolean;
+begin
+  Result:=OpenKey(UnicodeString(Key), CanCreate);
+end;
+
+function TRegistry.OpenKeyReadOnly(const Key: String): Boolean;
+begin
+  Result:=OpenKeyReadOnly(UnicodeString(Key));
+end;
+
 function TRegistry.HasSubKeys: Boolean;
 
 Var
@@ -326,7 +469,7 @@
     Result:=(Info.NumSubKeys>0);
 end;
 
-function TRegistry.ReadBinaryData(const Name: string; var Buffer; BufSize: Integer): Integer;
+function TRegistry.ReadBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer): Integer;
 
 Var
   RegDataType: TRegDataType;
@@ -337,8 +480,14 @@
     Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
 end;
 
-function TRegistry.ReadInteger(const Name: string): Integer;
+function TRegistry.ReadBinaryData(const Name: String; var Buffer;
+  BufSize: Integer): Integer;
+begin
+  Result:=ReadBinaryData(UnicodeString(Name), Buffer, BufSize);
+end;
 
+function TRegistry.ReadInteger(const Name: UnicodeString): Integer;
+
 Var
   RegDataType: TRegDataType;
 
@@ -348,8 +497,13 @@
     Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
 end;
 
-function TRegistry.ReadInt64(const Name: string): Int64;
+function TRegistry.ReadInteger(const Name: String): Integer;
+begin
+  Result:=ReadInteger(UnicodeString(Name));
+end;
 
+function TRegistry.ReadInt64(const Name: UnicodeString): Int64;
+
 Var
   RegDataType: TRegDataType;
 
@@ -359,21 +513,36 @@
     Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
 end;
 
-function TRegistry.ReadBool(const Name: string): Boolean;
+function TRegistry.ReadInt64(const Name: String): Int64;
+begin
+  Result:=ReadInt64(UnicodeString(Name));
+end;
 
+function TRegistry.ReadBool(const Name: UnicodeString): Boolean;
+
 begin
   Result:=ReadInteger(Name)<>0;
 end;
 
-function TRegistry.ReadCurrency(const Name: string): Currency;
+function TRegistry.ReadBool(const Name: String): Boolean;
+begin
+  Result:=ReadBool(UnicodeString(Name));
+end;
 
+function TRegistry.ReadCurrency(const Name: UnicodeString): Currency;
+
 begin
   Result:=Default(Currency);
   ReadBinaryData(Name, Result, SizeOf(Currency));
 end;
 
-function TRegistry.ReadDate(const Name: string): TDateTime;
+function TRegistry.ReadCurrency(const Name: String): Currency;
+begin
+  Result:=ReadCurrency(UnicodeString(Name));
+end;
 
+function TRegistry.ReadDate(const Name: UnicodeString): TDateTime;
+
 begin
   Result:=Default(TDateTime);
   ReadBinaryData(Name, Result, SizeOf(TDateTime));
@@ -380,22 +549,37 @@
   Result:=Trunc(Result);
 end;
 
-function TRegistry.ReadDateTime(const Name: string): TDateTime;
+function TRegistry.ReadDate(const Name: String): TDateTime;
+begin
+  Result:=ReadDate(UnicodeString(Name));
+end;
 
+function TRegistry.ReadDateTime(const Name: UnicodeString): TDateTime;
+
 begin
   Result:=Default(TDateTime);
   ReadBinaryData(Name, Result, SizeOf(TDateTime));
 end;
 
-function TRegistry.ReadFloat(const Name: string): Double;
+function TRegistry.ReadDateTime(const Name: String): TDateTime;
+begin
+  Result:=ReadDateTime(UnicodeString(Name));
+end;
 
+function TRegistry.ReadFloat(const Name: UnicodeString): Double;
+
 begin
   Result:=Default(Double);
   ReadBinaryData(Name,Result,SizeOf(Double));
 end;
 
-function TRegistry.ReadString(const Name: string): string;
+function TRegistry.ReadFloat(const Name: String): Double;
+begin
+  Result:=ReadFloat(UnicodeString(Name));
+end;
 
+function TRegistry.ReadString(const Name: UnicodeString): UnicodeString;
+
 Var
   Info : TRegDataInfo;
   ReadDataSize: Integer;
@@ -421,47 +605,139 @@
       if StringSizeIncludesNull and
          (u[Length(u)] = WideChar(0)) then
         SetLength(u,Length(u)-1);
-      Result:=UTF8Encode(u);
+      Result:=u;
     end;
   end;
 end;
 
-procedure TRegistry.ReadStringList(const Name: string; AList: TStrings);
+function TRegistry.ReadString(const Name: String): string;
+begin
+  Result:=ReadString(UnicodeString(Name));
+end;
 
+
+procedure TRegistry.ReadStringList(const Name: UnicodeString; AList: TStrings; ForceUtf8: Boolean=False);
+
 Var
+  UArr: TUnicodeStringArray;
+
+begin
+  UArr := ReadStringArray(Name);
+  ArrayToList(UArr, AList, ForceUtf8);
+end;
+
+procedure TRegistry.ReadStringList(const Name: String; AList: TStrings);
+begin
+  ReadStringList(UnicodeString(Name), AList);
+end;
+
+function TRegistry.RegMultiSzDataToUnicodeStringArray(U: UnicodeString): TUnicodeStringArray;
+var
+  Len, i, p: Integer;
+  Sub: UnicodeString;
+begin
+  Result := nil;
+  if (U = '') then Exit;
+  Len := 1;
+  for i := 1 to Length(U) do if (U[i] = #0) then Inc(Len);
+  SetLength(Result, Len);
+  i := 0;
+
+  while (U <> '') and (i < Length(Result)) do
+  begin
+    p := Pos(#0, U);
+    if (p = 0) then p := Length(U) + 1;
+    Sub := Copy(U, 1, p - 1);
+    Result[i] := Sub;
+    System.Delete(U, 1, p);
+    Inc(i);
+  end;
+end;
+
+function TRegistry.ListToArray(List: TStrings; IsUtf8: Boolean): TUnicodeStringArray;
+var
+  i, curr, Len: Integer;
+  u: UnicodeString;
+begin
+  Result := nil;
+  Len := List.Count;
+  SetLength(Result, Len);
+  //REG_MULTI_SZ data cannot contain empty strings
+  curr := 0;
+  for i := 0 to List.Count - 1 do
+  begin
+    if IsUtf8 then
+      u := Utf8Decode(List[i])
+    else
+      u := List[i];
+    if (u>'') then
+    begin
+      Result[curr] := u;
+      inc(curr);
+    end
+    else
+      Dec(Len);
+  end;
+  if (Len <> List.Count) then SetLength(Result, Len);
+end;
+
+procedure TRegistry.ArrayToList(const Arr: TUnicodeStringArray; List: TStrings; ForceUtf8: Boolean);
+var
+  i: Integer;
+begin
+  List.Clear;
+  for i := Low(Arr) to High(Arr) do
+  begin
+    if ForceUtf8 then
+      List.Add(Utf8Encode(Arr[i]))
+    else
+      List.Add(String(Arr[i]));
+  end;
+end;
+
+function TRegistry.ReadStringArray(const Name: UnicodeString): TUnicodeStringArray;
+Var
   Info : TRegDataInfo;
   ReadDataSize: Integer;
-  Data: string;
+  Data: UnicodeString;
 
 begin
-  AList.Clear;
+  Result := nil;
   GetDataInfo(Name,Info);
+  //writeln('TRegistry.ReadStringArray: datasize=',info.datasize);
   if info.datasize>0 then
     begin
      If Not (Info.RegData in [rdMultiString]) then
        Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
      SetLength(Data,Info.DataSize);
-     ReadDataSize := GetData(Name,PChar(Data),Info.DataSize,Info.RegData);
+     ReadDataSize := GetData(Name,PWideChar(Data),Info.DataSize,Info.RegData) div SizeOf(WideChar);
+     //writeln('TRegistry.ReadStringArray: ReadDataSize=',ReadDataSize);
      if ReadDataSize > 0 then
      begin
-       // If the data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type,
-       // the size includes any terminating null character or characters
-       // unless the data was stored without them! (RegQueryValueEx @ MSDN)
-       if StringSizeIncludesNull then begin
-         if Data[ReadDataSize] = #0 then
-           Dec(ReadDataSize);
-         if Data[ReadDataSize] = #0 then
-           Dec(ReadDataSize);
-       end;
+       // Windows returns the data with or without trailing zero's, so just strip all trailing null characters
+        while (Data[ReadDataSize] = #0) do Dec(ReadDataSize);
        SetLength(Data, ReadDataSize);
-       Data := StringReplace(Data, #0, LineEnding, [rfReplaceAll]);
-       AList.Text := Data;
+       //writeln('Data=',dbgs(data));
+       //Data := UnicodeStringReplace(Data, #0, AList.LineBreak, [rfReplaceAll]);
+       //AList.Text := Data;
+       Result := RegMultiSzDataToUnicodeStringArray(Data);
      end
    end
 end;
 
-function TRegistry.ReadTime(const Name: string): TDateTime;
+function TRegistry.ReadStringArray(const Name: String): TStringArray;
+var
+  UArr: TUnicodeStringArray;
+  i: Integer;
+begin
+  Result := nil;
+  UArr := ReadStringArray(UnicodeString(Name));
+  SetLength(Result, Length(UArr));
+  for i := Low(UArr) to High(UArr) do Result[i] := UArr[i];
+end;
 
+function TRegistry.ReadTime(const Name: UnicodeString): TDateTime;
+
 begin
   Result:=Default(TDateTime);
   ReadBinaryData(Name, Result, SizeOf(TDateTime));
@@ -468,85 +744,230 @@
   Result:=Frac(Result);
 end;
 
-procedure TRegistry.WriteBinaryData(const Name: string; var Buffer; BufSize: Integer);
+function TRegistry.ReadTime(const Name: String): TDateTime;
 begin
+  Result:=ReadTime(UnicodeString(Name));
+end;
+
+function TRegistry.RegistryConnect(const UNCName: String): Boolean;
+begin
+  Result:=RegistryConnect(UnicodeString(UNCName));
+end;
+
+function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: String): Boolean;
+begin
+  Result:=ReplaceKey(UnicodeString(Key), UnicodeString(FileName), UnicodeString(BackUpFileName))
+end;
+
+function TRegistry.RestoreKey(const Key, FileName: String): Boolean;
+begin
+  Result:=RestoreKey(UnicodeString(Key), UnicodeString(FileName));
+end;
+
+function TRegistry.SaveKey(const Key, FileName: String): Boolean;
+begin
+  Result:=SaveKey(UnicodeString(Key), UnicodeString(FileName));
+end;
+
+function TRegistry.UnLoadKey(const Key: String): Boolean;
+begin
+  Result:=UnloadKey(UnicodeString(Key));
+end;
+
+function TRegistry.ValueExists(const Name: String): Boolean;
+begin
+  Result:=ValueExists(UnicodeString(Name));
+end;
+
+procedure TRegistry.WriteBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer);
+begin
   PutData(Name, @Buffer, BufSize, rdBinary);
 end;
 
-procedure TRegistry.WriteBool(const Name: string; Value: Boolean);
+procedure TRegistry.WriteBinaryData(const Name: String; var Buffer;
+  BufSize: Integer);
+begin
+  WriteBinaryData(UnicodeString(Name), Buffer, BufSize);
+end;
 
+procedure TRegistry.WriteBool(const Name: UnicodeString; Value: Boolean);
+
 begin
   WriteInteger(Name,Ord(Value));
 end;
 
-procedure TRegistry.WriteCurrency(const Name: string; Value: Currency);
+procedure TRegistry.WriteBool(const Name: String; Value: Boolean);
 begin
+  WriteBool(UnicodeString(Name), Value);
+end;
+
+procedure TRegistry.WriteCurrency(const Name: UnicodeString; Value: Currency);
+begin
   WriteBinaryData(Name, Value, SizeOf(Currency));
 end;
 
-procedure TRegistry.WriteDate(const Name: string; Value: TDateTime);
+procedure TRegistry.WriteCurrency(const Name: String; Value: Currency);
 begin
+  WriteCurrency(UnicodeString(Name), Value);
+end;
+
+procedure TRegistry.WriteDate(const Name: UnicodeString; Value: TDateTime);
+begin
   WriteBinarydata(Name, Value, SizeOf(TDateTime));
 end;
 
-procedure TRegistry.WriteTime(const Name: string; Value: TDateTime);
+procedure TRegistry.WriteDate(const Name: String; Value: TDateTime);
 begin
+  WriteDate(UnicodeString(Name), Value);
+end;
+
+procedure TRegistry.WriteTime(const Name: UnicodeString; Value: TDateTime);
+begin
   WriteBinaryData(Name, Value, SizeOf(TDateTime));
 end;
 
-procedure TRegistry.WriteDateTime(const Name: string; Value: TDateTime);
+procedure TRegistry.WriteTime(const Name: String; Value: TDateTime);
 begin
+  WriteTime(UnicodeString(Name), Value);
+end;
+
+procedure TRegistry.WriteDateTime(const Name: UnicodeString; Value: TDateTime);
+begin
   WriteBinaryData(Name, Value, SizeOf(TDateTime));
 end;
 
-procedure TRegistry.WriteExpandString(const Name, Value: string);
-var
-  u: UnicodeString;
+procedure TRegistry.WriteDateTime(const Name: String; Value: TDateTime);
+begin
+  WriteDateTime(UnicodeString(Name), Value);
+end;
 
+procedure TRegistry.WriteExpandString(const Name, Value: UnicodeString);
 begin
-  u:=Value;
-  PutData(Name, PWideChar(u), ByteLength(u), rdExpandString);
+  PutData(Name, PWideChar(Value), ByteLength(Value), rdExpandString);
 end;
 
-procedure TRegistry.WriteStringList(const Name: string; List: TStrings);
+procedure TRegistry.WriteExpandString(const Name, Value: String);
+begin
+  WriteExpandString(UnicodeString(Name), UnicodeString(Value));
+end;
 
+
+procedure TRegistry.WriteStringList(const Name: UnicodeString; List: TStrings; IsUtf8: Boolean=False);
+
 Var
-  Data: string;
+  UArr: TUnicodeStringArray;
+begin
+  UArr := ListToArray(List, IsUtf8);
+  WriteStringArray(Name, UArr);
+end;
 
+procedure TRegistry.WriteStringArray(const Name: UnicodeString; const Arr: TUnicodeStringArray);
+Var
+  Data: UnicodeString;
+  u: UnicodeString;
+  i: Integer;
 begin
-  Data := StringReplace(List.Text, LineEnding, #0, [rfReplaceAll]) + #0#0;
-  PutData(Name, PChar(Data), Length(Data),rdMultiString);
+  Data := '';
+  //REG_MULTI_SZ data cannot contain empty strings
+  for i := Low(Arr) to High(Arr) do
+  begin
+    u := Arr[i];
+    if (u>'') then
+    begin
+      if (Data>'') then
+        Data := Data + #0 + u
+      else
+        Data := Data + u;
+    end;
+  end;
+  if StringSizeIncludesNull then
+    Data := Data + #0#0;
+  //writeln('Data=',Dbgs(Data));
+  PutData(Name, PWideChar(Data), ByteLength(Data), rdMultiString);
 end;
 
-procedure TRegistry.WriteFloat(const Name: string; Value: Double);
+procedure TRegistry.WriteStringArray(const Name: String; const Arr: TStringArray);
+var
+  UArr: TUnicodeStringArray;
+  i: Integer;
 begin
+  UArr := nil;
+  SetLength(UArr, Length(Arr));
+  for i := Low(Arr) to High(Arr) do UArr[i] := Arr[i];
+  WriteStringArray(UnicodeString(Name), UArr);
+end;
+
+procedure TRegistry.WriteFloat(const Name: UnicodeString; Value: Double);
+begin
   WriteBinaryData(Name, Value, SizeOf(Double));
 end;
 
-procedure TRegistry.WriteInteger(const Name: string; Value: Integer);
+procedure TRegistry.WriteFloat(const Name: String; Value: Double);
 begin
+  WriteFloat(UnicodeString(Name), Value);
+end;
+
+procedure TRegistry.WriteInteger(const Name: UnicodeString; Value: Integer);
+begin
   PutData(Name, @Value, SizeOf(Integer), rdInteger);
 end;
 
-procedure TRegistry.WriteInt64(const Name: string; Value: Int64);
+procedure TRegistry.WriteInteger(const Name: String; Value: Integer);
 begin
+  WriteInteger(UnicodeString(Name), Value);
+end;
+
+procedure TRegistry.WriteInt64(const Name: UnicodeString; Value: Int64);
+begin
   PutData(Name, @Value, SizeOf(Int64), rdInt64);
 end;
 
-procedure TRegistry.WriteString(const Name, Value: string);
+procedure TRegistry.WriteInt64(const Name: String; Value: Int64);
+begin
+  WriteInt64(UnicodeString(Name), Value);
+end;
+
+procedure TRegistry.WriteString(const Name, Value: UnicodeString);
+begin
+  PutData(Name, PWideChar(Value), ByteLength(Value), rdString);
+end;
+
+procedure TRegistry.WriteString(const Name, Value: String);
+begin
+  WriteString(UnicodeString(Name), UnicodeString(Value));
+end;
+
+procedure TRegistry.GetKeyNames(Strings: TStrings);
 var
-  u: UnicodeString;
+  UArr: TUnicodeStringArray;
+begin
+  UArr := GetKeyNames;
+  ArrayToList(UArr, Strings, True);
+end;
 
+procedure TRegistry.GetValueNames(Strings: TStrings);
+var
+  UArr: TUnicodeStringArray;
 begin
-  u:=Value;
-  PutData(Name, PWideChar(u), ByteLength(u), rdString);
+  UArr := GetValueNames;
+  ArrayToList(UArr, Strings, True);
 end;
 
-procedure TRegistry.MoveKey(const OldName, NewName: string; Delete: Boolean);
+procedure TRegistry.MoveKey(const OldName, NewName: UnicodeString; Delete: Boolean);
 begin
 
 end;
 
+procedure TRegistry.MoveKey(const OldName, NewName: String; Delete: Boolean);
+begin
+  MoveKey(UnicodeString(OldName), UnicodeString(NewName), Delete);
+end;
+
+procedure TRegistry.RenameValue(const OldName, NewName: String);
+begin
+  RenameValue(UnicodeString(OldName), UnicodeString(NewName));
+end;
+
 { ---------------------------------------------------------------------
     Include TRegIniFile implementation
   ---------------------------------------------------------------------}
@@ -583,7 +1004,7 @@
   Value: TStream): Integer;
 begin
   result:=-1; // unimplemented
- // 
+ //
 end;
 
 function TRegistryIniFile.ReadDate(const Section, Name: string;
Index: packages/fcl-registry/src/winreg.inc
===================================================================
--- packages/fcl-registry/src/winreg.inc	(revision 41667)
+++ packages/fcl-registry/src/winreg.inc	(working copy)
@@ -28,7 +28,7 @@
   Dispose(PWinRegData(FSysData));
 end;
 
-Function PrepKey(Const S : String) : String;
+Function PrepKey(Const S : UnicodeString) : UnicodeString;
 
 begin
   Result := S;
@@ -36,7 +36,7 @@
     System.Delete(Result, 1, 1);
 end;
 
-Function RelativeKey(Const S : String) : Boolean;
+Function RelativeKey(Const S : UnicodeString) : Boolean;
 
 begin
   Result:=(S='') or (S[1]<>'\')
@@ -43,9 +43,8 @@
 end;
 
 
-function TRegistry.sysCreateKey(const Key: String): Boolean;
+function TRegistry.sysCreateKey(Key: UnicodeString): Boolean;
 Var
-  u: UnicodeString;
   Disposition: Dword;
   Handle: HKEY;
   SecurityAttributes: Pointer; //LPSECURITY_ATTRIBUTES;
@@ -52,9 +51,9 @@
 
 begin
   SecurityAttributes := Nil;
-  u:=PrepKey(Key);
+  Key:=PrepKey(Key);
   FLastError:=RegCreateKeyExW(GetBaseKey(RelativeKey(Key)),
-                              PWideChar(u),
+                              PWideChar(Key),
                               0,
                               '',
                               REG_OPTION_NON_VOLATILE,
@@ -66,7 +65,7 @@
   RegCloseKey(Handle);
 end;
 
-function TRegistry.DeleteKey(const Key: String): Boolean;
+function TRegistry.DeleteKey(const Key: UnicodeString): Boolean;
 
 Var
   u: UnicodeString;
@@ -76,21 +75,21 @@
   Result:=FLastError=ERROR_SUCCESS;
 end;
 
-function TRegistry.DeleteValue(const Name: String): Boolean;
+
+function TRegistry.DeleteValue(const Name: UnicodeString): Boolean;
 begin
-  FLastError:= RegDeleteValueW(fCurrentKey, PWideChar(UnicodeString(Name)));
+  FLastError:= RegDeleteValueW(fCurrentKey, PWideChar(Name));
   Result:=FLastError=ERROR_SUCCESS;
 end;
 
-function TRegistry.SysGetData(const Name: String; Buffer: Pointer;
+
+function TRegistry.SysGetData(const Name: UnicodeString; Buffer: Pointer;
           BufSize: Integer; Out RegData: TRegDataType): Integer;
 Var
-  u: UnicodeString;
   RD : DWord;
 
 begin
-  u := Name;
-  FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(u),Nil,
+  FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(Name),Nil,
                       @RD,Buffer,lpdword(@BufSize));
   if (FLastError<>ERROR_SUCCESS) Then
     Result:=-1
@@ -103,17 +102,15 @@
     end;
 end;
 
-function TRegistry.GetDataInfo(const ValueName: String; out Value: TRegDataInfo): Boolean;
+function TRegistry.GetDataInfo(const ValueName: UnicodeString; out Value: TRegDataInfo): Boolean;
 
 Var
-  u: UnicodeString;
   RD : DWord;
 
 begin
-  u:=ValueName;
   With Value do
     begin
-    FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(u),Nil,lpdword(@RegData),Nil,lpdword(@DataSize));
+    FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(ValueName),Nil,lpdword(@RegData),Nil,lpdword(@DataSize));
     Result:=FLastError=ERROR_SUCCESS;
     if Result then
       begin
@@ -131,24 +128,18 @@
 end;
 
 
-function TRegistry.GetKey(const Key: String): HKEY;
+function TRegistry.GetKey(Key: UnicodeString): HKEY;
 var
-  S : string;
-{$ifndef WinCE}
-  u : UnicodeString;
-{$endif}
   Rel : Boolean;
 begin
   Result:=0;
-  S:=Key;
-  Rel:=RelativeKey(S);
+  Rel:=RelativeKey(Key);
   if not(Rel) then
-    Delete(S,1,1);
+    Delete(Key,1,1);
 {$ifdef WinCE}
-  FLastError:=RegOpenKeyEx(GetBaseKey(Rel),PWideChar(WideString(S)),0,FAccess,Result);
+  FLastError:=RegOpenKeyEx(GetBaseKey(Rel),PWideChar(Key),0,FAccess,Result);
 {$else WinCE}
-  u:=UnicodeString(S);
-  FLastError:=RegOpenKeyExW(GetBaseKey(Rel),PWideChar(u),0,FAccess,Result);
+  FLastError:=RegOpenKeyExW(GetBaseKey(Rel),PWideChar(Key),0,FAccess,Result);
 {$endif WinCE}
 end;
 
@@ -158,7 +149,7 @@
   winFileTime: Windows.FILETIME;
   sysTime: TSystemTime;
 begin
-  FillChar(Value, SizeOf(Value), 0);
+  Value := Default(TRegKeyInfo);
   With Value do
     begin
     FLastError:=RegQueryInfoKeyA(CurrentKey,nil,nil,nil,lpdword(@NumSubKeys),
@@ -174,7 +165,7 @@
 end;
 
 
-function TRegistry.KeyExists(const Key: string): Boolean;
+function TRegistry.KeyExists(const Key: UnicodeString): Boolean;
 var
   KeyHandle : HKEY;
   OldAccess : LONG;
@@ -196,20 +187,20 @@
 end;
 
 
-function TRegistry.LoadKey(const Key, FileName: string): Boolean;
+function TRegistry.LoadKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
 
-function TRegistry.OpenKey(const Key: string; CanCreate: Boolean): Boolean;
 
+function TRegistry.OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
+
 Var
-  u: UnicodeString;
+  u, S: UnicodeString;
   Handle: HKEY;
   Disposition: Integer;
   SecurityAttributes: Pointer; //LPSECURITY_ATTRIBUTES;
-  S: string;
 begin
   SecurityAttributes := Nil;
   u:=PrepKey(Key);
@@ -232,13 +223,14 @@
     if RelativeKey(Key) then
       S:=CurrentPath + Key
     else
-      S:=UTF8Encode(u);
+      S:=u;
     ChangeKey(Handle, S);
   end;
 end;
 
-function TRegistry.OpenKeyReadOnly(const Key: string): Boolean;
 
+function TRegistry.OpenKeyReadOnly(const Key: UnicodeString): Boolean;
+
 Var
   OldAccess: LongWord;
 begin
@@ -251,7 +243,8 @@
   end;
 end;
 
-function TRegistry.RegistryConnect(const UNCName: string): Boolean;
+
+function TRegistry.RegistryConnect(const UNCName: UnicodeString): Boolean;
 {$ifndef WinCE}
 var
   newroot: HKEY;
@@ -260,7 +253,7 @@
 {$ifdef WinCE}
   Result:=False;
 {$else}
-  FLastError:=RegConnectRegistryW(PWideChar(UnicodeString(UNCName)),RootKey,newroot);
+  FLastError:=RegConnectRegistryW(PWideChar(UNCName),RootKey,newroot);
   Result:=FLastError=ERROR_SUCCESS;
   if Result then begin
     RootKey:=newroot;
@@ -269,28 +262,33 @@
 {$endif}
 end;
 
-function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
+
+function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.RestoreKey(const Key, FileName: string): Boolean;
+
+function TRegistry.RestoreKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.SaveKey(const Key, FileName: string): Boolean;
+
+function TRegistry.SaveKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.UnLoadKey(const Key: string): Boolean;
+
+function TRegistry.UnLoadKey(const Key: UnicodeString): Boolean;
 begin
   Result := false;
 end;
 
-function TRegistry.ValueExists(const Name: string): Boolean;
 
+function TRegistry.ValueExists(const Name: UnicodeString): Boolean;
+
 var
   Info : TRegDataInfo;
 
@@ -298,6 +296,7 @@
   Result:=GetDataInfo(Name,Info);
 end;
 
+
 procedure TRegistry.CloseKey;
 begin
   If (CurrentKey<>0) then
@@ -316,7 +315,7 @@
   RegCloseKey(key);
 end;
 
-procedure TRegistry.ChangeKey(Value: HKey; const Path: String);
+procedure TRegistry.ChangeKey(Value: HKey; const Path: UnicodeString);
 begin
   CloseKey;
   FCurrentKey:=Value;
@@ -323,8 +322,9 @@
   FCurrentPath:=Path;
 end;
 
-procedure TRegistry.GetKeyNames(Strings: TStrings);
 
+function TRegistry.GetKeyNames: TUnicodeStringArray;
+
 var
   Info:    TRegKeyInfo;
   dwLen:   DWORD;
@@ -331,15 +331,17 @@
   lpName:  LPWSTR;
   dwIndex: DWORD;
   lResult: LONGINT;
-  s:       string;
+  u:       UnicodeString;
 
 begin
-  Strings.Clear;
+  Result:=nil;
   if GetKeyInfo(Info) then
   begin
     dwLen:=Info.MaxSubKeyLen+1;
     GetMem(lpName,dwLen*SizeOf(WideChar));
     try
+      //writeln('TRegistry.GetKeyNames: Info.NumSubKeys=',Info.NumSubKeys);
+      SetLength(Result, Info.NumSubKeys);
       for dwIndex:=0 to Info.NumSubKeys-1 do
       begin
         dwLen:=Info.MaxSubKeyLen+1;
@@ -347,19 +349,13 @@
         if lResult<>ERROR_SUCCESS then
           raise ERegistryException.Create(SysErrorMessage(lResult));
         if dwLen=0 then
-          s:=''
+          u:=''
         else
         begin           // dwLen>0
-          SetLength(s,dwLen*3);
-          dwLen:=UnicodeToUTF8(PChar(s),Length(s)+1,lpName,dwLen);
-          if dwLen<=1 then
-            s:=''
-          else          // dwLen>1
-            SetLength(s,dwLen-1);
+          u:=lpName;
         end;            // if dwLen=0
-        Strings.Add(s);
+        Result[dwIndex]:=u;
       end;              // for dwIndex:=0 ...
-
     finally
       FreeMem(lpName);
     end;
@@ -366,8 +362,9 @@
   end;
 end;
 
-procedure TRegistry.GetValueNames(Strings: TStrings);
 
+Function TRegistry.GetValueNames: TUnicodeStringArray;
+
 var
   Info:    TRegKeyInfo;
   dwLen:   DWORD;
@@ -374,15 +371,16 @@
   lpName:  LPWSTR;
   dwIndex: DWORD;
   lResult: LONGINT;
-  s:       string;
+  u:       UnicodeString;
 
 begin
-   Strings.Clear;
+  Result:=nil;
   if GetKeyInfo(Info) then
   begin
     dwLen:=Info.MaxValueLen+1;
     GetMem(lpName,dwLen*SizeOf(WideChar));
     try
+      SetLength(Result, Info.NumValues);
       for dwIndex:=0 to Info.NumValues-1 do
       begin
         dwLen:=Info.MaxValueLen+1;
@@ -390,17 +388,12 @@
         if lResult<>ERROR_SUCCESS then
           raise ERegistryException.Create(SysErrorMessage(lResult));
         if dwLen=0 then
-          s:=''
+          u:=''
         else
         begin           // dwLen>0
-          SetLength(s,dwLen*3);
-          dwLen:=UnicodeToUTF8(PChar(s),Length(s)+1,lpName,dwLen);
-          if dwLen<=1 then
-            s:=''
-          else          // dwLen>1
-            SetLength(s,dwLen-1);
+          u:=lpName;
         end;            // if dwLen=0
-        Strings.Add(s);
+        Result[dwIndex]:=u;
       end;              // for dwIndex:=0 ...
 
     finally
@@ -410,12 +403,11 @@
 end;
 
 
-Function TRegistry.SysPutData(const Name: string; Buffer: Pointer;
+Function TRegistry.SysPutData(const Name: UnicodeString; Buffer: Pointer;
   BufSize: Integer; RegData: TRegDataType) : Boolean;
 
 
 Var
-  u: UnicodeString;
   RegDataType: DWORD;
   B : Pchar;
   S : String;
@@ -422,12 +414,11 @@
 
 begin
   RegDataType:=RegDataWords[RegData];
-  u:=UnicodeString(Name);
-  FLastError:=RegSetValueExW(fCurrentKey,PWideChar(u),0,RegDataType,Buffer,BufSize);
+  FLastError:=RegSetValueExW(fCurrentKey,PWideChar(Name),0,RegDataType,Buffer,BufSize);
   Result:=FLastError=ERROR_SUCCESS;
 end;
 
-procedure TRegistry.RenameValue(const OldName, NewName: string);
+procedure TRegistry.RenameValue(const OldName, NewName: UnicodeString);
 
 var
   L: Integer;
Index: packages/fcl-registry/src/xmlreg.pp
===================================================================
--- packages/fcl-registry/src/xmlreg.pp	(revision 41667)
+++ packages/fcl-registry/src/xmlreg.pp	(working copy)
@@ -25,6 +25,7 @@
     FTime     : TDateTime;
   end;
 
+  TUnicodeStringArray = Array of UnicodeString;
 
   { TXmlRegistry }
 
@@ -33,24 +34,24 @@
     FAutoFlush,
     FDirty : Boolean;
     FFileName : String;
-    FRootKey : String;
+    FRootKey : UnicodeString;
     FDocument : TXMLDocument;
     FCurrentElement : TDomElement;
-    FCurrentKey : String;
+    FCurrentKey : UnicodeString;
     Procedure SetFileName(Value : String);
   Protected
-    function DoGetValueData(Name: String; out DataType: TDataType; Var Data; Var DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
-    function DoSetValueData(Name: String; DataType: TDataType; const Data; DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
+    function DoGetValueData(Name: UnicodeString; out DataType: TDataType; Var Data; Var DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
+    function DoSetValueData(Name: UnicodeString; DataType: TDataType; const Data; DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
     Procedure LoadFromStream(S : TStream);
-    Function  NormalizeKey(KeyPath : String) : String;
+    Function  NormalizeKey(KeyPath : UnicodeString) : UnicodeString;
     Procedure CreateEmptyDoc;
-    Function  FindKey (S : String) : TDomElement;
-    Function  FindSubKey (S : String; N : TDomElement) : TDomElement;
-    Function  CreateSubKey (S : String; N : TDomElement) : TDomElement;
-    Function  FindValueKey (S : String) : TDomElement;
-    Function  CreateValueKey (S : String) : TDomElement;
+    Function  FindKey (S : UnicodeString) : TDomElement;
+    Function  FindSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
+    Function  CreateSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
+    Function  FindValueKey (S : UnicodeString) : TDomElement;
+    Function  CreateValueKey (S : UnicodeString) : TDomElement;
     Function  BufToHex(Const Buf; Len : Integer) : String;
-    Function  hexToBuf(Const Str : String; Var Buf; Var Len : Integer ) : Integer;
+    Function  HexToBuf(Const Str : UnicodeString; Var Buf; Var Len : Integer ) : Integer;
     Procedure MaybeFlush;
     Property  Document : TXMLDocument Read FDocument;
     Property  Dirty : Boolean Read FDirty write FDirty;
@@ -57,29 +58,31 @@
   Public
     Constructor Create(AFileName : String);
     Destructor  Destroy;override;
-    Function  SetKey(KeyPath : String; AllowCreate : Boolean) : Boolean ;
-    Procedure SetRootKey(Value : String);
-    Function  DeleteKey(KeyPath : String) : Boolean;
-    Function  CreateKey(KeyPath : String) : Boolean;
-    Function  GetValueSize(Name : String) : Integer;
-    Function  GetValueType(Name : String) : TDataType;
-    Function  GetValueInfo(Name : String; Out Info : TDataInfo; AsUnicode : Boolean = False) : Boolean;
+    Function  SetKey(KeyPath : UnicodeString; AllowCreate : Boolean) : Boolean ;
+    Procedure SetRootKey(Value : UnicodeString);
+    Function  DeleteKey(KeyPath : UnicodeString) : Boolean;
+    Function  CreateKey(KeyPath : UnicodeString) : Boolean;
+    Function  GetValueSize(Name : UnicodeString) : Integer;
+    Function  GetValueType(Name : UnicodeString) : TDataType;
+    Function  GetValueInfo(Name : UnicodeString; Out Info : TDataInfo; AsUnicode : Boolean = False) : Boolean;
     Function  GetKeyInfo(Out Info : TKeyInfo) : Boolean;
     Function  EnumSubKeys(List : TStrings) : Integer;
+    Function  EnumSubKeys: TUnicodeStringArray;
     Function  EnumValues(List : TStrings) : Integer;
-    Function  KeyExists(KeyPath : String) : Boolean;
-    Function  ValueExists(ValueName : String) : Boolean;
-    Function  RenameValue(Const OldName,NewName : String) : Boolean;
-    Function  DeleteValue(S : String) : Boolean;
+    Function  EnumValues: TUnicodeStringArray;
+    Function  KeyExists(KeyPath : UnicodeString) : Boolean;
+    Function  ValueExists(ValueName : UnicodeString) : Boolean;
+    Function  RenameValue(Const OldName,NewName : UnicodeString) : Boolean;
+    Function  DeleteValue(S : UnicodeString) : Boolean;
     Procedure Flush;
     Procedure Load;
-    Function GetValueData(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
-    Function SetValueData(Name : String; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
+    Function GetValueData(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
+    Function SetValueData(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
     // These interpret the Data buffer as unicode data
-    Function GetValueDataUnicode(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
-    Function SetValueDataUnicode(Name : String; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
+    Function GetValueDataUnicode(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
+    Function SetValueDataUnicode(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
     Property FileName : String Read FFileName Write SetFileName;
-    Property RootKey : String Read FRootKey Write SetRootkey;
+    Property RootKey : UnicodeString Read FRootKey Write SetRootkey;
     Property AutoFlush : Boolean Read FAutoFlush Write FAutoFlush;
   end;
 
@@ -143,13 +146,13 @@
   end;
 end;
 
-Function TXmlRegistry.NormalizeKey(KeyPath : String) : String;
+Function TXmlRegistry.NormalizeKey(KeyPath : UnicodeString) : UnicodeString;
 
 Var
   L : Integer;
 
 begin
-  Result:=StringReplace(KeyPath,'\','/',[rfReplaceAll]);
+  Result:=UnicodeStringReplace(KeyPath,'\','/',[rfReplaceAll]);
   L:=Length(Result);
   If (L>0) and (Result[L]<>'/') then
     Result:=Result+'/';
@@ -157,10 +160,10 @@
     Result:='/' + Result;
 end;
 
-Function TXmlRegistry.SetKey(KeyPath : String; AllowCreate : Boolean) : boolean;
+Function TXmlRegistry.SetKey(KeyPath : UnicodeString; AllowCreate : Boolean) : boolean;
 
 Var
-  SubKey,ResultKey : String;
+  SubKey,ResultKey : UnicodeString;
   P : Integer;
   Node,Node2 : TDomElement;
 
@@ -218,7 +221,7 @@
   MaybeFlush;
 end;
 
-Procedure TXmlRegistry.SetRootKey(Value : String);
+Procedure TXmlRegistry.SetRootKey(Value : UnicodeString);
 
 begin
   FRootKey:=NormalizeKey(Value);
@@ -228,7 +231,7 @@
   FCurrentElement:=Nil;
 end;
 
-Function TXmlRegistry.DeleteKey(KeyPath : String) : Boolean;
+Function TXmlRegistry.DeleteKey(KeyPath : UnicodeString) : Boolean;
 
 Var
   N : TDomElement;
@@ -244,10 +247,10 @@
    end;
 end;
 
-Function TXmlRegistry.CreateKey(KeyPath : String) : Boolean;
+Function TXmlRegistry.CreateKey(KeyPath : UnicodeString) : Boolean;
 
 Var
-  SubKey : String;
+  SubKey : UnicodeString;
   P : Integer;
   Node,Node2 : TDomElement;
 
@@ -290,7 +293,7 @@
   MaybeFlush;
 end;
 
-Function TXmlRegistry.DoGetValueData(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer; IsUnicode : Boolean) : Boolean;
+Function TXmlRegistry.DoGetValueData(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer; IsUnicode : Boolean) : Boolean;
 
 Type
   PCardinal = ^Cardinal;
@@ -305,22 +308,27 @@
   D : DWord;
   
 begin
+  //writeln('TXmlRegistry.DoGetValueData: Name=',Name,' IsUnicode=',IsUnicode);
   Node:=FindValueKey(Name);
   Result:=Node<>Nil;
   If Result then
     begin
+    //writeln('TXmlRegistry.DoGetValueData: Node<>nil');
     DataNode:=Node.FirstChild;
     HasData:=Assigned(DataNode) and (DataNode.NodeType=TEXT_NODE);
-    ND:=StrToIntDef(Node[Stype],0);
+    //writeln('TXmlRegistry.DoGetValueData: HasData=',hasdata);
+    ND:=StrToIntDef(String(Node[Stype]),0);
+    //writeln('TXmlRegistry.DoGetValueData: ND=',ND);
     Result:=ND<=Ord(High(TDataType));
     If Result then
       begin
       DataType:=TDataType(ND);
+      //writeln('TXmlRegistry.DoGetValueData: DataType=',DataType);
       NS:=0; // Initialize, for optional nodes.
       Case DataType of
         dtDWORD : begin   // DataNode is required
                   NS:=SizeOf(Cardinal);
-                  Result:=HasData and TryStrToDWord(DataNode.NodeValue,D) and (DataSize>=NS);
+                  Result:=HasData and TryStrToDWord(String(DataNode.NodeValue),D) and (DataSize>=NS);
                   if Result then
                     PCardinal(@Data)^:=D;
                   end;
@@ -329,7 +337,7 @@
                      begin
                      if not IsUnicode then
                        begin
-                       S:=UTF8Encode(DataNode.NodeValue); // Convert to ansistring
+                       S:=DataNode.NodeValue; // Convert to ansistring
                        NS:=Length(S);
                        Result:=(DataSize>=NS);
                        if Result then
@@ -350,8 +358,10 @@
                    if HasData then
                      begin
                      BL:=Length(DataNode.NodeValue);
+                     //writeln('TXmlRegistry.DoGetValueData: BL=',BL);
                      NS:=BL div 2;
                      Result:=DataSize>=NS;
+                     //writeln('TXmlRegistry.DoGetValueData: Result=',Result);
                      If Result then
                        // No need to check for -1, We checked NS before calling.
                        NS:=HexToBuf(DataNode.NodeValue,Data,BL);
@@ -363,7 +373,7 @@
     end;
 end;
 
-Function TXmlRegistry.DoSetValueData(Name : String; DataType : TDataType; Const Data; DataSize : Integer; IsUnicode : Boolean) : Boolean;
+Function TXmlRegistry.DoSetValueData(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer; IsUnicode : Boolean) : Boolean;
 
 Type
   PCardinal = ^Cardinal;
@@ -374,6 +384,7 @@
   SW : UnicodeString;
 
 begin
+  //writeln('TXmlRegistry.DoSetValueData A: Name=',Name,', DataType=',DataType,', DataSize=',DataSize,', IsUnicode=',IsUnicode);
   Node:=FindValueKey(Name);
   If Node=Nil then
     Node:=CreateValueKey(Name);
@@ -380,20 +391,20 @@
   Result:=(Node<>Nil);
   If Result then
     begin
-    Node[SType]:=IntToStr(Ord(DataType));
+    Node[SType]:=UnicodeString(IntToStr(Ord(DataType)));
     DataNode:=Node.FirstChild;
 
     Case DataType of
-      dtDWORD : SW:=IntToStr(PCardinal(@Data)^);
+      dtDWORD : SW:=UnicodeString(IntToStr(PCardinal(@Data)^));
       dtString : begin
                  if IsUnicode then
                    SW:=UnicodeString(PUnicodeChar(@Data))
                  else
                    SW:=UnicodeString(PAnsiChar(@Data));
-                   //S:=UTF8Encode(SW);
+                   //S:=SW;
                  end;
-      dtBinary : SW:=BufToHex(Data,DataSize);
-      dtStrings : SW:=BufToHex(Data,DataSize);
+      dtBinary : SW:=UnicodeString(BufToHex(Data,DataSize));
+      dtStrings : SW:=UnicodeString(BufToHex(Data,DataSize));
     else
       sw:='';
     end;
@@ -416,29 +427,29 @@
     end;
 end;
 
-Function TXmlRegistry.SetValueData(Name : String; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
+Function TXmlRegistry.SetValueData(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
 
 begin
   Result:=DoSetValueData(Name,DataType,Data,DataSize,False);
 end;
 
-Function TXmlRegistry.GetValueData(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
+Function TXmlRegistry.GetValueData(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
 
 begin
   Result:=DoGetValueData(Name,DataType,Data,DataSize,False);
 end;
 
-function TXmlRegistry.GetValueDataUnicode(Name: String; out DataType: TDataType; Var Data; Var DataSize: Integer): Boolean;
+function TXmlRegistry.GetValueDataUnicode(Name: UnicodeString; out DataType: TDataType; Var Data; Var DataSize: Integer): Boolean;
 begin
   Result:=DoGetValueData(Name,DataType,Data,DataSize,True);
 end;
 
-function TXmlRegistry.SetValueDataUnicode(Name: String; DataType: TDataType; const Data; DataSize: Integer): Boolean;
+function TXmlRegistry.SetValueDataUnicode(Name: UnicodeString; DataType: TDataType; const Data; DataSize: Integer): Boolean;
 begin
   Result:=DoSetValueData(Name,DataType,Data,DataSize,True)
 end;
 
-Function TXmlRegistry.FindSubKey (S : String; N : TDomElement) : TDomElement;
+Function TXmlRegistry.FindSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
 
 Var
   Node : TDOMNode;
@@ -451,7 +462,7 @@
     While (Result=Nil) and (Assigned(Node)) do
       begin
       If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SKey) then
-        If CompareText(TDomElement(Node)[SName],S)=0 then
+        If UnicodeCompareText(TDomElement(Node)[SName],S)=0 then
           Result:=TDomElement(Node);
       Node:=Node.NextSibling;
       end;
@@ -458,7 +469,7 @@
     end;
 end;
 
-Function TXmlRegistry.CreateSubKey (S : String; N : TDomElement) : TDomElement;
+Function TXmlRegistry.CreateSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
 
 begin
   Result:=FDocument.CreateElement(SKey);
@@ -468,7 +479,7 @@
   FDirty:=True;
 end;
 
-Function  TXmlRegistry.FindValueKey (S : String) : TDomElement;
+Function  TXmlRegistry.FindValueKey (S : UnicodeString) : TDomElement;
 
 Var
   Node : TDOMNode;
@@ -481,7 +492,7 @@
     While (Result=Nil) and (Assigned(Node)) do
       begin
       If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SValue) then
-        If CompareText(TDomElement(Node)[SName],S)=0 then
+        If UnicodeCompareText(TDomElement(Node)[SName],S)=0 then
           Result:=TDomElement(Node);
       Node:=Node.NextSibling;
       end;
@@ -488,7 +499,7 @@
     end;
 end;
 
-Function  TXmlRegistry.CreateValueKey (S : String) : TDomElement;
+Function  TXmlRegistry.CreateValueKey (S : UnicodeString) : TDomElement;
 
 begin
   If Assigned(FCurrentElement) then
@@ -581,38 +592,47 @@
     end;
 end;
 
-Function TXMLRegistry.hexToBuf(Const Str : String; Var Buf; Var Len : Integer ) : Integer;
+Function TXMLRegistry.HexToBuf(Const Str : UnicodeString; Var Buf; Var Len : Integer ) : Integer;
 
 Var
   NLeN,I : Integer;
   P : PByte;
-  S : String;
+  S : UnicodeString;
   B : Byte;
   Code : Integer;
 
 begin
+  //writeln('TXMLRegistry.HexToBuf A: Str=',Str,', Len=',Len);
   Result:=0;
   P:=@Buf;
+  //writeln('TXMLRegistry.HexToBuf B: (p=nil)=',p=nil);
   NLen:= Length(Str) div 2;
+  //writeln('TXMLRegistry.HexToBuf C: NLen=',NLen,', SizeOf(TDateTime)=',SizeOf(TDateTime));
   If (NLen>Len) then
     begin
     Len:=NLen;
     Exit(-1);
     end;
-  For I:=0 to Len-1 do
+  For I:=0 to NLen-1 do
     begin
+    //write('TXMLRegistry.HexToBuf: i=',i);
     S:='$'+Copy(Str,(I*2)+1,2);
+    //write(', S=',S);
     Val(S,B,Code);
+    //writeln(', Code=',Code);
     If Code<>0 then
-      begin
-      Inc(Result);
-      B:=0;
+      begin    //This means invalid data in the registry, why continue and increment result? Why not Exit(-1)?
+      //Inc(Result);   //the whole function only worked because this was called as often as when Code=0, so by change
+      //B:=0;          //it causes AV's
+      Exit(-1);
       end;
+    Inc(Result);
     P[I]:=B;
     end;
+  //writeln('TXMLRegistry.HexToBuf End: Result=',Result);
 end;
 
-Function TXMLRegistry.DeleteValue(S : String) : Boolean;
+Function TXMLRegistry.DeleteValue(S : UnicodeString) : Boolean;
 
 Var
   N : TDomElement;
@@ -628,31 +648,31 @@
     end;
 end;
 
-Function TXMLRegistry.GetValueSize(Name : String) : Integer;
+Function TXMLRegistry.GetValueSize(Name : UnicodeString) : Integer;
 
 Var
   Info : TDataInfo;
 
 begin
-  If GetValueInfo(Name,Info) then
+  If GetValueInfo(Name,Info,True) then
     Result:=Info.DataSize
   else
     Result:=-1;
 end;
 
-Function TXMLRegistry.GetValueType(Name : String) : TDataType;
+Function TXMLRegistry.GetValueType(Name : UnicodeString) : TDataType;
 
 Var
   Info : TDataInfo;
 
 begin
-  If GetValueInfo(Name,Info) then
+  If GetValueInfo(Name,Info,True) then
     Result:=Info.DataType
   else
     Result:=dtUnknown;
 end;
 
-function TXmlRegistry.GetValueInfo(Name: String; out Info: TDataInfo; AsUnicode: Boolean): Boolean;
+function TXmlRegistry.GetValueInfo(Name: UnicodeString; out Info: TDataInfo; AsUnicode: Boolean): Boolean;
 
 Var
   N  : TDomElement;
@@ -671,7 +691,7 @@
         L:=Length(DN.NodeValue)*SizeOf(UnicodeChar)
       else
         begin
-        S := UTF8Encode(DN.NodeValue);
+        S := DN.NodeValue;
         L:=Length(S);
         end
       end
@@ -679,7 +699,7 @@
       L:=0;
     With Info do
       begin
-      DataType:=TDataType(StrToIntDef(N[SType],0));
+      DataType:=TDataType(StrToIntDef(String(N[SType]),0));
       Case DataType of
         dtUnknown : DataSize:=0;
         dtDword   : Datasize:=SizeOf(Cardinal);
@@ -724,10 +744,10 @@
               ValueLen:=L;
             DataNode:=TDomElement(Node).FirstChild;
             If (DataNode<>Nil) and (DataNode is TDomText) then
-              Case TDataType(StrToIntDef(TDomElement(Node)[SType],0)) of
+              Case TDataType(StrToIntDef(String(TDomElement(Node)[SType]),0)) of
                 dtUnknown : L:=0;
                 dtDWord   : L:=4;
-                DtString  : L:=Length(UTF8Encode(DataNode.NodeValue));
+                DtString  : L:=Length(String(DataNode.NodeValue));
                 dtBinary  : L:=Length(DataNode.NodeValue) div 2;
               end
             else
@@ -761,6 +781,28 @@
     end;
 end;
 
+function TXmlRegistry.EnumSubKeys: TUnicodeStringArray;
+
+Var
+  Node : TDOMNode;
+
+begin
+  Result:=nil;
+  If FCurrentElement<>Nil then
+    begin
+    Node:=FCurrentElement.FirstChild;
+    While Assigned(Node) do
+      begin
+      If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SKey) then
+        begin
+        SetLength(Result, Length(Result)+1);
+        Result[High(Result)]:=TDomElement(Node)[SName];
+        end;
+      Node:=Node.NextSibling;
+      end;
+    end;
+end;
+
 Function TXMLRegistry.EnumValues(List : TStrings) : Integer;
 
 Var
@@ -775,7 +817,8 @@
     While Assigned(Node) do
       begin
       If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SValue) then
-        List.Add(TDomElement(Node)[SName]);
+        If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SValue) then
+          List.Add(TDomElement(Node)[SName]);
       Node:=Node.NextSibling;
       end;
     Result:=List.Count;
@@ -782,13 +825,36 @@
     end;
 end;
 
-Function TXMLRegistry.KeyExists(KeyPath : String) : Boolean;
+Function TXMLRegistry.EnumValues: TUnicodeStringArray;
 
+Var
+  Node : TDOMNode;
+
 begin
+  Result:=nil;
+  If FCurrentElement<>Nil then
+    begin
+    Node:=FCurrentElement.FirstChild;
+    While Assigned(Node) do
+      begin
+      If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SValue) then
+        begin
+        SetLength(Result, Length(Result)+1);
+        Result[High(Result)]:=TDomElement(Node)[SName];
+        end;
+      Node:=Node.NextSibling;
+      end;
+    end;
+end;
+
+
+Function TXMLRegistry.KeyExists(KeyPath : UnicodeString) : Boolean;
+
+begin
   Result:=FindKey(KeyPath)<>Nil;
 end;
 
-Function TXMLRegistry.RenameValue(Const OldName,NewName : String) : Boolean;
+Function TXMLRegistry.RenameValue(Const OldName,NewName : UnicodeString) : Boolean;
 
 Var
   N : TDomElement;
@@ -804,10 +870,10 @@
     end;
 end;
 
-Function TXMLRegistry.FindKey (S : String) : TDomElement;
+Function TXMLRegistry.FindKey (S : UnicodeString) : TDomElement;
 
 Var
-  SubKey : String;
+  SubKey : UnicodeString;
   P : Integer;
   Node : TDomElement;
 
@@ -840,7 +906,7 @@
   Until (Result=Nil) or (Length(S)=0);
 end;
 
-Function  TXmlRegistry.ValueExists(ValueName : String) : Boolean;
+Function  TXmlRegistry.ValueExists(ValueName : UnicodeString) : Boolean;
 
 begin
   Result:=FindValueKey(ValueName)<>Nil;
Index: packages/fcl-registry/src/xregreg.inc
===================================================================
--- packages/fcl-registry/src/xregreg.inc	(revision 41667)
+++ packages/fcl-registry/src/xregreg.inc	(working copy)
@@ -116,7 +116,11 @@
 procedure TRegistry.SysRegCreate;
 var s : string;
 begin
+  FStringSizeIncludesNull:=False;
   s:=includetrailingpathdelimiter(GetAppConfigDir(GlobalXMLFile));
+  {$ifdef XMLRegfile_in_CurDir}
+  s:='.' + PathDelim;
+  {$endif}
   ForceDirectories(s);
   FSysData:=TXMLRegistryInstance.GetXMLRegistry(s+XFileName);
   TXmlRegistry(FSysData).AutoFlush:=False;
@@ -130,24 +134,24 @@
   TXMLRegistryInstance.FreeXMLRegistry(TXMLRegistry(FSysData));
 end;
 
-function TRegistry.SysCreateKey(const Key: String): Boolean;
+function TRegistry.SysCreateKey(Key: UnicodeString): Boolean;
 
 begin
   Result:=TXmlRegistry(FSysData).CreateKey(Key);
 end;
 
-function TRegistry.DeleteKey(const Key: string): Boolean;
+function TRegistry.DeleteKey(const Key: UnicodeString): Boolean;
 
 begin
   Result:=TXMLRegistry(FSysData).DeleteKey(Key);
 end;
 
-function TRegistry.DeleteValue(const Name: string): Boolean;
+function TRegistry.DeleteValue(const Name: UnicodeString): Boolean;
 begin
   Result:=TXmlRegistry(FSysData).DeleteValue(Name);
 end;
 
-function TRegistry.SysGetData(const Name: String; Buffer: Pointer;
+function TRegistry.SysGetData(const Name: UnicodeString; Buffer: Pointer;
           BufSize: Integer; Out RegData: TRegDataType): Integer;
 
 Var
@@ -160,7 +164,7 @@
     Result:=-1;
 end;
 
-function TRegistry.GetDataInfo(const ValueName: string; out Value: TRegDataInfo): Boolean;
+function TRegistry.GetDataInfo(const ValueName: UnicodeString; out Value: TRegDataInfo): Boolean;
 
 Var
   Info : TDataInfo;
@@ -181,7 +185,7 @@
       end;
 end;
 
-function TRegistry.GetKey(const Key: string): HKEY;
+function TRegistry.GetKey(Key: UnicodeString): HKEY;
 begin
   Result := 0;
 end;
@@ -205,17 +209,17 @@
       end;
 end;
 
-function TRegistry.KeyExists(const Key: string): Boolean;
+function TRegistry.KeyExists(const Key: UnicodeString): Boolean;
 begin
   Result:=TXmlRegistry(FSysData).KeyExists(Key);
 end;
 
-function TRegistry.LoadKey(const Key, FileName: string): Boolean;
+function TRegistry.LoadKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.OpenKey(const Key: string; CanCreate: Boolean): Boolean;
+function TRegistry.OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
 
 begin
   Result:=TXmlRegistry(FSysData).SetKey(Key,CanCreate);
@@ -222,59 +226,59 @@
   FCurrentKey:=1;
 end;
 
-function TRegistry.OpenKeyReadOnly(const Key: string): Boolean;
+function TRegistry.OpenKeyReadOnly(const Key: UnicodeString): Boolean;
 
 begin
   Result:=TXmlRegistry(FSysData).SetKey(Key,False);
 end;
 
-function TRegistry.RegistryConnect(const UNCName: string): Boolean;
+function TRegistry.RegistryConnect(const UNCName: UnicodeString): Boolean;
 begin
   Result := True;
 end;
 
-function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
+function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.RestoreKey(const Key, FileName: string): Boolean;
+function TRegistry.RestoreKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.SaveKey(const Key, FileName: string): Boolean;
+function TRegistry.SaveKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.UnLoadKey(const Key: string): Boolean;
+function TRegistry.UnLoadKey(const Key: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.ValueExists(const Name: string): Boolean;
+function TRegistry.ValueExists(const Name: UnicodeString): Boolean;
 begin
   Result := TXmlRegistry(FSysData).ValueExists(Name);
 end;
 
-procedure TRegistry.ChangeKey(Value: HKey; const Path: string);
+procedure TRegistry.ChangeKey(Value: HKey; const Path: UnicodeString);
 begin
 
 end;
 
-procedure TRegistry.GetKeyNames(Strings: TStrings);
+function TRegistry.GetKeyNames: TUnicodeStringArray;
 begin
-  TXmlRegistry(FSysData).EnumSubKeys(Strings);
+  Result:=TXmlRegistry(FSysData).EnumSubKeys;
 end;
 
-procedure TRegistry.GetValueNames(Strings: TStrings);
+function TRegistry.GetValueNames: TUnicodeStringArray;
 begin
-  TXmlRegistry(FSysData).EnumValues(Strings);
+  Result := TXmlRegistry(FSysData).EnumValues;
 end;
 
 
-function TRegistry.SysPutData(const Name: string; Buffer: Pointer;
+function TRegistry.SysPutData(const Name: UnicodeString; Buffer: Pointer;
   BufSize: Integer; RegData: TRegDataType): Boolean;
 
 Var
@@ -281,15 +285,18 @@
   DataType : TDataType;
 
 begin
+  //writeln('TRegistry.SysPutData: Name=',Name,', RegData=',RegData,', BufSize=',BufSize);
   DataType:=RegDataTypeToXmlDataType(RegData);
+
   Result:=TXMLRegistry(FSysData).SetValueDataUnicode(Name,DataType,Buffer^,BufSize);
 end;
 
-procedure TRegistry.RenameValue(const OldName, NewName: string);
+procedure TRegistry.RenameValue(const OldName, NewName: UnicodeString);
 begin
   TXMLRegistry(FSysData).RenameValue(OldName,NewName);
 end;
 
+
 procedure TRegistry.SetCurrentKey(Value: HKEY);
 begin
   fCurrentKey := Value;
@@ -298,7 +305,7 @@
 procedure TRegistry.SetRootKey(Value: HKEY);
 
 Var
-  S: String;
+  S: UnicodeString;
 
 begin
   If (Value=HKEY_CLASSES_ROOT) then
@@ -347,3 +354,5 @@
     TXMLRegistry(FSysData).SetRootKey(TXMLRegistry(FSysData).RootKey);
   end;
 end;
+
+

Bart Broersma

2019-03-17 12:46

reporter   ~0114896

Last edited: 2019-03-17 13:02

View 3 revisions

Attached registry.unicode.part5.diff for review.

All public and protected methods now default to UnicodeString.
Overloaded versions with String parameters use implicit conversion to/from UnicodeString.

Introduced new methods that read/write TUnicodeStringArray parameters.
All methods using TStrings now uses the methods using TUnicodeStringArray.
(In XMLReg unit I did not remove the existing implementation using TStrings, because AFAIK this unit can be used stand alone, and it would therefore not be backwards compatible.)

ReadStringList/WriteStringList have optional parameter to control if the Strings are encodes as UTF8.
GetKeyNames and GetValueNames with TStrings parameter encode the resulting strings as UTF8.
(I did not include an optional paramter as for Read/WriteStringList, because then the signature is no longer Delphi compatible.
If so desired this paramter can be added. It's a trivial change.)

As discussed: in XMLReg WriteStringList now writes UnicodeStrings to the reg.xml file, which the previous implementation (trunk only) did not. It was judged to be acceptable.

TXMLRegistry internally now uses UnicodeString everywhere (except for the Filename property and HexToBuf/BufToHex, where it seemed to make no sense to convert this to UnicodeString).
There are still warnigs about implicit UnicodeString to String conversions, but they are in codepaths that are not used by TRegistry.

I changed some existing $ifdefs to make it easier to use and test the XML implementation under Windows.
(Simplye defining XMLREG would not compile under Windows)

I added some conditional compilation to XMLReg unit for the same reason.

When reading Reg_Multi_SZ data, trailing zero's are deleted regardless of value of StringSizeIncludesNull, because (by Windows definition) this data cannot contain empty strings.

In the XMLReg implementations I did some Explicit UnicodeString to String conversions in places where the string in question can only contain '0'..'9','A'..'Z'.
It suppresses a warning and it is safe by definition in those places.

I had to fix TXmlRegistry.HexToBuf.
The fact that it worked before was by pure luck.

Bart Broersma

2019-03-19 19:15

reporter  

registry.unicode.part6.diff (68,376 bytes)
Index: packages/fcl-registry/src/regdef.inc
===================================================================
--- packages/fcl-registry/src/regdef.inc	(revision 41667)
+++ packages/fcl-registry/src/regdef.inc	(working copy)
@@ -2,7 +2,7 @@
   HKEY = THandle;
   PHKEY = ^HKEY;
   
-{$ifdef windows}
+{$if defined(windows) and not defined(XMLREG)}
 
 { Direct mapping to constants in Windows unit }
 
Index: packages/fcl-registry/src/registry.pp
===================================================================
--- packages/fcl-registry/src/registry.pp	(revision 41667)
+++ packages/fcl-registry/src/registry.pp	(working copy)
@@ -39,6 +39,8 @@
     DataSize: Integer;
   end;
 
+  TUnicodeStringArray = Array of UnicodeString;
+
 { ---------------------------------------------------------------------
     TRegistry
   ---------------------------------------------------------------------}
@@ -54,22 +56,31 @@
     fCurrentKey: HKEY;
     fRootKey: HKEY;
     fLazyWrite: Boolean;
-    fCurrentPath: string;
+    fCurrentPath: UnicodeString;
     function GetLastErrorMsg: string;
+    function RegMultiSzDataToUnicodeStringArray(U: UnicodeString): TUnicodeStringArray;
+    function ListToArray(List: TStrings; IsUtf8: Boolean): TUnicodeStringArray;
+    procedure ArrayToList(const Arr: TUnicodeStringArray; List: TStrings; ForceUtf8: Boolean);
     procedure SetRootKey(Value: HKEY);
     Procedure SysRegCreate;
     Procedure SysRegFree;
-    Function  SysGetData(const Name: String; Buffer: Pointer; BufSize: Integer; Out RegData: TRegDataType): Integer;
-    Function  SysPutData(const Name: string; Buffer: Pointer; BufSize: Integer; RegData: TRegDataType) : Boolean;
-    Function  SysCreateKey(const Key: String): Boolean;
+    Function  SysGetData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; Out RegData: TRegDataType): Integer;
+    Function  SysPutData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; RegData: TRegDataType) : Boolean;
+    Function  SysCreateKey(Key: UnicodeString): Boolean;
   protected
     function GetBaseKey(Relative: Boolean): HKey;
-    function GetData(const Name: string; Buffer: Pointer;
+    function GetData(const Name: UnicodeString; Buffer: Pointer;
                   BufSize: Integer; Out RegData: TRegDataType): Integer;
-    function GetKey(const Key: string): HKEY;
-    procedure ChangeKey(Value: HKey; const Path: string);
-    procedure PutData(const Name: string; Buffer: Pointer;
+    function GetData(const Name: String; Buffer: Pointer;
+                  BufSize: Integer; Out RegData: TRegDataType): Integer;
+    function GetKey(Key: UnicodeString): HKEY;
+    function GetKey(Key: String): HKEY;
+    procedure ChangeKey(Value: HKey; const Path: UnicodeString);
+    procedure ChangeKey(Value: HKey; const Path: String);
+    procedure PutData(const Name: UnicodeString; Buffer: Pointer;
                   BufSize: Integer; RegData: TRegDataType);
+    procedure PutData(const Name: String; Buffer: Pointer;
+                  BufSize: Integer; RegData: TRegDataType);
     procedure SetCurrentKey(Value: HKEY);
   public
     constructor Create; overload;
@@ -76,58 +87,105 @@
     constructor Create(aaccess:longword); overload;
     destructor Destroy; override;
 
-    function CreateKey(const Key: string): Boolean;
-    function DeleteKey(const Key: string): Boolean;
-    function DeleteValue(const Name: string): Boolean;
-    function GetDataInfo(const ValueName: string; Out Value: TRegDataInfo): Boolean;
-    function GetDataSize(const ValueName: string): Integer;
-    function GetDataType(const ValueName: string): TRegDataType;
+    function CreateKey(const Key: UnicodeString): Boolean;
+    function CreateKey(const Key: String): Boolean;
+    function DeleteKey(const Key: UnicodeString): Boolean;
+    function DeleteKey(const Key: String): Boolean;
+    function DeleteValue(const Name: UnicodeString): Boolean;
+    function DeleteValue(const Name: String): Boolean;
+    function GetDataInfo(const ValueName: UnicodeString; Out Value: TRegDataInfo): Boolean;
+    function GetDataInfo(const ValueName: String; Out Value: TRegDataInfo): Boolean;
+    function GetDataSize(const ValueName: UnicodeString): Integer;
+    function GetDataSize(const ValueName: String): Integer;
+    function GetDataType(const ValueName: UnicodeString): TRegDataType;
+    function GetDataType(const ValueName: String): TRegDataType;
     function GetKeyInfo(Out Value: TRegKeyInfo): Boolean;
     function HasSubKeys: Boolean;
-    function KeyExists(const Key: string): Boolean;
-    function LoadKey(const Key, FileName: string): Boolean;
-    function OpenKey(const Key: string; CanCreate: Boolean): Boolean;
-    function OpenKeyReadOnly(const Key: string): Boolean;
-    function ReadCurrency(const Name: string): Currency;
-    function ReadBinaryData(const Name: string; var Buffer; BufSize: Integer): Integer;
-    function ReadBool(const Name: string): Boolean;
-    function ReadDate(const Name: string): TDateTime;
-    function ReadDateTime(const Name: string): TDateTime;
-    function ReadFloat(const Name: string): Double;
-    function ReadInteger(const Name: string): Integer;
-    function ReadInt64(const Name: string): Int64;
-    function ReadString(const Name: string): string;
-    procedure ReadStringList(const Name: string; AList: TStrings);
-    function ReadTime(const Name: string): TDateTime;
-    function RegistryConnect(const UNCName: string): Boolean;
-    function ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
-    function RestoreKey(const Key, FileName: string): Boolean;
-    function SaveKey(const Key, FileName: string): Boolean;
-    function UnLoadKey(const Key: string): Boolean;
-    function ValueExists(const Name: string): Boolean;
+    function KeyExists(const Key: UnicodeString): Boolean;
+    function KeyExists(const Key: String): Boolean;
+    function LoadKey(const Key, FileName: UnicodeString): Boolean;
+    function LoadKey(const Key, FileName: String): Boolean;
+    function OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
+    function OpenKey(const Key: String; CanCreate: Boolean): Boolean;
+    function OpenKeyReadOnly(const Key: UnicodeString): Boolean;
+    function OpenKeyReadOnly(const Key: String): Boolean;
+    function ReadCurrency(const Name: UnicodeString): Currency;
+    function ReadCurrency(const Name: String): Currency;
+    function ReadBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer): Integer;
+    function ReadBinaryData(const Name: String; var Buffer; BufSize: Integer): Integer;
+    function ReadBool(const Name: UnicodeString): Boolean;
+    function ReadBool(const Name: String): Boolean;
+    function ReadDate(const Name: UnicodeString): TDateTime;
+    function ReadDate(const Name: String): TDateTime;
+    function ReadDateTime(const Name: UnicodeString): TDateTime;
+    function ReadDateTime(const Name: String): TDateTime;
+    function ReadFloat(const Name: UnicodeString): Double;
+    function ReadFloat(const Name: String): Double;
+    function ReadInteger(const Name: UnicodeString): Integer;
+    function ReadInteger(const Name: String): Integer;
+    function ReadInt64(const Name: UnicodeString): Int64;
+    function ReadInt64(const Name: String): Int64;
+    function ReadString(const Name: UnicodeString): UnicodeString;
+    function ReadString(const Name: String): string;
+    procedure ReadStringList(const Name: UnicodeString; AList: TStrings; ForceUtf8: Boolean=False);
+    procedure ReadStringList(const Name: String; AList: TStrings);
+    function ReadStringArray(const Name: UnicodeString): TUnicodeStringArray;
+    function ReadStringArray(const Name: String): TStringArray;
+    function ReadTime(const Name: UnicodeString): TDateTime;
+    function ReadTime(const Name: String): TDateTime;
+    function RegistryConnect(const UNCName: UnicodeString): Boolean;
+    function RegistryConnect(const UNCName: String): Boolean;
+    function ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
+    function ReplaceKey(const Key, FileName, BackUpFileName: String): Boolean;
+    function RestoreKey(const Key, FileName: UnicodeString): Boolean;
+    function RestoreKey(const Key, FileName: String): Boolean;
+    function SaveKey(const Key, FileName: UnicodeString): Boolean;
+    function SaveKey(const Key, FileName: String): Boolean;
+    function UnLoadKey(const Key: UnicodeString): Boolean;
+    function UnLoadKey(const Key: String): Boolean;
+    function ValueExists(const Name: UnicodeString): Boolean;
+    function ValueExists(const Name: String): Boolean;
 
     procedure CloseKey;
     procedure CloseKey(key:HKEY);
     procedure GetKeyNames(Strings: TStrings);
+    function GetKeyNames: TUnicodeStringArray;
     procedure GetValueNames(Strings: TStrings);
-    procedure MoveKey(const OldName, NewName: string; Delete: Boolean);
-    procedure RenameValue(const OldName, NewName: string);
-    procedure WriteCurrency(const Name: string; Value: Currency);
-    procedure WriteBinaryData(const Name: string; var Buffer; BufSize: Integer);
-    procedure WriteBool(const Name: string; Value: Boolean);
-    procedure WriteDate(const Name: string; Value: TDateTime);
-    procedure WriteDateTime(const Name: string; Value: TDateTime);
-    procedure WriteFloat(const Name: string; Value: Double);
-    procedure WriteInteger(const Name: string; Value: Integer);
-    procedure WriteInt64(const Name: string; Value: Int64);
-    procedure WriteString(const Name, Value: string);
-    procedure WriteExpandString(const Name, Value: string);
-    procedure WriteStringList(const Name: string; List: TStrings);
-    procedure WriteTime(const Name: string; Value: TDateTime);
+    //ToDo
+    function GetValueNames: TUnicodeStringArray;
+    procedure MoveKey(const OldName, NewName: UnicodeString; Delete: Boolean);
+    procedure MoveKey(const OldName, NewName: String; Delete: Boolean);
+    procedure RenameValue(const OldName, NewName: UnicodeString);
+    procedure RenameValue(const OldName, NewName: String);
+    procedure WriteCurrency(const Name: UnicodeString; Value: Currency);
+    procedure WriteCurrency(const Name: String; Value: Currency);
+    procedure WriteBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer);
+    procedure WriteBinaryData(const Name: String; var Buffer; BufSize: Integer);
+    procedure WriteBool(const Name: UnicodeString; Value: Boolean);
+    procedure WriteBool(const Name: String; Value: Boolean);
+    procedure WriteDate(const Name: UnicodeString; Value: TDateTime);
+    procedure WriteDate(const Name: String; Value: TDateTime);
+    procedure WriteDateTime(const Name: UnicodeString; Value: TDateTime);
+    procedure WriteDateTime(const Name: String; Value: TDateTime);
+    procedure WriteFloat(const Name: UnicodeString; Value: Double);
+    procedure WriteFloat(const Name: String; Value: Double);
+    procedure WriteInteger(const Name: UnicodeString; Value: Integer);
+    procedure WriteInteger(const Name: String; Value: Integer);
+    procedure WriteInt64(const Name: UnicodeString; Value: Int64);
+    procedure WriteInt64(const Name: String; Value: Int64);
+    procedure WriteString(const Name, Value: UnicodeString);
+    procedure WriteString(const Name, Value: String);
+    procedure WriteExpandString(const Name, Value: UnicodeString);
+    procedure WriteExpandString(const Name, Value: String);
+    procedure WriteStringList(const Name: UnicodeString; List: TStrings; IsUtf8: Boolean=False);
+    procedure WriteStringArray(const Name: UnicodeString; const Arr: TUnicodeStringArray);
+    procedure WriteStringArray(const Name: String; const Arr: TStringArray);
+    procedure WriteTime(const Name: UnicodeString; Value: TDateTime);
+    procedure WriteTime(const Name: String; Value: TDateTime);
 
     property Access: LongWord read fAccess write fAccess;
     property CurrentKey: HKEY read fCurrentKey;
-    property CurrentPath: string read fCurrentPath;
+    property CurrentPath: UnicodeString read fCurrentPath;
     property LazyWrite: Boolean read fLazyWrite write fLazyWrite;
     property RootKey: HKEY read fRootKey write SetRootKey;
     Property StringSizeIncludesNull : Boolean read FStringSizeIncludesNull;
@@ -235,6 +293,16 @@
     Generic, implementation-independent code.
   ---------------------------------------------------------------------}
 
+{$ifdef DebugRegistry}
+function DbgS(const S: UnicodeString): String;
+var
+  C: WideChar;
+begin
+  Result := '';
+  for C in S do Result := Result + IntToHex(Word(C),4) + #32;
+  Result := TrimRight(Result);
+end;
+{$endif}
 
 constructor TRegistry.Create;
 
@@ -261,7 +329,7 @@
   inherited Destroy;
 end;
 
-function TRegistry.CreateKey(const Key: string): Boolean;
+function TRegistry.CreateKey(const Key: UnicodeString): Boolean;
 
 begin
   Result:=SysCreateKey(Key);
@@ -269,6 +337,27 @@
     Raise ERegistryException.CreateFmt(SRegCreateFailed, [Key]);
 end;
 
+function TRegistry.CreateKey(const Key: String): Boolean;
+begin
+  Result:=CreateKey(UnicodeString(Key));
+end;
+
+function TRegistry.DeleteKey(const Key: String): Boolean;
+begin
+  Result:=DeleteKey(UnicodeString(Key));
+end;
+
+function TRegistry.DeleteValue(const Name: String): Boolean;
+begin
+  Result:=DeleteValue(UnicodeString(Name));
+end;
+
+function TRegistry.GetDataInfo(const ValueName: String; out Value: TRegDataInfo
+  ): Boolean;
+begin
+  Result:=GetDataInfo(UnicodeString(ValueName), Value);
+end;
+
 function TRegistry.GetBaseKey(Relative: Boolean): HKey;
 begin
   If Relative and (CurrentKey<>0) Then
@@ -277,7 +366,7 @@
     Result := RootKey;
 end;
 
-function TRegistry.GetData(const Name: string; Buffer: Pointer; BufSize: Integer; out RegData: TRegDataType): Integer;
+function TRegistry.GetData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; out RegData: TRegDataType): Integer;
 begin
   Result:=SysGetData(Name,Buffer,BufSize,RegData);
   If (Result=-1) then
@@ -284,7 +373,24 @@
     Raise ERegistryException.CreateFmt(SRegGetDataFailed, [Name]);
 end;
 
-procedure TRegistry.PutData(const Name: string; Buffer: Pointer;
+function TRegistry.GetData(const Name: String; Buffer: Pointer;
+  BufSize: Integer; out RegData: TRegDataType): Integer;
+begin
+  Result:=GetData(UnicodeString(Name), Buffer, BufSize, RegData);
+end;
+
+function TRegistry.GetKey(Key: String): HKEY;
+begin
+  Result:=GetKey(UnicodeString(Key));
+end;
+
+procedure TRegistry.ChangeKey(Value: HKey; const Path: String);
+begin
+  ChangeKey(Value, UnicodeString(Path));
+end;
+
+
+procedure TRegistry.PutData(const Name: UnicodeString; Buffer: Pointer;
   BufSize: Integer; RegData: TRegDataType);
 
 begin
@@ -292,9 +398,15 @@
     Raise ERegistryException.CreateFmt(SRegSetDataFailed, [Name]);
 end;
 
+procedure TRegistry.PutData(const Name: String; Buffer: Pointer;
+  BufSize: Integer; RegData: TRegDataType);
+begin
+  PutData(UnicodeString(Name), Buffer, BufSize, RegData);
+end;
 
-function TRegistry.GetDataSize(const ValueName: string): Integer;
 
+function TRegistry.GetDataSize(const ValueName: UnicodeString): Integer;
+
 Var
   Info: TRegDataInfo;
 
@@ -305,8 +417,13 @@
     Result := -1;
 end;
 
-function TRegistry.GetDataType(const ValueName: string): TRegDataType;
+function TRegistry.GetDataSize(const ValueName: String): Integer;
+begin
+  Result:=GetDataSize(UnicodeString(ValueName));
+end;
 
+function TRegistry.GetDataType(const ValueName: UnicodeString): TRegDataType;
+
 Var
   Info: TRegDataInfo;
 
@@ -315,6 +432,32 @@
   Result:=Info.RegData;
 end;
 
+function TRegistry.GetDataType(const ValueName: String): TRegDataType;
+begin
+  Result:=GetDataType(UnicodeString(ValueName));
+end;
+
+
+function TRegistry.KeyExists(const Key: String): Boolean;
+begin
+  Result:=KeyExists(UnicodeString(Key));
+end;
+
+function TRegistry.LoadKey(const Key, FileName: String): Boolean;
+begin
+  Result:=LoadKey(UnicodeString(Key), UnicodeString(FileName));
+end;
+
+function TRegistry.OpenKey(const Key: String; CanCreate: Boolean): Boolean;
+begin
+  Result:=OpenKey(UnicodeString(Key), CanCreate);
+end;
+
+function TRegistry.OpenKeyReadOnly(const Key: String): Boolean;
+begin
+  Result:=OpenKeyReadOnly(UnicodeString(Key));
+end;
+
 function TRegistry.HasSubKeys: Boolean;
 
 Var
@@ -326,7 +469,7 @@
     Result:=(Info.NumSubKeys>0);
 end;
 
-function TRegistry.ReadBinaryData(const Name: string; var Buffer; BufSize: Integer): Integer;
+function TRegistry.ReadBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer): Integer;
 
 Var
   RegDataType: TRegDataType;
@@ -337,8 +480,14 @@
     Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
 end;
 
-function TRegistry.ReadInteger(const Name: string): Integer;
+function TRegistry.ReadBinaryData(const Name: String; var Buffer;
+  BufSize: Integer): Integer;
+begin
+  Result:=ReadBinaryData(UnicodeString(Name), Buffer, BufSize);
+end;
 
+function TRegistry.ReadInteger(const Name: UnicodeString): Integer;
+
 Var
   RegDataType: TRegDataType;
 
@@ -348,8 +497,13 @@
     Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
 end;
 
-function TRegistry.ReadInt64(const Name: string): Int64;
+function TRegistry.ReadInteger(const Name: String): Integer;
+begin
+  Result:=ReadInteger(UnicodeString(Name));
+end;
 
+function TRegistry.ReadInt64(const Name: UnicodeString): Int64;
+
 Var
   RegDataType: TRegDataType;
 
@@ -359,21 +513,36 @@
     Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
 end;
 
-function TRegistry.ReadBool(const Name: string): Boolean;
+function TRegistry.ReadInt64(const Name: String): Int64;
+begin
+  Result:=ReadInt64(UnicodeString(Name));
+end;
 
+function TRegistry.ReadBool(const Name: UnicodeString): Boolean;
+
 begin
   Result:=ReadInteger(Name)<>0;
 end;
 
-function TRegistry.ReadCurrency(const Name: string): Currency;
+function TRegistry.ReadBool(const Name: String): Boolean;
+begin
+  Result:=ReadBool(UnicodeString(Name));
+end;
 
+function TRegistry.ReadCurrency(const Name: UnicodeString): Currency;
+
 begin
   Result:=Default(Currency);
   ReadBinaryData(Name, Result, SizeOf(Currency));
 end;
 
-function TRegistry.ReadDate(const Name: string): TDateTime;
+function TRegistry.ReadCurrency(const Name: String): Currency;
+begin
+  Result:=ReadCurrency(UnicodeString(Name));
+end;
 
+function TRegistry.ReadDate(const Name: UnicodeString): TDateTime;
+
 begin
   Result:=Default(TDateTime);
   ReadBinaryData(Name, Result, SizeOf(TDateTime));
@@ -380,22 +549,37 @@
   Result:=Trunc(Result);
 end;
 
-function TRegistry.ReadDateTime(const Name: string): TDateTime;
+function TRegistry.ReadDate(const Name: String): TDateTime;
+begin
+  Result:=ReadDate(UnicodeString(Name));
+end;
 
+function TRegistry.ReadDateTime(const Name: UnicodeString): TDateTime;
+
 begin
   Result:=Default(TDateTime);
   ReadBinaryData(Name, Result, SizeOf(TDateTime));
 end;
 
-function TRegistry.ReadFloat(const Name: string): Double;
+function TRegistry.ReadDateTime(const Name: String): TDateTime;
+begin
+  Result:=ReadDateTime(UnicodeString(Name));
+end;
 
+function TRegistry.ReadFloat(const Name: UnicodeString): Double;
+
 begin
   Result:=Default(Double);
   ReadBinaryData(Name,Result,SizeOf(Double));
 end;
 
-function TRegistry.ReadString(const Name: string): string;
+function TRegistry.ReadFloat(const Name: String): Double;
+begin
+  Result:=ReadFloat(UnicodeString(Name));
+end;
 
+function TRegistry.ReadString(const Name: UnicodeString): UnicodeString;
+
 Var
   Info : TRegDataInfo;
   ReadDataSize: Integer;
@@ -421,47 +605,139 @@
       if StringSizeIncludesNull and
          (u[Length(u)] = WideChar(0)) then
         SetLength(u,Length(u)-1);
-      Result:=UTF8Encode(u);
+      Result:=u;
     end;
   end;
 end;
 
-procedure TRegistry.ReadStringList(const Name: string; AList: TStrings);
+function TRegistry.ReadString(const Name: String): string;
+begin
+  Result:=ReadString(UnicodeString(Name));
+end;
 
+
+procedure TRegistry.ReadStringList(const Name: UnicodeString; AList: TStrings; ForceUtf8: Boolean=False);
+
 Var
+  UArr: TUnicodeStringArray;
+
+begin
+  UArr := ReadStringArray(Name);
+  ArrayToList(UArr, AList, ForceUtf8);
+end;
+
+procedure TRegistry.ReadStringList(const Name: String; AList: TStrings);
+begin
+  ReadStringList(UnicodeString(Name), AList);
+end;
+
+function TRegistry.RegMultiSzDataToUnicodeStringArray(U: UnicodeString): TUnicodeStringArray;
+var
+  Len, i, p: Integer;
+  Sub: UnicodeString;
+begin
+  Result := nil;
+  if (U = '') then Exit;
+  Len := 1;
+  for i := 1 to Length(U) do if (U[i] = #0) then Inc(Len);
+  SetLength(Result, Len);
+  i := 0;
+
+  while (U <> '') and (i < Length(Result)) do
+  begin
+    p := Pos(#0, U);
+    if (p = 0) then p := Length(U) + 1;
+    Sub := Copy(U, 1, p - 1);
+    Result[i] := Sub;
+    System.Delete(U, 1, p);
+    Inc(i);
+  end;
+end;
+
+function TRegistry.ListToArray(List: TStrings; IsUtf8: Boolean): TUnicodeStringArray;
+var
+  i, curr, Len: Integer;
+  u: UnicodeString;
+begin
+  Result := nil;
+  Len := List.Count;
+  SetLength(Result, Len);
+  //REG_MULTI_SZ data cannot contain empty strings
+  curr := 0;
+  for i := 0 to List.Count - 1 do
+  begin
+    if IsUtf8 then
+      u := Utf8Decode(List[i])
+    else
+      u := List[i];
+    if (u>'') then
+    begin
+      Result[curr] := u;
+      inc(curr);
+    end
+    else
+      Dec(Len);
+  end;
+  if (Len <> List.Count) then SetLength(Result, Len);
+end;
+
+procedure TRegistry.ArrayToList(const Arr: TUnicodeStringArray; List: TStrings; ForceUtf8: Boolean);
+var
+  i: Integer;
+begin
+  List.Clear;
+  for i := Low(Arr) to High(Arr) do
+  begin
+    if ForceUtf8 then
+      List.Add(Utf8Encode(Arr[i]))
+    else
+      List.Add(String(Arr[i]));
+  end;
+end;
+
+function TRegistry.ReadStringArray(const Name: UnicodeString): TUnicodeStringArray;
+Var
   Info : TRegDataInfo;
   ReadDataSize: Integer;
-  Data: string;
+  Data: UnicodeString;
 
 begin
-  AList.Clear;
+  Result := nil;
   GetDataInfo(Name,Info);
+  //writeln('TRegistry.ReadStringArray: datasize=',info.datasize);
   if info.datasize>0 then
     begin
      If Not (Info.RegData in [rdMultiString]) then
        Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
      SetLength(Data,Info.DataSize);
-     ReadDataSize := GetData(Name,PChar(Data),Info.DataSize,Info.RegData);
+     ReadDataSize := GetData(Name,PWideChar(Data),Info.DataSize,Info.RegData) div SizeOf(WideChar);
+     //writeln('TRegistry.ReadStringArray: ReadDataSize=',ReadDataSize);
      if ReadDataSize > 0 then
      begin
-       // If the data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type,
-       // the size includes any terminating null character or characters
-       // unless the data was stored without them! (RegQueryValueEx @ MSDN)
-       if StringSizeIncludesNull then begin
-         if Data[ReadDataSize] = #0 then
-           Dec(ReadDataSize);
-         if Data[ReadDataSize] = #0 then
-           Dec(ReadDataSize);
-       end;
+       // Windows returns the data with or without trailing zero's, so just strip all trailing null characters
+        while (Data[ReadDataSize] = #0) do Dec(ReadDataSize);
        SetLength(Data, ReadDataSize);
-       Data := StringReplace(Data, #0, LineEnding, [rfReplaceAll]);
-       AList.Text := Data;
+       //writeln('Data=',dbgs(data));
+       //Data := UnicodeStringReplace(Data, #0, AList.LineBreak, [rfReplaceAll]);
+       //AList.Text := Data;
+       Result := RegMultiSzDataToUnicodeStringArray(Data);
      end
    end
 end;
 
-function TRegistry.ReadTime(const Name: string): TDateTime;
+function TRegistry.ReadStringArray(const Name: String): TStringArray;
+var
+  UArr: TUnicodeStringArray;
+  i: Integer;
+begin
+  Result := nil;
+  UArr := ReadStringArray(UnicodeString(Name));
+  SetLength(Result, Length(UArr));
+  for i := Low(UArr) to High(UArr) do Result[i] := UArr[i];
+end;
 
+function TRegistry.ReadTime(const Name: UnicodeString): TDateTime;
+
 begin
   Result:=Default(TDateTime);
   ReadBinaryData(Name, Result, SizeOf(TDateTime));
@@ -468,85 +744,230 @@
   Result:=Frac(Result);
 end;
 
-procedure TRegistry.WriteBinaryData(const Name: string; var Buffer; BufSize: Integer);
+function TRegistry.ReadTime(const Name: String): TDateTime;
 begin
+  Result:=ReadTime(UnicodeString(Name));
+end;
+
+function TRegistry.RegistryConnect(const UNCName: String): Boolean;
+begin
+  Result:=RegistryConnect(UnicodeString(UNCName));
+end;
+
+function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: String): Boolean;
+begin
+  Result:=ReplaceKey(UnicodeString(Key), UnicodeString(FileName), UnicodeString(BackUpFileName))
+end;
+
+function TRegistry.RestoreKey(const Key, FileName: String): Boolean;
+begin
+  Result:=RestoreKey(UnicodeString(Key), UnicodeString(FileName));
+end;
+
+function TRegistry.SaveKey(const Key, FileName: String): Boolean;
+begin
+  Result:=SaveKey(UnicodeString(Key), UnicodeString(FileName));
+end;
+
+function TRegistry.UnLoadKey(const Key: String): Boolean;
+begin
+  Result:=UnloadKey(UnicodeString(Key));
+end;
+
+function TRegistry.ValueExists(const Name: String): Boolean;
+begin
+  Result:=ValueExists(UnicodeString(Name));
+end;
+
+procedure TRegistry.WriteBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer);
+begin
   PutData(Name, @Buffer, BufSize, rdBinary);
 end;
 
-procedure TRegistry.WriteBool(const Name: string; Value: Boolean);
+procedure TRegistry.WriteBinaryData(const Name: String; var Buffer;
+  BufSize: Integer);
+begin
+  WriteBinaryData(UnicodeString(Name), Buffer, BufSize);
+end;
 
+procedure TRegistry.WriteBool(const Name: UnicodeString; Value: Boolean);
+
 begin
   WriteInteger(Name,Ord(Value));
 end;
 
-procedure TRegistry.WriteCurrency(const Name: string; Value: Currency);
+procedure TRegistry.WriteBool(const Name: String; Value: Boolean);
 begin
+  WriteBool(UnicodeString(Name), Value);
+end;
+
+procedure TRegistry.WriteCurrency(const Name: UnicodeString; Value: Currency);
+begin
   WriteBinaryData(Name, Value, SizeOf(Currency));
 end;
 
-procedure TRegistry.WriteDate(const Name: string; Value: TDateTime);
+procedure TRegistry.WriteCurrency(const Name: String; Value: Currency);
 begin
+  WriteCurrency(UnicodeString(Name), Value);
+end;
+
+procedure TRegistry.WriteDate(const Name: UnicodeString; Value: TDateTime);
+begin
   WriteBinarydata(Name, Value, SizeOf(TDateTime));
 end;
 
-procedure TRegistry.WriteTime(const Name: string; Value: TDateTime);
+procedure TRegistry.WriteDate(const Name: String; Value: TDateTime);
 begin
+  WriteDate(UnicodeString(Name), Value);
+end;
+
+procedure TRegistry.WriteTime(const Name: UnicodeString; Value: TDateTime);
+begin
   WriteBinaryData(Name, Value, SizeOf(TDateTime));
 end;
 
-procedure TRegistry.WriteDateTime(const Name: string; Value: TDateTime);
+procedure TRegistry.WriteTime(const Name: String; Value: TDateTime);
 begin
+  WriteTime(UnicodeString(Name), Value);
+end;
+
+procedure TRegistry.WriteDateTime(const Name: UnicodeString; Value: TDateTime);
+begin
   WriteBinaryData(Name, Value, SizeOf(TDateTime));
 end;
 
-procedure TRegistry.WriteExpandString(const Name, Value: string);
-var
-  u: UnicodeString;
+procedure TRegistry.WriteDateTime(const Name: String; Value: TDateTime);
+begin
+  WriteDateTime(UnicodeString(Name), Value);
+end;
 
+procedure TRegistry.WriteExpandString(const Name, Value: UnicodeString);
 begin
-  u:=Value;
-  PutData(Name, PWideChar(u), ByteLength(u), rdExpandString);
+  PutData(Name, PWideChar(Value), ByteLength(Value), rdExpandString);
 end;
 
-procedure TRegistry.WriteStringList(const Name: string; List: TStrings);
+procedure TRegistry.WriteExpandString(const Name, Value: String);
+begin
+  WriteExpandString(UnicodeString(Name), UnicodeString(Value));
+end;
 
+
+procedure TRegistry.WriteStringList(const Name: UnicodeString; List: TStrings; IsUtf8: Boolean=False);
+
 Var
-  Data: string;
+  UArr: TUnicodeStringArray;
+begin
+  UArr := ListToArray(List, IsUtf8);
+  WriteStringArray(Name, UArr);
+end;
 
+procedure TRegistry.WriteStringArray(const Name: UnicodeString; const Arr: TUnicodeStringArray);
+Var
+  Data: UnicodeString;
+  u: UnicodeString;
+  i: Integer;
 begin
-  Data := StringReplace(List.Text, LineEnding, #0, [rfReplaceAll]) + #0#0;
-  PutData(Name, PChar(Data), Length(Data),rdMultiString);
+  Data := '';
+  //REG_MULTI_SZ data cannot contain empty strings
+  for i := Low(Arr) to High(Arr) do
+  begin
+    u := Arr[i];
+    if (u>'') then
+    begin
+      if (Data>'') then
+        Data := Data + #0 + u
+      else
+        Data := Data + u;
+    end;
+  end;
+  if StringSizeIncludesNull then
+    Data := Data + #0#0;
+  //writeln('Data=',Dbgs(Data));
+  PutData(Name, PWideChar(Data), ByteLength(Data), rdMultiString);
 end;
 
-procedure TRegistry.WriteFloat(const Name: string; Value: Double);
+procedure TRegistry.WriteStringArray(const Name: String; const Arr: TStringArray);
+var
+  UArr: TUnicodeStringArray;
+  i: Integer;
 begin
+  UArr := nil;
+  SetLength(UArr, Length(Arr));
+  for i := Low(Arr) to High(Arr) do UArr[i] := Arr[i];
+  WriteStringArray(UnicodeString(Name), UArr);
+end;
+
+procedure TRegistry.WriteFloat(const Name: UnicodeString; Value: Double);
+begin
   WriteBinaryData(Name, Value, SizeOf(Double));
 end;
 
-procedure TRegistry.WriteInteger(const Name: string; Value: Integer);
+procedure TRegistry.WriteFloat(const Name: String; Value: Double);
 begin
+  WriteFloat(UnicodeString(Name), Value);
+end;
+
+procedure TRegistry.WriteInteger(const Name: UnicodeString; Value: Integer);
+begin
   PutData(Name, @Value, SizeOf(Integer), rdInteger);
 end;
 
-procedure TRegistry.WriteInt64(const Name: string; Value: Int64);
+procedure TRegistry.WriteInteger(const Name: String; Value: Integer);
 begin
+  WriteInteger(UnicodeString(Name), Value);
+end;
+
+procedure TRegistry.WriteInt64(const Name: UnicodeString; Value: Int64);
+begin
   PutData(Name, @Value, SizeOf(Int64), rdInt64);
 end;
 
-procedure TRegistry.WriteString(const Name, Value: string);
+procedure TRegistry.WriteInt64(const Name: String; Value: Int64);
+begin
+  WriteInt64(UnicodeString(Name), Value);
+end;
+
+procedure TRegistry.WriteString(const Name, Value: UnicodeString);
+begin
+  PutData(Name, PWideChar(Value), ByteLength(Value), rdString);
+end;
+
+procedure TRegistry.WriteString(const Name, Value: String);
+begin
+  WriteString(UnicodeString(Name), UnicodeString(Value));
+end;
+
+procedure TRegistry.GetKeyNames(Strings: TStrings);
 var
-  u: UnicodeString;
+  UArr: TUnicodeStringArray;
+begin
+  UArr := GetKeyNames;
+  ArrayToList(UArr, Strings, True);
+end;
 
+procedure TRegistry.GetValueNames(Strings: TStrings);
+var
+  UArr: TUnicodeStringArray;
 begin
-  u:=Value;
-  PutData(Name, PWideChar(u), ByteLength(u), rdString);
+  UArr := GetValueNames;
+  ArrayToList(UArr, Strings, True);
 end;
 
-procedure TRegistry.MoveKey(const OldName, NewName: string; Delete: Boolean);
+procedure TRegistry.MoveKey(const OldName, NewName: UnicodeString; Delete: Boolean);
 begin
 
 end;
 
+procedure TRegistry.MoveKey(const OldName, NewName: String; Delete: Boolean);
+begin
+  MoveKey(UnicodeString(OldName), UnicodeString(NewName), Delete);
+end;
+
+procedure TRegistry.RenameValue(const OldName, NewName: String);
+begin
+  RenameValue(UnicodeString(OldName), UnicodeString(NewName));
+end;
+
 { ---------------------------------------------------------------------
     Include TRegIniFile implementation
   ---------------------------------------------------------------------}
@@ -583,7 +1004,7 @@
   Value: TStream): Integer;
 begin
   result:=-1; // unimplemented
- // 
+ //
 end;
 
 function TRegistryIniFile.ReadDate(const Section, Name: string;
Index: packages/fcl-registry/src/winreg.inc
===================================================================
--- packages/fcl-registry/src/winreg.inc	(revision 41667)
+++ packages/fcl-registry/src/winreg.inc	(working copy)
@@ -28,7 +28,7 @@
   Dispose(PWinRegData(FSysData));
 end;
 
-Function PrepKey(Const S : String) : String;
+Function PrepKey(Const S : UnicodeString) : UnicodeString;
 
 begin
   Result := S;
@@ -36,7 +36,7 @@
     System.Delete(Result, 1, 1);
 end;
 
-Function RelativeKey(Const S : String) : Boolean;
+Function RelativeKey(Const S : UnicodeString) : Boolean;
 
 begin
   Result:=(S='') or (S[1]<>'\')
@@ -43,9 +43,8 @@
 end;
 
 
-function TRegistry.sysCreateKey(const Key: String): Boolean;
+function TRegistry.sysCreateKey(Key: UnicodeString): Boolean;
 Var
-  u: UnicodeString;
   Disposition: Dword;
   Handle: HKEY;
   SecurityAttributes: Pointer; //LPSECURITY_ATTRIBUTES;
@@ -52,9 +51,9 @@
 
 begin
   SecurityAttributes := Nil;
-  u:=PrepKey(Key);
+  Key:=PrepKey(Key);
   FLastError:=RegCreateKeyExW(GetBaseKey(RelativeKey(Key)),
-                              PWideChar(u),
+                              PWideChar(Key),
                               0,
                               '',
                               REG_OPTION_NON_VOLATILE,
@@ -66,7 +65,7 @@
   RegCloseKey(Handle);
 end;
 
-function TRegistry.DeleteKey(const Key: String): Boolean;
+function TRegistry.DeleteKey(const Key: UnicodeString): Boolean;
 
 Var
   u: UnicodeString;
@@ -76,21 +75,21 @@
   Result:=FLastError=ERROR_SUCCESS;
 end;
 
-function TRegistry.DeleteValue(const Name: String): Boolean;
+
+function TRegistry.DeleteValue(const Name: UnicodeString): Boolean;
 begin
-  FLastError:= RegDeleteValueW(fCurrentKey, PWideChar(UnicodeString(Name)));
+  FLastError:= RegDeleteValueW(fCurrentKey, PWideChar(Name));
   Result:=FLastError=ERROR_SUCCESS;
 end;
 
-function TRegistry.SysGetData(const Name: String; Buffer: Pointer;
+
+function TRegistry.SysGetData(const Name: UnicodeString; Buffer: Pointer;
           BufSize: Integer; Out RegData: TRegDataType): Integer;
 Var
-  u: UnicodeString;
   RD : DWord;
 
 begin
-  u := Name;
-  FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(u),Nil,
+  FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(Name),Nil,
                       @RD,Buffer,lpdword(@BufSize));
   if (FLastError<>ERROR_SUCCESS) Then
     Result:=-1
@@ -103,17 +102,15 @@
     end;
 end;
 
-function TRegistry.GetDataInfo(const ValueName: String; out Value: TRegDataInfo): Boolean;
+function TRegistry.GetDataInfo(const ValueName: UnicodeString; out Value: TRegDataInfo): Boolean;
 
 Var
-  u: UnicodeString;
   RD : DWord;
 
 begin
-  u:=ValueName;
   With Value do
     begin
-    FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(u),Nil,lpdword(@RegData),Nil,lpdword(@DataSize));
+    FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(ValueName),Nil,lpdword(@RegData),Nil,lpdword(@DataSize));
     Result:=FLastError=ERROR_SUCCESS;
     if Result then
       begin
@@ -131,24 +128,18 @@
 end;
 
 
-function TRegistry.GetKey(const Key: String): HKEY;
+function TRegistry.GetKey(Key: UnicodeString): HKEY;
 var
-  S : string;
-{$ifndef WinCE}
-  u : UnicodeString;
-{$endif}
   Rel : Boolean;
 begin
   Result:=0;
-  S:=Key;
-  Rel:=RelativeKey(S);
+  Rel:=RelativeKey(Key);
   if not(Rel) then
-    Delete(S,1,1);
+    Delete(Key,1,1);
 {$ifdef WinCE}
-  FLastError:=RegOpenKeyEx(GetBaseKey(Rel),PWideChar(WideString(S)),0,FAccess,Result);
+  FLastError:=RegOpenKeyEx(GetBaseKey(Rel),PWideChar(Key),0,FAccess,Result);
 {$else WinCE}
-  u:=UnicodeString(S);
-  FLastError:=RegOpenKeyExW(GetBaseKey(Rel),PWideChar(u),0,FAccess,Result);
+  FLastError:=RegOpenKeyExW(GetBaseKey(Rel),PWideChar(Key),0,FAccess,Result);
 {$endif WinCE}
 end;
 
@@ -158,7 +149,7 @@
   winFileTime: Windows.FILETIME;
   sysTime: TSystemTime;
 begin
-  FillChar(Value, SizeOf(Value), 0);
+  Value := Default(TRegKeyInfo);
   With Value do
     begin
     FLastError:=RegQueryInfoKeyA(CurrentKey,nil,nil,nil,lpdword(@NumSubKeys),
@@ -174,7 +165,7 @@
 end;
 
 
-function TRegistry.KeyExists(const Key: string): Boolean;
+function TRegistry.KeyExists(const Key: UnicodeString): Boolean;
 var
   KeyHandle : HKEY;
   OldAccess : LONG;
@@ -196,20 +187,20 @@
 end;
 
 
-function TRegistry.LoadKey(const Key, FileName: string): Boolean;
+function TRegistry.LoadKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
 
-function TRegistry.OpenKey(const Key: string; CanCreate: Boolean): Boolean;
 
+function TRegistry.OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
+
 Var
-  u: UnicodeString;
+  u, S: UnicodeString;
   Handle: HKEY;
   Disposition: Integer;
   SecurityAttributes: Pointer; //LPSECURITY_ATTRIBUTES;
-  S: string;
 begin
   SecurityAttributes := Nil;
   u:=PrepKey(Key);
@@ -232,13 +223,14 @@
     if RelativeKey(Key) then
       S:=CurrentPath + Key
     else
-      S:=UTF8Encode(u);
+      S:=u;
     ChangeKey(Handle, S);
   end;
 end;
 
-function TRegistry.OpenKeyReadOnly(const Key: string): Boolean;
 
+function TRegistry.OpenKeyReadOnly(const Key: UnicodeString): Boolean;
+
 Var
   OldAccess: LongWord;
 begin
@@ -251,7 +243,8 @@
   end;
 end;
 
-function TRegistry.RegistryConnect(const UNCName: string): Boolean;
+
+function TRegistry.RegistryConnect(const UNCName: UnicodeString): Boolean;
 {$ifndef WinCE}
 var
   newroot: HKEY;
@@ -260,7 +253,7 @@
 {$ifdef WinCE}
   Result:=False;
 {$else}
-  FLastError:=RegConnectRegistryW(PWideChar(UnicodeString(UNCName)),RootKey,newroot);
+  FLastError:=RegConnectRegistryW(PWideChar(UNCName),RootKey,newroot);
   Result:=FLastError=ERROR_SUCCESS;
   if Result then begin
     RootKey:=newroot;
@@ -269,28 +262,33 @@
 {$endif}
 end;
 
-function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
+
+function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.RestoreKey(const Key, FileName: string): Boolean;
+
+function TRegistry.RestoreKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.SaveKey(const Key, FileName: string): Boolean;
+
+function TRegistry.SaveKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.UnLoadKey(const Key: string): Boolean;
+
+function TRegistry.UnLoadKey(const Key: UnicodeString): Boolean;
 begin
   Result := false;
 end;
 
-function TRegistry.ValueExists(const Name: string): Boolean;
 
+function TRegistry.ValueExists(const Name: UnicodeString): Boolean;
+
 var
   Info : TRegDataInfo;
 
@@ -298,6 +296,7 @@
   Result:=GetDataInfo(Name,Info);
 end;
 
+
 procedure TRegistry.CloseKey;
 begin
   If (CurrentKey<>0) then
@@ -316,7 +315,7 @@
   RegCloseKey(key);
 end;
 
-procedure TRegistry.ChangeKey(Value: HKey; const Path: String);
+procedure TRegistry.ChangeKey(Value: HKey; const Path: UnicodeString);
 begin
   CloseKey;
   FCurrentKey:=Value;
@@ -323,8 +322,9 @@
   FCurrentPath:=Path;
 end;
 
-procedure TRegistry.GetKeyNames(Strings: TStrings);
 
+function TRegistry.GetKeyNames: TUnicodeStringArray;
+
 var
   Info:    TRegKeyInfo;
   dwLen:   DWORD;
@@ -331,15 +331,17 @@
   lpName:  LPWSTR;
   dwIndex: DWORD;
   lResult: LONGINT;
-  s:       string;
+  u:       UnicodeString;
 
 begin
-  Strings.Clear;
+  Result:=nil;
   if GetKeyInfo(Info) then
   begin
     dwLen:=Info.MaxSubKeyLen+1;
     GetMem(lpName,dwLen*SizeOf(WideChar));
     try
+      //writeln('TRegistry.GetKeyNames: Info.NumSubKeys=',Info.NumSubKeys);
+      SetLength(Result, Info.NumSubKeys);
       for dwIndex:=0 to Info.NumSubKeys-1 do
       begin
         dwLen:=Info.MaxSubKeyLen+1;
@@ -347,19 +349,13 @@
         if lResult<>ERROR_SUCCESS then
           raise ERegistryException.Create(SysErrorMessage(lResult));
         if dwLen=0 then
-          s:=''
+          u:=''
         else
         begin           // dwLen>0
-          SetLength(s,dwLen*3);
-          dwLen:=UnicodeToUTF8(PChar(s),Length(s)+1,lpName,dwLen);
-          if dwLen<=1 then
-            s:=''
-          else          // dwLen>1
-            SetLength(s,dwLen-1);
+          u:=lpName;
         end;            // if dwLen=0
-        Strings.Add(s);
+        Result[dwIndex]:=u;
       end;              // for dwIndex:=0 ...
-
     finally
       FreeMem(lpName);
     end;
@@ -366,8 +362,9 @@
   end;
 end;
 
-procedure TRegistry.GetValueNames(Strings: TStrings);
 
+Function TRegistry.GetValueNames: TUnicodeStringArray;
+
 var
   Info:    TRegKeyInfo;
   dwLen:   DWORD;
@@ -374,15 +371,16 @@
   lpName:  LPWSTR;
   dwIndex: DWORD;
   lResult: LONGINT;
-  s:       string;
+  u:       UnicodeString;
 
 begin
-   Strings.Clear;
+  Result:=nil;
   if GetKeyInfo(Info) then
   begin
     dwLen:=Info.MaxValueLen+1;
     GetMem(lpName,dwLen*SizeOf(WideChar));
     try
+      SetLength(Result, Info.NumValues);
       for dwIndex:=0 to Info.NumValues-1 do
       begin
         dwLen:=Info.MaxValueLen+1;
@@ -390,17 +388,12 @@
         if lResult<>ERROR_SUCCESS then
           raise ERegistryException.Create(SysErrorMessage(lResult));
         if dwLen=0 then
-          s:=''
+          u:=''
         else
         begin           // dwLen>0
-          SetLength(s,dwLen*3);
-          dwLen:=UnicodeToUTF8(PChar(s),Length(s)+1,lpName,dwLen);
-          if dwLen<=1 then
-            s:=''
-          else          // dwLen>1
-            SetLength(s,dwLen-1);
+          u:=lpName;
         end;            // if dwLen=0
-        Strings.Add(s);
+        Result[dwIndex]:=u;
       end;              // for dwIndex:=0 ...
 
     finally
@@ -410,12 +403,11 @@
 end;
 
 
-Function TRegistry.SysPutData(const Name: string; Buffer: Pointer;
+Function TRegistry.SysPutData(const Name: UnicodeString; Buffer: Pointer;
   BufSize: Integer; RegData: TRegDataType) : Boolean;
 
 
 Var
-  u: UnicodeString;
   RegDataType: DWORD;
   B : Pchar;
   S : String;
@@ -422,12 +414,11 @@
 
 begin
   RegDataType:=RegDataWords[RegData];
-  u:=UnicodeString(Name);
-  FLastError:=RegSetValueExW(fCurrentKey,PWideChar(u),0,RegDataType,Buffer,BufSize);
+  FLastError:=RegSetValueExW(fCurrentKey,PWideChar(Name),0,RegDataType,Buffer,BufSize);
   Result:=FLastError=ERROR_SUCCESS;
 end;
 
-procedure TRegistry.RenameValue(const OldName, NewName: string);
+procedure TRegistry.RenameValue(const OldName, NewName: UnicodeString);
 
 var
   L: Integer;
Index: packages/fcl-registry/src/xmlreg.pp
===================================================================
--- packages/fcl-registry/src/xmlreg.pp	(revision 41667)
+++ packages/fcl-registry/src/xmlreg.pp	(working copy)
@@ -25,6 +25,7 @@
     FTime     : TDateTime;
   end;
 
+  TUnicodeStringArray = Array of UnicodeString;
 
   { TXmlRegistry }
 
@@ -33,24 +34,24 @@
     FAutoFlush,
     FDirty : Boolean;
     FFileName : String;
-    FRootKey : String;
+    FRootKey : UnicodeString;
     FDocument : TXMLDocument;
     FCurrentElement : TDomElement;
-    FCurrentKey : String;
+    FCurrentKey : UnicodeString;
     Procedure SetFileName(Value : String);
   Protected
-    function DoGetValueData(Name: String; out DataType: TDataType; Var Data; Var DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
-    function DoSetValueData(Name: String; DataType: TDataType; const Data; DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
+    function DoGetValueData(Name: UnicodeString; out DataType: TDataType; Var Data; Var DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
+    function DoSetValueData(Name: UnicodeString; DataType: TDataType; const Data; DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
     Procedure LoadFromStream(S : TStream);
-    Function  NormalizeKey(KeyPath : String) : String;
+    Function  NormalizeKey(KeyPath : UnicodeString) : UnicodeString;
     Procedure CreateEmptyDoc;
-    Function  FindKey (S : String) : TDomElement;
-    Function  FindSubKey (S : String; N : TDomElement) : TDomElement;
-    Function  CreateSubKey (S : String; N : TDomElement) : TDomElement;
-    Function  FindValueKey (S : String) : TDomElement;
-    Function  CreateValueKey (S : String) : TDomElement;
+    Function  FindKey (S : UnicodeString) : TDomElement;
+    Function  FindSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
+    Function  CreateSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
+    Function  FindValueKey (S : UnicodeString) : TDomElement;
+    Function  CreateValueKey (S : UnicodeString) : TDomElement;
     Function  BufToHex(Const Buf; Len : Integer) : String;
-    Function  hexToBuf(Const Str : String; Var Buf; Var Len : Integer ) : Integer;
+    Function  HexToBuf(Const Str : UnicodeString; Var Buf; Var Len : Integer ) : Integer;
     Procedure MaybeFlush;
     Property  Document : TXMLDocument Read FDocument;
     Property  Dirty : Boolean Read FDirty write FDirty;
@@ -57,29 +58,31 @@
   Public
     Constructor Create(AFileName : String);
     Destructor  Destroy;override;
-    Function  SetKey(KeyPath : String; AllowCreate : Boolean) : Boolean ;
-    Procedure SetRootKey(Value : String);
-    Function  DeleteKey(KeyPath : String) : Boolean;
-    Function  CreateKey(KeyPath : String) : Boolean;
-    Function  GetValueSize(Name : String) : Integer;
-    Function  GetValueType(Name : String) : TDataType;
-    Function  GetValueInfo(Name : String; Out Info : TDataInfo; AsUnicode : Boolean = False) : Boolean;
+    Function  SetKey(KeyPath : UnicodeString; AllowCreate : Boolean) : Boolean ;
+    Procedure SetRootKey(Value : UnicodeString);
+    Function  DeleteKey(KeyPath : UnicodeString) : Boolean;
+    Function  CreateKey(KeyPath : UnicodeString) : Boolean;
+    Function  GetValueSize(Name : UnicodeString) : Integer;
+    Function  GetValueType(Name : UnicodeString) : TDataType;
+    Function  GetValueInfo(Name : UnicodeString; Out Info : TDataInfo; AsUnicode : Boolean = False) : Boolean;
     Function  GetKeyInfo(Out Info : TKeyInfo) : Boolean;
     Function  EnumSubKeys(List : TStrings) : Integer;
+    Function  EnumSubKeys: TUnicodeStringArray;
     Function  EnumValues(List : TStrings) : Integer;
-    Function  KeyExists(KeyPath : String) : Boolean;
-    Function  ValueExists(ValueName : String) : Boolean;
-    Function  RenameValue(Const OldName,NewName : String) : Boolean;
-    Function  DeleteValue(S : String) : Boolean;
+    Function  EnumValues: TUnicodeStringArray;
+    Function  KeyExists(KeyPath : UnicodeString) : Boolean;
+    Function  ValueExists(ValueName : UnicodeString) : Boolean;
+    Function  RenameValue(Const OldName,NewName : UnicodeString) : Boolean;
+    Function  DeleteValue(S : UnicodeString) : Boolean;
     Procedure Flush;
     Procedure Load;
-    Function GetValueData(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
-    Function SetValueData(Name : String; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
+    Function GetValueData(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
+    Function SetValueData(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
     // These interpret the Data buffer as unicode data
-    Function GetValueDataUnicode(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
-    Function SetValueDataUnicode(Name : String; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
+    Function GetValueDataUnicode(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
+    Function SetValueDataUnicode(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
     Property FileName : String Read FFileName Write SetFileName;
-    Property RootKey : String Read FRootKey Write SetRootkey;
+    Property RootKey : UnicodeString Read FRootKey Write SetRootkey;
     Property AutoFlush : Boolean Read FAutoFlush Write FAutoFlush;
   end;
 
@@ -143,13 +146,13 @@
   end;
 end;
 
-Function TXmlRegistry.NormalizeKey(KeyPath : String) : String;
+Function TXmlRegistry.NormalizeKey(KeyPath : UnicodeString) : UnicodeString;
 
 Var
   L : Integer;
 
 begin
-  Result:=StringReplace(KeyPath,'\','/',[rfReplaceAll]);
+  Result:=UnicodeStringReplace(KeyPath,'\','/',[rfReplaceAll]);
   L:=Length(Result);
   If (L>0) and (Result[L]<>'/') then
     Result:=Result+'/';
@@ -157,10 +160,10 @@
     Result:='/' + Result;
 end;
 
-Function TXmlRegistry.SetKey(KeyPath : String; AllowCreate : Boolean) : boolean;
+Function TXmlRegistry.SetKey(KeyPath : UnicodeString; AllowCreate : Boolean) : boolean;
 
 Var
-  SubKey,ResultKey : String;
+  SubKey,ResultKey : UnicodeString;
   P : Integer;
   Node,Node2 : TDomElement;
 
@@ -218,7 +221,7 @@
   MaybeFlush;
 end;
 
-Procedure TXmlRegistry.SetRootKey(Value : String);
+Procedure TXmlRegistry.SetRootKey(Value : UnicodeString);
 
 begin
   FRootKey:=NormalizeKey(Value);
@@ -228,7 +231,7 @@
   FCurrentElement:=Nil;
 end;
 
-Function TXmlRegistry.DeleteKey(KeyPath : String) : Boolean;
+Function TXmlRegistry.DeleteKey(KeyPath : UnicodeString) : Boolean;
 
 Var
   N : TDomElement;
@@ -244,10 +247,10 @@
    end;
 end;
 
-Function TXmlRegistry.CreateKey(KeyPath : String) : Boolean;
+Function TXmlRegistry.CreateKey(KeyPath : UnicodeString) : Boolean;
 
 Var
-  SubKey : String;
+  SubKey : UnicodeString;
   P : Integer;
   Node,Node2 : TDomElement;
 
@@ -290,7 +293,7 @@
   MaybeFlush;
 end;
 
-Function TXmlRegistry.DoGetValueData(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer; IsUnicode : Boolean) : Boolean;
+Function TXmlRegistry.DoGetValueData(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer; IsUnicode : Boolean) : Boolean;
 
 Type
   PCardinal = ^Cardinal;
@@ -305,22 +308,27 @@
   D : DWord;
   
 begin
+  //writeln('TXmlRegistry.DoGetValueData: Name=',Name,' IsUnicode=',IsUnicode);
   Node:=FindValueKey(Name);
   Result:=Node<>Nil;
   If Result then
     begin
+    //writeln('TXmlRegistry.DoGetValueData: Node<>nil');
     DataNode:=Node.FirstChild;
     HasData:=Assigned(DataNode) and (DataNode.NodeType=TEXT_NODE);
-    ND:=StrToIntDef(Node[Stype],0);
+    //writeln('TXmlRegistry.DoGetValueData: HasData=',hasdata);
+    ND:=StrToIntDef(String(Node[Stype]),0);
+    //writeln('TXmlRegistry.DoGetValueData: ND=',ND);
     Result:=ND<=Ord(High(TDataType));
     If Result then
       begin
       DataType:=TDataType(ND);
+      //writeln('TXmlRegistry.DoGetValueData: DataType=',DataType);
       NS:=0; // Initialize, for optional nodes.
       Case DataType of
         dtDWORD : begin   // DataNode is required
                   NS:=SizeOf(Cardinal);
-                  Result:=HasData and TryStrToDWord(DataNode.NodeValue,D) and (DataSize>=NS);
+                  Result:=HasData and TryStrToDWord(String(DataNode.NodeValue),D) and (DataSize>=NS);
                   if Result then
                     PCardinal(@Data)^:=D;
                   end;
@@ -329,7 +337,7 @@
                      begin
                      if not IsUnicode then
                        begin
-                       S:=UTF8Encode(DataNode.NodeValue); // Convert to ansistring
+                       S:=DataNode.NodeValue; // Convert to ansistring
                        NS:=Length(S);
                        Result:=(DataSize>=NS);
                        if Result then
@@ -350,8 +358,10 @@
                    if HasData then
                      begin
                      BL:=Length(DataNode.NodeValue);
+                     //writeln('TXmlRegistry.DoGetValueData: BL=',BL);
                      NS:=BL div 2;
                      Result:=DataSize>=NS;
+                     //writeln('TXmlRegistry.DoGetValueData: Result=',Result);
                      If Result then
                        // No need to check for -1, We checked NS before calling.
                        NS:=HexToBuf(DataNode.NodeValue,Data,BL);
@@ -363,7 +373,7 @@
     end;
 end;
 
-Function TXmlRegistry.DoSetValueData(Name : String; DataType : TDataType; Const Data; DataSize : Integer; IsUnicode : Boolean) : Boolean;
+Function TXmlRegistry.DoSetValueData(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer; IsUnicode : Boolean) : Boolean;
 
 Type
   PCardinal = ^Cardinal;
@@ -374,6 +384,7 @@
   SW : UnicodeString;
 
 begin
+  //writeln('TXmlRegistry.DoSetValueData A: Name=',Name,', DataType=',DataType,', DataSize=',DataSize,', IsUnicode=',IsUnicode);
   Node:=FindValueKey(Name);
   If Node=Nil then
     Node:=CreateValueKey(Name);
@@ -380,20 +391,20 @@
   Result:=(Node<>Nil);
   If Result then
     begin
-    Node[SType]:=IntToStr(Ord(DataType));
+    Node[SType]:=UnicodeString(IntToStr(Ord(DataType)));
     DataNode:=Node.FirstChild;
 
     Case DataType of
-      dtDWORD : SW:=IntToStr(PCardinal(@Data)^);
+      dtDWORD : SW:=UnicodeString(IntToStr(PCardinal(@Data)^));
       dtString : begin
                  if IsUnicode then
                    SW:=UnicodeString(PUnicodeChar(@Data))
                  else
                    SW:=UnicodeString(PAnsiChar(@Data));
-                   //S:=UTF8Encode(SW);
+                   //S:=SW;
                  end;
-      dtBinary : SW:=BufToHex(Data,DataSize);
-      dtStrings : SW:=BufToHex(Data,DataSize);
+      dtBinary : SW:=UnicodeString(BufToHex(Data,DataSize));
+      dtStrings : SW:=UnicodeString(BufToHex(Data,DataSize));
     else
       sw:='';
     end;
@@ -416,29 +427,29 @@
     end;
 end;
 
-Function TXmlRegistry.SetValueData(Name : String; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
+Function TXmlRegistry.SetValueData(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
 
 begin
   Result:=DoSetValueData(Name,DataType,Data,DataSize,False);
 end;
 
-Function TXmlRegistry.GetValueData(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
+Function TXmlRegistry.GetValueData(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
 
 begin
   Result:=DoGetValueData(Name,DataType,Data,DataSize,False);
 end;
 
-function TXmlRegistry.GetValueDataUnicode(Name: String; out DataType: TDataType; Var Data; Var DataSize: Integer): Boolean;
+function TXmlRegistry.GetValueDataUnicode(Name: UnicodeString; out DataType: TDataType; Var Data; Var DataSize: Integer): Boolean;
 begin
   Result:=DoGetValueData(Name,DataType,Data,DataSize,True);
 end;
 
-function TXmlRegistry.SetValueDataUnicode(Name: String; DataType: TDataType; const Data; DataSize: Integer): Boolean;
+function TXmlRegistry.SetValueDataUnicode(Name: UnicodeString; DataType: TDataType; const Data; DataSize: Integer): Boolean;
 begin
   Result:=DoSetValueData(Name,DataType,Data,DataSize,True)
 end;
 
-Function TXmlRegistry.FindSubKey (S : String; N : TDomElement) : TDomElement;
+Function TXmlRegistry.FindSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
 
 Var
   Node : TDOMNode;
@@ -451,7 +462,7 @@
     While (Result=Nil) and (Assigned(Node)) do
       begin
       If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SKey) then
-        If CompareText(TDomElement(Node)[SName],S)=0 then
+        If UnicodeCompareText(TDomElement(Node)[SName],S)=0 then
           Result:=TDomElement(Node);
       Node:=Node.NextSibling;
       end;
@@ -458,7 +469,7 @@
     end;
 end;
 
-Function TXmlRegistry.CreateSubKey (S : String; N : TDomElement) : TDomElement;
+Function TXmlRegistry.CreateSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
 
 begin
   Result:=FDocument.CreateElement(SKey);
@@ -468,7 +479,7 @@
   FDirty:=True;
 end;
 
-Function  TXmlRegistry.FindValueKey (S : String) : TDomElement;
+Function  TXmlRegistry.FindValueKey (S : UnicodeString) : TDomElement;
 
 Var
   Node : TDOMNode;
@@ -481,7 +492,7 @@
     While (Result=Nil) and (Assigned(Node)) do
       begin
       If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SValue) then
-        If CompareText(TDomElement(Node)[SName],S)=0 then
+        If UnicodeCompareText(TDomElement(Node)[SName],S)=0 then
           Result:=TDomElement(Node);
       Node:=Node.NextSibling;
       end;
@@ -488,7 +499,7 @@
     end;
 end;
 
-Function  TXmlRegistry.CreateValueKey (S : String) : TDomElement;
+Function  TXmlRegistry.CreateValueKey (S : UnicodeString) : TDomElement;
 
 begin
   If Assigned(FCurrentElement) then
@@ -581,38 +592,47 @@
     end;
 end;
 
-Function TXMLRegistry.hexToBuf(Const Str : String; Var Buf; Var Len : Integer ) : Integer;
+Function TXMLRegistry.HexToBuf(Const Str : UnicodeString; Var Buf; Var Len : Integer ) : Integer;
 
 Var
   NLeN,I : Integer;
   P : PByte;
-  S : String;
+  S : UnicodeString;
   B : Byte;
   Code : Integer;
 
 begin
+  //writeln('TXMLRegistry.HexToBuf A: Str=',Str,', Len=',Len);
   Result:=0;
   P:=@Buf;
+  //writeln('TXMLRegistry.HexToBuf B: (p=nil)=',p=nil);
   NLen:= Length(Str) div 2;
+  //writeln('TXMLRegistry.HexToBuf C: NLen=',NLen,', SizeOf(TDateTime)=',SizeOf(TDateTime));
   If (NLen>Len) then
     begin
     Len:=NLen;
     Exit(-1);
     end;
-  For I:=0 to Len-1 do
+  For I:=0 to NLen-1 do
     begin
+    //write('TXMLRegistry.HexToBuf: i=',i);
     S:='$'+Copy(Str,(I*2)+1,2);
+    //write(', S=',S);
     Val(S,B,Code);
+    //writeln(', Code=',Code);
     If Code<>0 then
-      begin
-      Inc(Result);
-      B:=0;
+      begin    //This means invalid data in the registry, why continue and increment result? Why not Exit(-1)?
+      //Inc(Result);   //the whole function only worked because this was called as often as when Code=0, so by change
+      //B:=0;          //it causes AV's
+      Exit(-1);
       end;
+    Inc(Result);
     P[I]:=B;
     end;
+  //writeln('TXMLRegistry.HexToBuf End: Result=',Result);
 end;
 
-Function TXMLRegistry.DeleteValue(S : String) : Boolean;
+Function TXMLRegistry.DeleteValue(S : UnicodeString) : Boolean;
 
 Var
   N : TDomElement;
@@ -628,31 +648,31 @@
     end;
 end;
 
-Function TXMLRegistry.GetValueSize(Name : String) : Integer;
+Function TXMLRegistry.GetValueSize(Name : UnicodeString) : Integer;
 
 Var
   Info : TDataInfo;
 
 begin
-  If GetValueInfo(Name,Info) then
+  If GetValueInfo(Name,Info,True) then
     Result:=Info.DataSize
   else
     Result:=-1;
 end;
 
-Function TXMLRegistry.GetValueType(Name : String) : TDataType;
+Function TXMLRegistry.GetValueType(Name : UnicodeString) : TDataType;
 
 Var
   Info : TDataInfo;
 
 begin
-  If GetValueInfo(Name,Info) then
+  If GetValueInfo(Name,Info,True) then
     Result:=Info.DataType
   else
     Result:=dtUnknown;
 end;
 
-function TXmlRegistry.GetValueInfo(Name: String; out Info: TDataInfo; AsUnicode: Boolean): Boolean;
+function TXmlRegistry.GetValueInfo(Name: UnicodeString; out Info: TDataInfo; AsUnicode: Boolean): Boolean;
 
 Var
   N  : TDomElement;
@@ -671,7 +691,7 @@
         L:=Length(DN.NodeValue)*SizeOf(UnicodeChar)
       else
         begin
-        S := UTF8Encode(DN.NodeValue);
+        S := DN.NodeValue;
         L:=Length(S);
         end
       end
@@ -679,7 +699,7 @@
       L:=0;
     With Info do
       begin
-      DataType:=TDataType(StrToIntDef(N[SType],0));
+      DataType:=TDataType(StrToIntDef(String(N[SType]),0));
       Case DataType of
         dtUnknown : DataSize:=0;
         dtDword   : Datasize:=SizeOf(Cardinal);
@@ -724,10 +744,10 @@
               ValueLen:=L;
             DataNode:=TDomElement(Node).FirstChild;
             If (DataNode<>Nil) and (DataNode is TDomText) then
-              Case TDataType(StrToIntDef(TDomElement(Node)[SType],0)) of
+              Case TDataType(StrToIntDef(String(TDomElement(Node)[SType]),0)) of
                 dtUnknown : L:=0;
                 dtDWord   : L:=4;
-                DtString  : L:=Length(UTF8Encode(DataNode.NodeValue));
+                DtString  : L:=Length(String(DataNode.NodeValue));
                 dtBinary  : L:=Length(DataNode.NodeValue) div 2;
               end
             else
@@ -761,6 +781,37 @@
     end;
 end;
 
+function TXmlRegistry.EnumSubKeys: TUnicodeStringArray;
+
+Var
+  Node : TDOMNode;
+  Len, Count: Integer;
+
+begin
+  Result:=nil;
+  If FCurrentElement<>Nil then
+    begin
+    Node:=FCurrentElement.FirstChild;
+    Len:=0;
+    Count:=0;
+    While Assigned(Node) do
+      begin
+      If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SKey) then
+        begin
+        Inc(Count);
+        if (Count>Len) then
+          begin
+          Inc(Len,10); //avoid calling SetLength on each addition
+          SetLength(Result,Len);
+          end;
+        Result[Count-1]:=TDomElement(Node)[SName];
+        end;
+      Node:=Node.NextSibling;
+      end;
+    SetLength(Result,Count);
+    end;
+end;
+
 Function TXMLRegistry.EnumValues(List : TStrings) : Integer;
 
 Var
@@ -775,7 +826,8 @@
     While Assigned(Node) do
       begin
       If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SValue) then
-        List.Add(TDomElement(Node)[SName]);
+        If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SValue) then
+          List.Add(TDomElement(Node)[SName]);
       Node:=Node.NextSibling;
       end;
     Result:=List.Count;
@@ -782,13 +834,44 @@
     end;
 end;
 
-Function TXMLRegistry.KeyExists(KeyPath : String) : Boolean;
+Function TXMLRegistry.EnumValues: TUnicodeStringArray;
 
+Var
+  Node : TDOMNode;
+  Len, Count: Integer;
 begin
+  Result:=nil;
+  If FCurrentElement<>Nil then
+    begin
+    Node:=FCurrentElement.FirstChild;
+    Count:=0;
+    Len:=0;
+    While Assigned(Node) do
+      begin
+      If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SValue) then
+        begin
+        Inc(Count);
+        if (Count>Len) then
+          begin
+          Inc(Len,10); //avoid calling SetLength on each addition
+          SetLength(Result,Len);
+          end;
+        Result[Count-1]:=TDomElement(Node)[SName];
+        end;
+      Node:=Node.NextSibling;
+      end;
+    SetLength(Result,Count);
+    end;
+end;
+
+
+Function TXMLRegistry.KeyExists(KeyPath : UnicodeString) : Boolean;
+
+begin
   Result:=FindKey(KeyPath)<>Nil;
 end;
 
-Function TXMLRegistry.RenameValue(Const OldName,NewName : String) : Boolean;
+Function TXMLRegistry.RenameValue(Const OldName,NewName : UnicodeString) : Boolean;
 
 Var
   N : TDomElement;
@@ -804,10 +887,10 @@
     end;
 end;
 
-Function TXMLRegistry.FindKey (S : String) : TDomElement;
+Function TXMLRegistry.FindKey (S : UnicodeString) : TDomElement;
 
 Var
-  SubKey : String;
+  SubKey : UnicodeString;
   P : Integer;
   Node : TDomElement;
 
@@ -840,7 +923,7 @@
   Until (Result=Nil) or (Length(S)=0);
 end;
 
-Function  TXmlRegistry.ValueExists(ValueName : String) : Boolean;
+Function  TXmlRegistry.ValueExists(ValueName : UnicodeString) : Boolean;
 
 begin
   Result:=FindValueKey(ValueName)<>Nil;
Index: packages/fcl-registry/src/xregreg.inc
===================================================================
--- packages/fcl-registry/src/xregreg.inc	(revision 41667)
+++ packages/fcl-registry/src/xregreg.inc	(working copy)
@@ -116,7 +116,11 @@
 procedure TRegistry.SysRegCreate;
 var s : string;
 begin
+  FStringSizeIncludesNull:=False;
   s:=includetrailingpathdelimiter(GetAppConfigDir(GlobalXMLFile));
+  {$ifdef XMLRegfile_in_CurDir}
+  s:='.' + PathDelim;
+  {$endif}
   ForceDirectories(s);
   FSysData:=TXMLRegistryInstance.GetXMLRegistry(s+XFileName);
   TXmlRegistry(FSysData).AutoFlush:=False;
@@ -130,24 +134,24 @@
   TXMLRegistryInstance.FreeXMLRegistry(TXMLRegistry(FSysData));
 end;
 
-function TRegistry.SysCreateKey(const Key: String): Boolean;
+function TRegistry.SysCreateKey(Key: UnicodeString): Boolean;
 
 begin
   Result:=TXmlRegistry(FSysData).CreateKey(Key);
 end;
 
-function TRegistry.DeleteKey(const Key: string): Boolean;
+function TRegistry.DeleteKey(const Key: UnicodeString): Boolean;
 
 begin
   Result:=TXMLRegistry(FSysData).DeleteKey(Key);
 end;
 
-function TRegistry.DeleteValue(const Name: string): Boolean;
+function TRegistry.DeleteValue(const Name: UnicodeString): Boolean;
 begin
   Result:=TXmlRegistry(FSysData).DeleteValue(Name);
 end;
 
-function TRegistry.SysGetData(const Name: String; Buffer: Pointer;
+function TRegistry.SysGetData(const Name: UnicodeString; Buffer: Pointer;
           BufSize: Integer; Out RegData: TRegDataType): Integer;
 
 Var
@@ -160,7 +164,7 @@
     Result:=-1;
 end;
 
-function TRegistry.GetDataInfo(const ValueName: string; out Value: TRegDataInfo): Boolean;
+function TRegistry.GetDataInfo(const ValueName: UnicodeString; out Value: TRegDataInfo): Boolean;
 
 Var
   Info : TDataInfo;
@@ -181,7 +185,7 @@
       end;
 end;
 
-function TRegistry.GetKey(const Key: string): HKEY;
+function TRegistry.GetKey(Key: UnicodeString): HKEY;
 begin
   Result := 0;
 end;
@@ -205,17 +209,17 @@
       end;
 end;
 
-function TRegistry.KeyExists(const Key: string): Boolean;
+function TRegistry.KeyExists(const Key: UnicodeString): Boolean;
 begin
   Result:=TXmlRegistry(FSysData).KeyExists(Key);
 end;
 
-function TRegistry.LoadKey(const Key, FileName: string): Boolean;
+function TRegistry.LoadKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.OpenKey(const Key: string; CanCreate: Boolean): Boolean;
+function TRegistry.OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
 
 begin
   Result:=TXmlRegistry(FSysData).SetKey(Key,CanCreate);
@@ -222,59 +226,59 @@
   FCurrentKey:=1;
 end;
 
-function TRegistry.OpenKeyReadOnly(const Key: string): Boolean;
+function TRegistry.OpenKeyReadOnly(const Key: UnicodeString): Boolean;
 
 begin
   Result:=TXmlRegistry(FSysData).SetKey(Key,False);
 end;
 
-function TRegistry.RegistryConnect(const UNCName: string): Boolean;
+function TRegistry.RegistryConnect(const UNCName: UnicodeString): Boolean;
 begin
   Result := True;
 end;
 
-function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
+function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.RestoreKey(const Key, FileName: string): Boolean;
+function TRegistry.RestoreKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.SaveKey(const Key, FileName: string): Boolean;
+function TRegistry.SaveKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.UnLoadKey(const Key: string): Boolean;
+function TRegistry.UnLoadKey(const Key: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.ValueExists(const Name: string): Boolean;
+function TRegistry.ValueExists(const Name: UnicodeString): Boolean;
 begin
   Result := TXmlRegistry(FSysData).ValueExists(Name);
 end;
 
-procedure TRegistry.ChangeKey(Value: HKey; const Path: string);
+procedure TRegistry.ChangeKey(Value: HKey; const Path: UnicodeString);
 begin
 
 end;
 
-procedure TRegistry.GetKeyNames(Strings: TStrings);
+function TRegistry.GetKeyNames: TUnicodeStringArray;
 begin
-  TXmlRegistry(FSysData).EnumSubKeys(Strings);
+  Result:=TXmlRegistry(FSysData).EnumSubKeys;
 end;
 
-procedure TRegistry.GetValueNames(Strings: TStrings);
+function TRegistry.GetValueNames: TUnicodeStringArray;
 begin
-  TXmlRegistry(FSysData).EnumValues(Strings);
+  Result := TXmlRegistry(FSysData).EnumValues;
 end;
 
 
-function TRegistry.SysPutData(const Name: string; Buffer: Pointer;
+function TRegistry.SysPutData(const Name: UnicodeString; Buffer: Pointer;
   BufSize: Integer; RegData: TRegDataType): Boolean;
 
 Var
@@ -281,15 +285,18 @@
   DataType : TDataType;
 
 begin
+  //writeln('TRegistry.SysPutData: Name=',Name,', RegData=',RegData,', BufSize=',BufSize);
   DataType:=RegDataTypeToXmlDataType(RegData);
+
   Result:=TXMLRegistry(FSysData).SetValueDataUnicode(Name,DataType,Buffer^,BufSize);
 end;
 
-procedure TRegistry.RenameValue(const OldName, NewName: string);
+procedure TRegistry.RenameValue(const OldName, NewName: UnicodeString);
 begin
   TXMLRegistry(FSysData).RenameValue(OldName,NewName);
 end;
 
+
 procedure TRegistry.SetCurrentKey(Value: HKEY);
 begin
   fCurrentKey := Value;
@@ -298,7 +305,7 @@
 procedure TRegistry.SetRootKey(Value: HKEY);
 
 Var
-  S: String;
+  S: UnicodeString;
 
 begin
   If (Value=HKEY_CLASSES_ROOT) then
@@ -347,3 +354,5 @@
     TXMLRegistry(FSysData).SetRootKey(TXMLRegistry(FSysData).RootKey);
   end;
 end;
+
+

Bart Broersma

2019-03-19 19:17

reporter   ~0114929

Attached file registry.unicode.part6.diff:
Slightly improves TXMLRegistry.EnumValues and TXMLRegistry.EnumKeys by not calling SetLength on each addition.

Serge Anvarov

2019-03-20 10:25

reporter   ~0114937

Bart, can you upload the changed files, because at revision 41749 applying the patch registry.unicode.part6.diff gives a lot of conflicts?

Bart Broersma

2019-03-20 15:41

reporter   ~0114940

Patchfiles were made against r41667.
Since then no changes were applied to fcl-registry (at least I was told so by the fpc devels).

According to https://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/packages/fcl-registry/src/ , the last update in that folder is r41415.

So, I don't really see how you could get a conflict.

I know you worked in the registry yourself (IIRC you have several patches in the bugtracker), did you revert your changes before trying to apply my patchfile?

Bart Broersma

2019-03-20 15:47

reporter   ~0114941

Just tested:

C:\devel\fpc\trunk>svn revert -R packages\fcl-registry
Reverted 'packages\fcl-registry\src\winreg.inc'
Reverted 'packages\fcl-registry\src\regdef.inc'
Reverted 'packages\fcl-registry\src\registry.pp'
Reverted 'packages\fcl-registry\src\xregreg.inc'
Reverted 'packages\fcl-registry\src\xmlreg.pp'

C:\devel\fpc\trunk>svn up
Updating '.':
....
Updated to revision 41749.

C:\devel\fpc\trunk>svn patch registry.unicode.part6.diff
U packages\fcl-registry\src\regdef.inc
U packages\fcl-registry\src\registry.pp
U packages\fcl-registry\src\winreg.inc
U packages\fcl-registry\src\xmlreg.pp
U packages\fcl-registry\src\xregreg.inc

Bart Broersma

2019-03-22 18:33

reporter   ~0114983

@Serge: did you manage to apply the patch in the mean time?

Joost van der Sluis

2019-03-23 10:36

manager   ~0114985

I thought I could have a look at it again, but Bart and Michael discussed so much about it, better that Michael should have a look at it.

Some comments from my part:
- I do not like big patches, I would have preferred smaller patches. But it was not possible for me to follow up on all the mails on the ML to catch up.
- I can live with the big-patch when it solves one issue. But there are also unrelated changes like the replacement of fillchar with Default. Or a change in the code that strips trailing #0 characters. And there might be others. Those should go in a separate patch, imho. Yes, it is annoying to keep track of such changes, but do one thing at once, please.
- CurrenPath changed from string to unicode string. That's backwards incompatible although I do not see a real problem with it, as everything was converted to a widestring anyway in the past too.
- GetValueNames? Probably discussed with Michael? It does not seems to be backwards compatible.

Bart Broersma

2019-03-23 14:26

reporter   ~0114988

Last edited: 2019-03-23 14:47

View 4 revisions

> - I do not like big patches,
I was told to do a all-in-one patch, so that the impact of the changes were visible at a glance...

> - I can live with the big-patch when it solves one issue. But there are also
> unrelated changes like the replacement of fillchar with Default.
I can undo that.
(I got a bit carried away when trying to solve as much compiler warnings as possible)

> -Or a change in the code that strips trailing #0 characters.
This is about the Read/WriteStringList code that does not work with Unicode.
It makes no sense to me to make it Unicode aware, but still not correct.
(Again: I was told to solve 0034876 in this patch as well)

- CurrenPath changed from string to unicode string. That's backwards
> incompatible although
Having CurentPath as AnsiString would make no sense if TRegistry is fully Unicode capable, hence I change it. This change IMO is part of what I was "told to do".

- GetValueNames? Probably discussed with Michael? It does not seems to be backwards compatible.

Indeed this was discussed on ML.
The one returning a TUnicodeStringArray did not exist before, but the TStrings version uses it. It will a return TStrings with all strings CP_ACP encoded.
Adding an optional boolean parameter to have it UTF8 encoded/decoded is trivial, but it changes the signature of the method, which might then be frowned upon.

Bart Broersma

2019-03-23 14:42

reporter  

registry.unicode.part7.diff (68,110 bytes)
Index: packages/fcl-registry/src/regdef.inc
===================================================================
--- packages/fcl-registry/src/regdef.inc	(revision 41749)
+++ packages/fcl-registry/src/regdef.inc	(working copy)
@@ -2,7 +2,7 @@
   HKEY = THandle;
   PHKEY = ^HKEY;
   
-{$ifdef windows}
+{$if defined(windows) and not defined(XMLREG)}
 
 { Direct mapping to constants in Windows unit }
 
Index: packages/fcl-registry/src/registry.pp
===================================================================
--- packages/fcl-registry/src/registry.pp	(revision 41749)
+++ packages/fcl-registry/src/registry.pp	(working copy)
@@ -39,6 +39,8 @@
     DataSize: Integer;
   end;
 
+  TUnicodeStringArray = Array of UnicodeString;
+
 { ---------------------------------------------------------------------
     TRegistry
   ---------------------------------------------------------------------}
@@ -54,22 +56,31 @@
     fCurrentKey: HKEY;
     fRootKey: HKEY;
     fLazyWrite: Boolean;
-    fCurrentPath: string;
+    fCurrentPath: UnicodeString;
     function GetLastErrorMsg: string;
+    function RegMultiSzDataToUnicodeStringArray(U: UnicodeString): TUnicodeStringArray;
+    function ListToArray(List: TStrings; IsUtf8: Boolean): TUnicodeStringArray;
+    procedure ArrayToList(const Arr: TUnicodeStringArray; List: TStrings; ForceUtf8: Boolean);
     procedure SetRootKey(Value: HKEY);
     Procedure SysRegCreate;
     Procedure SysRegFree;
-    Function  SysGetData(const Name: String; Buffer: Pointer; BufSize: Integer; Out RegData: TRegDataType): Integer;
-    Function  SysPutData(const Name: string; Buffer: Pointer; BufSize: Integer; RegData: TRegDataType) : Boolean;
-    Function  SysCreateKey(const Key: String): Boolean;
+    Function  SysGetData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; Out RegData: TRegDataType): Integer;
+    Function  SysPutData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; RegData: TRegDataType) : Boolean;
+    Function  SysCreateKey(Key: UnicodeString): Boolean;
   protected
     function GetBaseKey(Relative: Boolean): HKey;
-    function GetData(const Name: string; Buffer: Pointer;
+    function GetData(const Name: UnicodeString; Buffer: Pointer;
                   BufSize: Integer; Out RegData: TRegDataType): Integer;
-    function GetKey(const Key: string): HKEY;
-    procedure ChangeKey(Value: HKey; const Path: string);
-    procedure PutData(const Name: string; Buffer: Pointer;
+    function GetData(const Name: String; Buffer: Pointer;
+                  BufSize: Integer; Out RegData: TRegDataType): Integer;
+    function GetKey(Key: UnicodeString): HKEY;
+    function GetKey(Key: String): HKEY;
+    procedure ChangeKey(Value: HKey; const Path: UnicodeString);
+    procedure ChangeKey(Value: HKey; const Path: String);
+    procedure PutData(const Name: UnicodeString; Buffer: Pointer;
                   BufSize: Integer; RegData: TRegDataType);
+    procedure PutData(const Name: String; Buffer: Pointer;
+                  BufSize: Integer; RegData: TRegDataType);
     procedure SetCurrentKey(Value: HKEY);
   public
     constructor Create; overload;
@@ -76,58 +87,105 @@
     constructor Create(aaccess:longword); overload;
     destructor Destroy; override;
 
-    function CreateKey(const Key: string): Boolean;
-    function DeleteKey(const Key: string): Boolean;
-    function DeleteValue(const Name: string): Boolean;
-    function GetDataInfo(const ValueName: string; Out Value: TRegDataInfo): Boolean;
-    function GetDataSize(const ValueName: string): Integer;
-    function GetDataType(const ValueName: string): TRegDataType;
+    function CreateKey(const Key: UnicodeString): Boolean;
+    function CreateKey(const Key: String): Boolean;
+    function DeleteKey(const Key: UnicodeString): Boolean;
+    function DeleteKey(const Key: String): Boolean;
+    function DeleteValue(const Name: UnicodeString): Boolean;
+    function DeleteValue(const Name: String): Boolean;
+    function GetDataInfo(const ValueName: UnicodeString; Out Value: TRegDataInfo): Boolean;
+    function GetDataInfo(const ValueName: String; Out Value: TRegDataInfo): Boolean;
+    function GetDataSize(const ValueName: UnicodeString): Integer;
+    function GetDataSize(const ValueName: String): Integer;
+    function GetDataType(const ValueName: UnicodeString): TRegDataType;
+    function GetDataType(const ValueName: String): TRegDataType;
     function GetKeyInfo(Out Value: TRegKeyInfo): Boolean;
     function HasSubKeys: Boolean;
-    function KeyExists(const Key: string): Boolean;
-    function LoadKey(const Key, FileName: string): Boolean;
-    function OpenKey(const Key: string; CanCreate: Boolean): Boolean;
-    function OpenKeyReadOnly(const Key: string): Boolean;
-    function ReadCurrency(const Name: string): Currency;
-    function ReadBinaryData(const Name: string; var Buffer; BufSize: Integer): Integer;
-    function ReadBool(const Name: string): Boolean;
-    function ReadDate(const Name: string): TDateTime;
-    function ReadDateTime(const Name: string): TDateTime;
-    function ReadFloat(const Name: string): Double;
-    function ReadInteger(const Name: string): Integer;
-    function ReadInt64(const Name: string): Int64;
-    function ReadString(const Name: string): string;
-    procedure ReadStringList(const Name: string; AList: TStrings);
-    function ReadTime(const Name: string): TDateTime;
-    function RegistryConnect(const UNCName: string): Boolean;
-    function ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
-    function RestoreKey(const Key, FileName: string): Boolean;
-    function SaveKey(const Key, FileName: string): Boolean;
-    function UnLoadKey(const Key: string): Boolean;
-    function ValueExists(const Name: string): Boolean;
+    function KeyExists(const Key: UnicodeString): Boolean;
+    function KeyExists(const Key: String): Boolean;
+    function LoadKey(const Key, FileName: UnicodeString): Boolean;
+    function LoadKey(const Key, FileName: String): Boolean;
+    function OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
+    function OpenKey(const Key: String; CanCreate: Boolean): Boolean;
+    function OpenKeyReadOnly(const Key: UnicodeString): Boolean;
+    function OpenKeyReadOnly(const Key: String): Boolean;
+    function ReadCurrency(const Name: UnicodeString): Currency;
+    function ReadCurrency(const Name: String): Currency;
+    function ReadBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer): Integer;
+    function ReadBinaryData(const Name: String; var Buffer; BufSize: Integer): Integer;
+    function ReadBool(const Name: UnicodeString): Boolean;
+    function ReadBool(const Name: String): Boolean;
+    function ReadDate(const Name: UnicodeString): TDateTime;
+    function ReadDate(const Name: String): TDateTime;
+    function ReadDateTime(const Name: UnicodeString): TDateTime;
+    function ReadDateTime(const Name: String): TDateTime;
+    function ReadFloat(const Name: UnicodeString): Double;
+    function ReadFloat(const Name: String): Double;
+    function ReadInteger(const Name: UnicodeString): Integer;
+    function ReadInteger(const Name: String): Integer;
+    function ReadInt64(const Name: UnicodeString): Int64;
+    function ReadInt64(const Name: String): Int64;
+    function ReadString(const Name: UnicodeString): UnicodeString;
+    function ReadString(const Name: String): string;
+    procedure ReadStringList(const Name: UnicodeString; AList: TStrings; ForceUtf8: Boolean=False);
+    procedure ReadStringList(const Name: String; AList: TStrings);
+    function ReadStringArray(const Name: UnicodeString): TUnicodeStringArray;
+    function ReadStringArray(const Name: String): TStringArray;
+    function ReadTime(const Name: UnicodeString): TDateTime;
+    function ReadTime(const Name: String): TDateTime;
+    function RegistryConnect(const UNCName: UnicodeString): Boolean;
+    function RegistryConnect(const UNCName: String): Boolean;
+    function ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
+    function ReplaceKey(const Key, FileName, BackUpFileName: String): Boolean;
+    function RestoreKey(const Key, FileName: UnicodeString): Boolean;
+    function RestoreKey(const Key, FileName: String): Boolean;
+    function SaveKey(const Key, FileName: UnicodeString): Boolean;
+    function SaveKey(const Key, FileName: String): Boolean;
+    function UnLoadKey(const Key: UnicodeString): Boolean;
+    function UnLoadKey(const Key: String): Boolean;
+    function ValueExists(const Name: UnicodeString): Boolean;
+    function ValueExists(const Name: String): Boolean;
 
     procedure CloseKey;
     procedure CloseKey(key:HKEY);
     procedure GetKeyNames(Strings: TStrings);
+    function GetKeyNames: TUnicodeStringArray;
     procedure GetValueNames(Strings: TStrings);
-    procedure MoveKey(const OldName, NewName: string; Delete: Boolean);
-    procedure RenameValue(const OldName, NewName: string);
-    procedure WriteCurrency(const Name: string; Value: Currency);
-    procedure WriteBinaryData(const Name: string; var Buffer; BufSize: Integer);
-    procedure WriteBool(const Name: string; Value: Boolean);
-    procedure WriteDate(const Name: string; Value: TDateTime);
-    procedure WriteDateTime(const Name: string; Value: TDateTime);
-    procedure WriteFloat(const Name: string; Value: Double);
-    procedure WriteInteger(const Name: string; Value: Integer);
-    procedure WriteInt64(const Name: string; Value: Int64);
-    procedure WriteString(const Name, Value: string);
-    procedure WriteExpandString(const Name, Value: string);
-    procedure WriteStringList(const Name: string; List: TStrings);
-    procedure WriteTime(const Name: string; Value: TDateTime);
+    //ToDo
+    function GetValueNames: TUnicodeStringArray;
+    procedure MoveKey(const OldName, NewName: UnicodeString; Delete: Boolean);
+    procedure MoveKey(const OldName, NewName: String; Delete: Boolean);
+    procedure RenameValue(const OldName, NewName: UnicodeString);
+    procedure RenameValue(const OldName, NewName: String);
+    procedure WriteCurrency(const Name: UnicodeString; Value: Currency);
+    procedure WriteCurrency(const Name: String; Value: Currency);
+    procedure WriteBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer);
+    procedure WriteBinaryData(const Name: String; var Buffer; BufSize: Integer);
+    procedure WriteBool(const Name: UnicodeString; Value: Boolean);
+    procedure WriteBool(const Name: String; Value: Boolean);
+    procedure WriteDate(const Name: UnicodeString; Value: TDateTime);
+    procedure WriteDate(const Name: String; Value: TDateTime);
+    procedure WriteDateTime(const Name: UnicodeString; Value: TDateTime);
+    procedure WriteDateTime(const Name: String; Value: TDateTime);
+    procedure WriteFloat(const Name: UnicodeString; Value: Double);
+    procedure WriteFloat(const Name: String; Value: Double);
+    procedure WriteInteger(const Name: UnicodeString; Value: Integer);
+    procedure WriteInteger(const Name: String; Value: Integer);
+    procedure WriteInt64(const Name: UnicodeString; Value: Int64);
+    procedure WriteInt64(const Name: String; Value: Int64);
+    procedure WriteString(const Name, Value: UnicodeString);
+    procedure WriteString(const Name, Value: String);
+    procedure WriteExpandString(const Name, Value: UnicodeString);
+    procedure WriteExpandString(const Name, Value: String);
+    procedure WriteStringList(const Name: UnicodeString; List: TStrings; IsUtf8: Boolean=False);
+    procedure WriteStringArray(const Name: UnicodeString; const Arr: TUnicodeStringArray);
+    procedure WriteStringArray(const Name: String; const Arr: TStringArray);
+    procedure WriteTime(const Name: UnicodeString; Value: TDateTime);
+    procedure WriteTime(const Name: String; Value: TDateTime);
 
     property Access: LongWord read fAccess write fAccess;
     property CurrentKey: HKEY read fCurrentKey;
-    property CurrentPath: string read fCurrentPath;
+    property CurrentPath: UnicodeString read fCurrentPath;
     property LazyWrite: Boolean read fLazyWrite write fLazyWrite;
     property RootKey: HKEY read fRootKey write SetRootKey;
     Property StringSizeIncludesNull : Boolean read FStringSizeIncludesNull;
@@ -235,6 +293,16 @@
     Generic, implementation-independent code.
   ---------------------------------------------------------------------}
 
+{$ifdef DebugRegistry}
+function DbgS(const S: UnicodeString): String;
+var
+  C: WideChar;
+begin
+  Result := '';
+  for C in S do Result := Result + IntToHex(Word(C),4) + #32;
+  Result := TrimRight(Result);
+end;
+{$endif}
 
 constructor TRegistry.Create;
 
@@ -261,7 +329,7 @@
   inherited Destroy;
 end;
 
-function TRegistry.CreateKey(const Key: string): Boolean;
+function TRegistry.CreateKey(const Key: UnicodeString): Boolean;
 
 begin
   Result:=SysCreateKey(Key);
@@ -269,6 +337,27 @@
     Raise ERegistryException.CreateFmt(SRegCreateFailed, [Key]);
 end;
 
+function TRegistry.CreateKey(const Key: String): Boolean;
+begin
+  Result:=CreateKey(UnicodeString(Key));
+end;
+
+function TRegistry.DeleteKey(const Key: String): Boolean;
+begin
+  Result:=DeleteKey(UnicodeString(Key));
+end;
+
+function TRegistry.DeleteValue(const Name: String): Boolean;
+begin
+  Result:=DeleteValue(UnicodeString(Name));
+end;
+
+function TRegistry.GetDataInfo(const ValueName: String; out Value: TRegDataInfo
+  ): Boolean;
+begin
+  Result:=GetDataInfo(UnicodeString(ValueName), Value);
+end;
+
 function TRegistry.GetBaseKey(Relative: Boolean): HKey;
 begin
   If Relative and (CurrentKey<>0) Then
@@ -277,7 +366,7 @@
     Result := RootKey;
 end;
 
-function TRegistry.GetData(const Name: string; Buffer: Pointer; BufSize: Integer; out RegData: TRegDataType): Integer;
+function TRegistry.GetData(const Name: UnicodeString; Buffer: Pointer; BufSize: Integer; out RegData: TRegDataType): Integer;
 begin
   Result:=SysGetData(Name,Buffer,BufSize,RegData);
   If (Result=-1) then
@@ -284,7 +373,24 @@
     Raise ERegistryException.CreateFmt(SRegGetDataFailed, [Name]);
 end;
 
-procedure TRegistry.PutData(const Name: string; Buffer: Pointer;
+function TRegistry.GetData(const Name: String; Buffer: Pointer;
+  BufSize: Integer; out RegData: TRegDataType): Integer;
+begin
+  Result:=GetData(UnicodeString(Name), Buffer, BufSize, RegData);
+end;
+
+function TRegistry.GetKey(Key: String): HKEY;
+begin
+  Result:=GetKey(UnicodeString(Key));
+end;
+
+procedure TRegistry.ChangeKey(Value: HKey; const Path: String);
+begin
+  ChangeKey(Value, UnicodeString(Path));
+end;
+
+
+procedure TRegistry.PutData(const Name: UnicodeString; Buffer: Pointer;
   BufSize: Integer; RegData: TRegDataType);
 
 begin
@@ -292,9 +398,15 @@
     Raise ERegistryException.CreateFmt(SRegSetDataFailed, [Name]);
 end;
 
+procedure TRegistry.PutData(const Name: String; Buffer: Pointer;
+  BufSize: Integer; RegData: TRegDataType);
+begin
+  PutData(UnicodeString(Name), Buffer, BufSize, RegData);
+end;
 
-function TRegistry.GetDataSize(const ValueName: string): Integer;
 
+function TRegistry.GetDataSize(const ValueName: UnicodeString): Integer;
+
 Var
   Info: TRegDataInfo;
 
@@ -305,8 +417,13 @@
     Result := -1;
 end;
 
-function TRegistry.GetDataType(const ValueName: string): TRegDataType;
+function TRegistry.GetDataSize(const ValueName: String): Integer;
+begin
+  Result:=GetDataSize(UnicodeString(ValueName));
+end;
 
+function TRegistry.GetDataType(const ValueName: UnicodeString): TRegDataType;
+
 Var
   Info: TRegDataInfo;
 
@@ -315,6 +432,32 @@
   Result:=Info.RegData;
 end;
 
+function TRegistry.GetDataType(const ValueName: String): TRegDataType;
+begin
+  Result:=GetDataType(UnicodeString(ValueName));
+end;
+
+
+function TRegistry.KeyExists(const Key: String): Boolean;
+begin
+  Result:=KeyExists(UnicodeString(Key));
+end;
+
+function TRegistry.LoadKey(const Key, FileName: String): Boolean;
+begin
+  Result:=LoadKey(UnicodeString(Key), UnicodeString(FileName));
+end;
+
+function TRegistry.OpenKey(const Key: String; CanCreate: Boolean): Boolean;
+begin
+  Result:=OpenKey(UnicodeString(Key), CanCreate);
+end;
+
+function TRegistry.OpenKeyReadOnly(const Key: String): Boolean;
+begin
+  Result:=OpenKeyReadOnly(UnicodeString(Key));
+end;
+
 function TRegistry.HasSubKeys: Boolean;
 
 Var
@@ -326,7 +469,7 @@
     Result:=(Info.NumSubKeys>0);
 end;
 
-function TRegistry.ReadBinaryData(const Name: string; var Buffer; BufSize: Integer): Integer;
+function TRegistry.ReadBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer): Integer;
 
 Var
   RegDataType: TRegDataType;
@@ -337,8 +480,14 @@
     Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
 end;
 
-function TRegistry.ReadInteger(const Name: string): Integer;
+function TRegistry.ReadBinaryData(const Name: String; var Buffer;
+  BufSize: Integer): Integer;
+begin
+  Result:=ReadBinaryData(UnicodeString(Name), Buffer, BufSize);
+end;
 
+function TRegistry.ReadInteger(const Name: UnicodeString): Integer;
+
 Var
   RegDataType: TRegDataType;
 
@@ -348,8 +497,13 @@
     Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
 end;
 
-function TRegistry.ReadInt64(const Name: string): Int64;
+function TRegistry.ReadInteger(const Name: String): Integer;
+begin
+  Result:=ReadInteger(UnicodeString(Name));
+end;
 
+function TRegistry.ReadInt64(const Name: UnicodeString): Int64;
+
 Var
   RegDataType: TRegDataType;
 
@@ -359,21 +513,36 @@
     Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
 end;
 
-function TRegistry.ReadBool(const Name: string): Boolean;
+function TRegistry.ReadInt64(const Name: String): Int64;
+begin
+  Result:=ReadInt64(UnicodeString(Name));
+end;
 
+function TRegistry.ReadBool(const Name: UnicodeString): Boolean;
+
 begin
   Result:=ReadInteger(Name)<>0;
 end;
 
-function TRegistry.ReadCurrency(const Name: string): Currency;
+function TRegistry.ReadBool(const Name: String): Boolean;
+begin
+  Result:=ReadBool(UnicodeString(Name));
+end;
 
+function TRegistry.ReadCurrency(const Name: UnicodeString): Currency;
+
 begin
   Result:=Default(Currency);
   ReadBinaryData(Name, Result, SizeOf(Currency));
 end;
 
-function TRegistry.ReadDate(const Name: string): TDateTime;
+function TRegistry.ReadCurrency(const Name: String): Currency;
+begin
+  Result:=ReadCurrency(UnicodeString(Name));
+end;
 
+function TRegistry.ReadDate(const Name: UnicodeString): TDateTime;
+
 begin
   Result:=Default(TDateTime);
   ReadBinaryData(Name, Result, SizeOf(TDateTime));
@@ -380,22 +549,37 @@
   Result:=Trunc(Result);
 end;
 
-function TRegistry.ReadDateTime(const Name: string): TDateTime;
+function TRegistry.ReadDate(const Name: String): TDateTime;
+begin
+  Result:=ReadDate(UnicodeString(Name));
+end;
 
+function TRegistry.ReadDateTime(const Name: UnicodeString): TDateTime;
+
 begin
   Result:=Default(TDateTime);
   ReadBinaryData(Name, Result, SizeOf(TDateTime));
 end;
 
-function TRegistry.ReadFloat(const Name: string): Double;
+function TRegistry.ReadDateTime(const Name: String): TDateTime;
+begin
+  Result:=ReadDateTime(UnicodeString(Name));
+end;
 
+function TRegistry.ReadFloat(const Name: UnicodeString): Double;
+
 begin
   Result:=Default(Double);
   ReadBinaryData(Name,Result,SizeOf(Double));
 end;
 
-function TRegistry.ReadString(const Name: string): string;
+function TRegistry.ReadFloat(const Name: String): Double;
+begin
+  Result:=ReadFloat(UnicodeString(Name));
+end;
 
+function TRegistry.ReadString(const Name: UnicodeString): UnicodeString;
+
 Var
   Info : TRegDataInfo;
   ReadDataSize: Integer;
@@ -421,47 +605,139 @@
       if StringSizeIncludesNull and
          (u[Length(u)] = WideChar(0)) then
         SetLength(u,Length(u)-1);
-      Result:=UTF8Encode(u);
+      Result:=u;
     end;
   end;
 end;
 
-procedure TRegistry.ReadStringList(const Name: string; AList: TStrings);
+function TRegistry.ReadString(const Name: String): string;
+begin
+  Result:=ReadString(UnicodeString(Name));
+end;
 
+
+procedure TRegistry.ReadStringList(const Name: UnicodeString; AList: TStrings; ForceUtf8: Boolean=False);
+
 Var
+  UArr: TUnicodeStringArray;
+
+begin
+  UArr := ReadStringArray(Name);
+  ArrayToList(UArr, AList, ForceUtf8);
+end;
+
+procedure TRegistry.ReadStringList(const Name: String; AList: TStrings);
+begin
+  ReadStringList(UnicodeString(Name), AList);
+end;
+
+function TRegistry.RegMultiSzDataToUnicodeStringArray(U: UnicodeString): TUnicodeStringArray;
+var
+  Len, i, p: Integer;
+  Sub: UnicodeString;
+begin
+  Result := nil;
+  if (U = '') then Exit;
+  Len := 1;
+  for i := 1 to Length(U) do if (U[i] = #0) then Inc(Len);
+  SetLength(Result, Len);
+  i := 0;
+
+  while (U <> '') and (i < Length(Result)) do
+  begin
+    p := Pos(#0, U);
+    if (p = 0) then p := Length(U) + 1;
+    Sub := Copy(U, 1, p - 1);
+    Result[i] := Sub;
+    System.Delete(U, 1, p);
+    Inc(i);
+  end;
+end;
+
+function TRegistry.ListToArray(List: TStrings; IsUtf8: Boolean): TUnicodeStringArray;
+var
+  i, curr, Len: Integer;
+  u: UnicodeString;
+begin
+  Result := nil;
+  Len := List.Count;
+  SetLength(Result, Len);
+  //REG_MULTI_SZ data cannot contain empty strings
+  curr := 0;
+  for i := 0 to List.Count - 1 do
+  begin
+    if IsUtf8 then
+      u := Utf8Decode(List[i])
+    else
+      u := List[i];
+    if (u>'') then
+    begin
+      Result[curr] := u;
+      inc(curr);
+    end
+    else
+      Dec(Len);
+  end;
+  if (Len <> List.Count) then SetLength(Result, Len);
+end;
+
+procedure TRegistry.ArrayToList(const Arr: TUnicodeStringArray; List: TStrings; ForceUtf8: Boolean);
+var
+  i: Integer;
+begin
+  List.Clear;
+  for i := Low(Arr) to High(Arr) do
+  begin
+    if ForceUtf8 then
+      List.Add(Utf8Encode(Arr[i]))
+    else
+      List.Add(String(Arr[i]));
+  end;
+end;
+
+function TRegistry.ReadStringArray(const Name: UnicodeString): TUnicodeStringArray;
+Var
   Info : TRegDataInfo;
   ReadDataSize: Integer;
-  Data: string;
+  Data: UnicodeString;
 
 begin
-  AList.Clear;
+  Result := nil;
   GetDataInfo(Name,Info);
+  //writeln('TRegistry.ReadStringArray: datasize=',info.datasize);
   if info.datasize>0 then
     begin
      If Not (Info.RegData in [rdMultiString]) then
        Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
      SetLength(Data,Info.DataSize);
-     ReadDataSize := GetData(Name,PChar(Data),Info.DataSize,Info.RegData);
+     ReadDataSize := GetData(Name,PWideChar(Data),Info.DataSize,Info.RegData) div SizeOf(WideChar);
+     //writeln('TRegistry.ReadStringArray: ReadDataSize=',ReadDataSize);
      if ReadDataSize > 0 then
      begin
-       // If the data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type,
-       // the size includes any terminating null character or characters
-       // unless the data was stored without them! (RegQueryValueEx @ MSDN)
-       if StringSizeIncludesNull then begin
-         if Data[ReadDataSize] = #0 then
-           Dec(ReadDataSize);
-         if Data[ReadDataSize] = #0 then
-           Dec(ReadDataSize);
-       end;
+       // Windows returns the data with or without trailing zero's, so just strip all trailing null characters
+        while (Data[ReadDataSize] = #0) do Dec(ReadDataSize);
        SetLength(Data, ReadDataSize);
-       Data := StringReplace(Data, #0, LineEnding, [rfReplaceAll]);
-       AList.Text := Data;
+       //writeln('Data=',dbgs(data));
+       //Data := UnicodeStringReplace(Data, #0, AList.LineBreak, [rfReplaceAll]);
+       //AList.Text := Data;
+       Result := RegMultiSzDataToUnicodeStringArray(Data);
      end
    end
 end;
 
-function TRegistry.ReadTime(const Name: string): TDateTime;
+function TRegistry.ReadStringArray(const Name: String): TStringArray;
+var
+  UArr: TUnicodeStringArray;
+  i: Integer;
+begin
+  Result := nil;
+  UArr := ReadStringArray(UnicodeString(Name));
+  SetLength(Result, Length(UArr));
+  for i := Low(UArr) to High(UArr) do Result[i] := UArr[i];
+end;
 
+function TRegistry.ReadTime(const Name: UnicodeString): TDateTime;
+
 begin
   Result:=Default(TDateTime);
   ReadBinaryData(Name, Result, SizeOf(TDateTime));
@@ -468,85 +744,230 @@
   Result:=Frac(Result);
 end;
 
-procedure TRegistry.WriteBinaryData(const Name: string; var Buffer; BufSize: Integer);
+function TRegistry.ReadTime(const Name: String): TDateTime;
 begin
+  Result:=ReadTime(UnicodeString(Name));
+end;
+
+function TRegistry.RegistryConnect(const UNCName: String): Boolean;
+begin
+  Result:=RegistryConnect(UnicodeString(UNCName));
+end;
+
+function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: String): Boolean;
+begin
+  Result:=ReplaceKey(UnicodeString(Key), UnicodeString(FileName), UnicodeString(BackUpFileName))
+end;
+
+function TRegistry.RestoreKey(const Key, FileName: String): Boolean;
+begin
+  Result:=RestoreKey(UnicodeString(Key), UnicodeString(FileName));
+end;
+
+function TRegistry.SaveKey(const Key, FileName: String): Boolean;
+begin
+  Result:=SaveKey(UnicodeString(Key), UnicodeString(FileName));
+end;
+
+function TRegistry.UnLoadKey(const Key: String): Boolean;
+begin
+  Result:=UnloadKey(UnicodeString(Key));
+end;
+
+function TRegistry.ValueExists(const Name: String): Boolean;
+begin
+  Result:=ValueExists(UnicodeString(Name));
+end;
+
+procedure TRegistry.WriteBinaryData(const Name: UnicodeString; var Buffer; BufSize: Integer);
+begin
   PutData(Name, @Buffer, BufSize, rdBinary);
 end;
 
-procedure TRegistry.WriteBool(const Name: string; Value: Boolean);
+procedure TRegistry.WriteBinaryData(const Name: String; var Buffer;
+  BufSize: Integer);
+begin
+  WriteBinaryData(UnicodeString(Name), Buffer, BufSize);
+end;
 
+procedure TRegistry.WriteBool(const Name: UnicodeString; Value: Boolean);
+
 begin
   WriteInteger(Name,Ord(Value));
 end;
 
-procedure TRegistry.WriteCurrency(const Name: string; Value: Currency);
+procedure TRegistry.WriteBool(const Name: String; Value: Boolean);
 begin
+  WriteBool(UnicodeString(Name), Value);
+end;
+
+procedure TRegistry.WriteCurrency(const Name: UnicodeString; Value: Currency);
+begin
   WriteBinaryData(Name, Value, SizeOf(Currency));
 end;
 
-procedure TRegistry.WriteDate(const Name: string; Value: TDateTime);
+procedure TRegistry.WriteCurrency(const Name: String; Value: Currency);
 begin
+  WriteCurrency(UnicodeString(Name), Value);
+end;
+
+procedure TRegistry.WriteDate(const Name: UnicodeString; Value: TDateTime);
+begin
   WriteBinarydata(Name, Value, SizeOf(TDateTime));
 end;
 
-procedure TRegistry.WriteTime(const Name: string; Value: TDateTime);
+procedure TRegistry.WriteDate(const Name: String; Value: TDateTime);
 begin
+  WriteDate(UnicodeString(Name), Value);
+end;
+
+procedure TRegistry.WriteTime(const Name: UnicodeString; Value: TDateTime);
+begin
   WriteBinaryData(Name, Value, SizeOf(TDateTime));
 end;
 
-procedure TRegistry.WriteDateTime(const Name: string; Value: TDateTime);
+procedure TRegistry.WriteTime(const Name: String; Value: TDateTime);
 begin
+  WriteTime(UnicodeString(Name), Value);
+end;
+
+procedure TRegistry.WriteDateTime(const Name: UnicodeString; Value: TDateTime);
+begin
   WriteBinaryData(Name, Value, SizeOf(TDateTime));
 end;
 
-procedure TRegistry.WriteExpandString(const Name, Value: string);
-var
-  u: UnicodeString;
+procedure TRegistry.WriteDateTime(const Name: String; Value: TDateTime);
+begin
+  WriteDateTime(UnicodeString(Name), Value);
+end;
 
+procedure TRegistry.WriteExpandString(const Name, Value: UnicodeString);
 begin
-  u:=Value;
-  PutData(Name, PWideChar(u), ByteLength(u), rdExpandString);
+  PutData(Name, PWideChar(Value), ByteLength(Value), rdExpandString);
 end;
 
-procedure TRegistry.WriteStringList(const Name: string; List: TStrings);
+procedure TRegistry.WriteExpandString(const Name, Value: String);
+begin
+  WriteExpandString(UnicodeString(Name), UnicodeString(Value));
+end;
 
+
+procedure TRegistry.WriteStringList(const Name: UnicodeString; List: TStrings; IsUtf8: Boolean=False);
+
 Var
-  Data: string;
+  UArr: TUnicodeStringArray;
+begin
+  UArr := ListToArray(List, IsUtf8);
+  WriteStringArray(Name, UArr);
+end;
 
+procedure TRegistry.WriteStringArray(const Name: UnicodeString; const Arr: TUnicodeStringArray);
+Var
+  Data: UnicodeString;
+  u: UnicodeString;
+  i: Integer;
 begin
-  Data := StringReplace(List.Text, LineEnding, #0, [rfReplaceAll]) + #0#0;
-  PutData(Name, PChar(Data), Length(Data),rdMultiString);
+  Data := '';
+  //REG_MULTI_SZ data cannot contain empty strings
+  for i := Low(Arr) to High(Arr) do
+  begin
+    u := Arr[i];
+    if (u>'') then
+    begin
+      if (Data>'') then
+        Data := Data + #0 + u
+      else
+        Data := Data + u;
+    end;
+  end;
+  if StringSizeIncludesNull then
+    Data := Data + #0#0;
+  //writeln('Data=',Dbgs(Data));
+  PutData(Name, PWideChar(Data), ByteLength(Data), rdMultiString);
 end;
 
-procedure TRegistry.WriteFloat(const Name: string; Value: Double);
+procedure TRegistry.WriteStringArray(const Name: String; const Arr: TStringArray);
+var
+  UArr: TUnicodeStringArray;
+  i: Integer;
 begin
+  UArr := nil;
+  SetLength(UArr, Length(Arr));
+  for i := Low(Arr) to High(Arr) do UArr[i] := Arr[i];
+  WriteStringArray(UnicodeString(Name), UArr);
+end;
+
+procedure TRegistry.WriteFloat(const Name: UnicodeString; Value: Double);
+begin
   WriteBinaryData(Name, Value, SizeOf(Double));
 end;
 
-procedure TRegistry.WriteInteger(const Name: string; Value: Integer);
+procedure TRegistry.WriteFloat(const Name: String; Value: Double);
 begin
+  WriteFloat(UnicodeString(Name), Value);
+end;
+
+procedure TRegistry.WriteInteger(const Name: UnicodeString; Value: Integer);
+begin
   PutData(Name, @Value, SizeOf(Integer), rdInteger);
 end;
 
-procedure TRegistry.WriteInt64(const Name: string; Value: Int64);
+procedure TRegistry.WriteInteger(const Name: String; Value: Integer);
 begin
+  WriteInteger(UnicodeString(Name), Value);
+end;
+
+procedure TRegistry.WriteInt64(const Name: UnicodeString; Value: Int64);
+begin
   PutData(Name, @Value, SizeOf(Int64), rdInt64);
 end;
 
-procedure TRegistry.WriteString(const Name, Value: string);
+procedure TRegistry.WriteInt64(const Name: String; Value: Int64);
+begin
+  WriteInt64(UnicodeString(Name), Value);
+end;
+
+procedure TRegistry.WriteString(const Name, Value: UnicodeString);
+begin
+  PutData(Name, PWideChar(Value), ByteLength(Value), rdString);
+end;
+
+procedure TRegistry.WriteString(const Name, Value: String);
+begin
+  WriteString(UnicodeString(Name), UnicodeString(Value));
+end;
+
+procedure TRegistry.GetKeyNames(Strings: TStrings);
 var
-  u: UnicodeString;
+  UArr: TUnicodeStringArray;
+begin
+  UArr := GetKeyNames;
+  ArrayToList(UArr, Strings, True);
+end;
 
+procedure TRegistry.GetValueNames(Strings: TStrings);
+var
+  UArr: TUnicodeStringArray;
 begin
-  u:=Value;
-  PutData(Name, PWideChar(u), ByteLength(u), rdString);
+  UArr := GetValueNames;
+  ArrayToList(UArr, Strings, True);
 end;
 
-procedure TRegistry.MoveKey(const OldName, NewName: string; Delete: Boolean);
+procedure TRegistry.MoveKey(const OldName, NewName: UnicodeString; Delete: Boolean);
 begin
 
 end;
 
+procedure TRegistry.MoveKey(const OldName, NewName: String; Delete: Boolean);
+begin
+  MoveKey(UnicodeString(OldName), UnicodeString(NewName), Delete);
+end;
+
+procedure TRegistry.RenameValue(const OldName, NewName: String);
+begin
+  RenameValue(UnicodeString(OldName), UnicodeString(NewName));
+end;
+
 { ---------------------------------------------------------------------
     Include TRegIniFile implementation
   ---------------------------------------------------------------------}
@@ -583,7 +1004,7 @@
   Value: TStream): Integer;
 begin
   result:=-1; // unimplemented
- // 
+ //
 end;
 
 function TRegistryIniFile.ReadDate(const Section, Name: string;
Index: packages/fcl-registry/src/winreg.inc
===================================================================
--- packages/fcl-registry/src/winreg.inc	(revision 41749)
+++ packages/fcl-registry/src/winreg.inc	(working copy)
@@ -28,7 +28,7 @@
   Dispose(PWinRegData(FSysData));
 end;
 
-Function PrepKey(Const S : String) : String;
+Function PrepKey(Const S : UnicodeString) : UnicodeString;
 
 begin
   Result := S;
@@ -36,7 +36,7 @@
     System.Delete(Result, 1, 1);
 end;
 
-Function RelativeKey(Const S : String) : Boolean;
+Function RelativeKey(Const S : UnicodeString) : Boolean;
 
 begin
   Result:=(S='') or (S[1]<>'\')
@@ -43,9 +43,8 @@
 end;
 
 
-function TRegistry.sysCreateKey(const Key: String): Boolean;
+function TRegistry.sysCreateKey(Key: UnicodeString): Boolean;
 Var
-  u: UnicodeString;
   Disposition: Dword;
   Handle: HKEY;
   SecurityAttributes: Pointer; //LPSECURITY_ATTRIBUTES;
@@ -52,9 +51,9 @@
 
 begin
   SecurityAttributes := Nil;
-  u:=PrepKey(Key);
+  Key:=PrepKey(Key);
   FLastError:=RegCreateKeyExW(GetBaseKey(RelativeKey(Key)),
-                              PWideChar(u),
+                              PWideChar(Key),
                               0,
                               '',
                               REG_OPTION_NON_VOLATILE,
@@ -66,7 +65,7 @@
   RegCloseKey(Handle);
 end;
 
-function TRegistry.DeleteKey(const Key: String): Boolean;
+function TRegistry.DeleteKey(const Key: UnicodeString): Boolean;
 
 Var
   u: UnicodeString;
@@ -76,21 +75,21 @@
   Result:=FLastError=ERROR_SUCCESS;
 end;
 
-function TRegistry.DeleteValue(const Name: String): Boolean;
+
+function TRegistry.DeleteValue(const Name: UnicodeString): Boolean;
 begin
-  FLastError:= RegDeleteValueW(fCurrentKey, PWideChar(UnicodeString(Name)));
+  FLastError:= RegDeleteValueW(fCurrentKey, PWideChar(Name));
   Result:=FLastError=ERROR_SUCCESS;
 end;
 
-function TRegistry.SysGetData(const Name: String; Buffer: Pointer;
+
+function TRegistry.SysGetData(const Name: UnicodeString; Buffer: Pointer;
           BufSize: Integer; Out RegData: TRegDataType): Integer;
 Var
-  u: UnicodeString;
   RD : DWord;
 
 begin
-  u := Name;
-  FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(u),Nil,
+  FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(Name),Nil,
                       @RD,Buffer,lpdword(@BufSize));
   if (FLastError<>ERROR_SUCCESS) Then
     Result:=-1
@@ -103,17 +102,15 @@
     end;
 end;
 
-function TRegistry.GetDataInfo(const ValueName: String; out Value: TRegDataInfo): Boolean;
+function TRegistry.GetDataInfo(const ValueName: UnicodeString; out Value: TRegDataInfo): Boolean;
 
 Var
-  u: UnicodeString;
   RD : DWord;
 
 begin
-  u:=ValueName;
   With Value do
     begin
-    FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(u),Nil,lpdword(@RegData),Nil,lpdword(@DataSize));
+    FLastError:=RegQueryValueExW(fCurrentKey,PWideChar(ValueName),Nil,lpdword(@RegData),Nil,lpdword(@DataSize));
     Result:=FLastError=ERROR_SUCCESS;
     if Result then
       begin
@@ -131,24 +128,18 @@
 end;
 
 
-function TRegistry.GetKey(const Key: String): HKEY;
+function TRegistry.GetKey(Key: UnicodeString): HKEY;
 var
-  S : string;
-{$ifndef WinCE}
-  u : UnicodeString;
-{$endif}
   Rel : Boolean;
 begin
   Result:=0;
-  S:=Key;
-  Rel:=RelativeKey(S);
+  Rel:=RelativeKey(Key);
   if not(Rel) then
-    Delete(S,1,1);
+    Delete(Key,1,1);
 {$ifdef WinCE}
-  FLastError:=RegOpenKeyEx(GetBaseKey(Rel),PWideChar(WideString(S)),0,FAccess,Result);
+  FLastError:=RegOpenKeyEx(GetBaseKey(Rel),PWideChar(Key),0,FAccess,Result);
 {$else WinCE}
-  u:=UnicodeString(S);
-  FLastError:=RegOpenKeyExW(GetBaseKey(Rel),PWideChar(u),0,FAccess,Result);
+  FLastError:=RegOpenKeyExW(GetBaseKey(Rel),PWideChar(Key),0,FAccess,Result);
 {$endif WinCE}
 end;
 
@@ -174,7 +165,7 @@
 end;
 
 
-function TRegistry.KeyExists(const Key: string): Boolean;
+function TRegistry.KeyExists(const Key: UnicodeString): Boolean;
 var
   KeyHandle : HKEY;
   OldAccess : LONG;
@@ -196,20 +187,20 @@
 end;
 
 
-function TRegistry.LoadKey(const Key, FileName: string): Boolean;
+function TRegistry.LoadKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
 
-function TRegistry.OpenKey(const Key: string; CanCreate: Boolean): Boolean;
 
+function TRegistry.OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
+
 Var
-  u: UnicodeString;
+  u, S: UnicodeString;
   Handle: HKEY;
   Disposition: Integer;
   SecurityAttributes: Pointer; //LPSECURITY_ATTRIBUTES;
-  S: string;
 begin
   SecurityAttributes := Nil;
   u:=PrepKey(Key);
@@ -232,13 +223,14 @@
     if RelativeKey(Key) then
       S:=CurrentPath + Key
     else
-      S:=UTF8Encode(u);
+      S:=u;
     ChangeKey(Handle, S);
   end;
 end;
 
-function TRegistry.OpenKeyReadOnly(const Key: string): Boolean;
 
+function TRegistry.OpenKeyReadOnly(const Key: UnicodeString): Boolean;
+
 Var
   OldAccess: LongWord;
 begin
@@ -251,7 +243,8 @@
   end;
 end;
 
-function TRegistry.RegistryConnect(const UNCName: string): Boolean;
+
+function TRegistry.RegistryConnect(const UNCName: UnicodeString): Boolean;
 {$ifndef WinCE}
 var
   newroot: HKEY;
@@ -260,7 +253,7 @@
 {$ifdef WinCE}
   Result:=False;
 {$else}
-  FLastError:=RegConnectRegistryW(PWideChar(UnicodeString(UNCName)),RootKey,newroot);
+  FLastError:=RegConnectRegistryW(PWideChar(UNCName),RootKey,newroot);
   Result:=FLastError=ERROR_SUCCESS;
   if Result then begin
     RootKey:=newroot;
@@ -269,28 +262,33 @@
 {$endif}
 end;
 
-function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
+
+function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.RestoreKey(const Key, FileName: string): Boolean;
+
+function TRegistry.RestoreKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.SaveKey(const Key, FileName: string): Boolean;
+
+function TRegistry.SaveKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.UnLoadKey(const Key: string): Boolean;
+
+function TRegistry.UnLoadKey(const Key: UnicodeString): Boolean;
 begin
   Result := false;
 end;
 
-function TRegistry.ValueExists(const Name: string): Boolean;
 
+function TRegistry.ValueExists(const Name: UnicodeString): Boolean;
+
 var
   Info : TRegDataInfo;
 
@@ -298,6 +296,7 @@
   Result:=GetDataInfo(Name,Info);
 end;
 
+
 procedure TRegistry.CloseKey;
 begin
   If (CurrentKey<>0) then
@@ -316,7 +315,7 @@
   RegCloseKey(key);
 end;
 
-procedure TRegistry.ChangeKey(Value: HKey; const Path: String);
+procedure TRegistry.ChangeKey(Value: HKey; const Path: UnicodeString);
 begin
   CloseKey;
   FCurrentKey:=Value;
@@ -323,8 +322,9 @@
   FCurrentPath:=Path;
 end;
 
-procedure TRegistry.GetKeyNames(Strings: TStrings);
 
+function TRegistry.GetKeyNames: TUnicodeStringArray;
+
 var
   Info:    TRegKeyInfo;
   dwLen:   DWORD;
@@ -331,15 +331,17 @@
   lpName:  LPWSTR;
   dwIndex: DWORD;
   lResult: LONGINT;
-  s:       string;
+  u:       UnicodeString;
 
 begin
-  Strings.Clear;
+  Result:=nil;
   if GetKeyInfo(Info) then
   begin
     dwLen:=Info.MaxSubKeyLen+1;
     GetMem(lpName,dwLen*SizeOf(WideChar));
     try
+      //writeln('TRegistry.GetKeyNames: Info.NumSubKeys=',Info.NumSubKeys);
+      SetLength(Result, Info.NumSubKeys);
       for dwIndex:=0 to Info.NumSubKeys-1 do
       begin
         dwLen:=Info.MaxSubKeyLen+1;
@@ -347,19 +349,13 @@
         if lResult<>ERROR_SUCCESS then
           raise ERegistryException.Create(SysErrorMessage(lResult));
         if dwLen=0 then
-          s:=''
+          u:=''
         else
         begin           // dwLen>0
-          SetLength(s,dwLen*3);
-          dwLen:=UnicodeToUTF8(PChar(s),Length(s)+1,lpName,dwLen);
-          if dwLen<=1 then
-            s:=''
-          else          // dwLen>1
-            SetLength(s,dwLen-1);
+          u:=lpName;
         end;            // if dwLen=0
-        Strings.Add(s);
+        Result[dwIndex]:=u;
       end;              // for dwIndex:=0 ...
-
     finally
       FreeMem(lpName);
     end;
@@ -366,8 +362,9 @@
   end;
 end;
 
-procedure TRegistry.GetValueNames(Strings: TStrings);
 
+Function TRegistry.GetValueNames: TUnicodeStringArray;
+
 var
   Info:    TRegKeyInfo;
   dwLen:   DWORD;
@@ -374,15 +371,16 @@
   lpName:  LPWSTR;
   dwIndex: DWORD;
   lResult: LONGINT;
-  s:       string;
+  u:       UnicodeString;
 
 begin
-   Strings.Clear;
+  Result:=nil;
   if GetKeyInfo(Info) then
   begin
     dwLen:=Info.MaxValueLen+1;
     GetMem(lpName,dwLen*SizeOf(WideChar));
     try
+      SetLength(Result, Info.NumValues);
       for dwIndex:=0 to Info.NumValues-1 do
       begin
         dwLen:=Info.MaxValueLen+1;
@@ -390,17 +388,12 @@
         if lResult<>ERROR_SUCCESS then
           raise ERegistryException.Create(SysErrorMessage(lResult));
         if dwLen=0 then
-          s:=''
+          u:=''
         else
         begin           // dwLen>0
-          SetLength(s,dwLen*3);
-          dwLen:=UnicodeToUTF8(PChar(s),Length(s)+1,lpName,dwLen);
-          if dwLen<=1 then
-            s:=''
-          else          // dwLen>1
-            SetLength(s,dwLen-1);
+          u:=lpName;
         end;            // if dwLen=0
-        Strings.Add(s);
+        Result[dwIndex]:=u;
       end;              // for dwIndex:=0 ...
 
     finally
@@ -410,12 +403,11 @@
 end;
 
 
-Function TRegistry.SysPutData(const Name: string; Buffer: Pointer;
+Function TRegistry.SysPutData(const Name: UnicodeString; Buffer: Pointer;
   BufSize: Integer; RegData: TRegDataType) : Boolean;
 
 
 Var
-  u: UnicodeString;
   RegDataType: DWORD;
   B : Pchar;
   S : String;
@@ -422,12 +414,11 @@
 
 begin
   RegDataType:=RegDataWords[RegData];
-  u:=UnicodeString(Name);
-  FLastError:=RegSetValueExW(fCurrentKey,PWideChar(u),0,RegDataType,Buffer,BufSize);
+  FLastError:=RegSetValueExW(fCurrentKey,PWideChar(Name),0,RegDataType,Buffer,BufSize);
   Result:=FLastError=ERROR_SUCCESS;
 end;
 
-procedure TRegistry.RenameValue(const OldName, NewName: string);
+procedure TRegistry.RenameValue(const OldName, NewName: UnicodeString);
 
 var
   L: Integer;
Index: packages/fcl-registry/src/xmlreg.pp
===================================================================
--- packages/fcl-registry/src/xmlreg.pp	(revision 41749)
+++ packages/fcl-registry/src/xmlreg.pp	(working copy)
@@ -25,6 +25,7 @@
     FTime     : TDateTime;
   end;
 
+  TUnicodeStringArray = Array of UnicodeString;
 
   { TXmlRegistry }
 
@@ -33,24 +34,24 @@
     FAutoFlush,
     FDirty : Boolean;
     FFileName : String;
-    FRootKey : String;
+    FRootKey : UnicodeString;
     FDocument : TXMLDocument;
     FCurrentElement : TDomElement;
-    FCurrentKey : String;
+    FCurrentKey : UnicodeString;
     Procedure SetFileName(Value : String);
   Protected
-    function DoGetValueData(Name: String; out DataType: TDataType; Var Data; Var DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
-    function DoSetValueData(Name: String; DataType: TDataType; const Data; DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
+    function DoGetValueData(Name: UnicodeString; out DataType: TDataType; Var Data; Var DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
+    function DoSetValueData(Name: UnicodeString; DataType: TDataType; const Data; DataSize: Integer; IsUnicode: Boolean): Boolean; virtual;
     Procedure LoadFromStream(S : TStream);
-    Function  NormalizeKey(KeyPath : String) : String;
+    Function  NormalizeKey(KeyPath : UnicodeString) : UnicodeString;
     Procedure CreateEmptyDoc;
-    Function  FindKey (S : String) : TDomElement;
-    Function  FindSubKey (S : String; N : TDomElement) : TDomElement;
-    Function  CreateSubKey (S : String; N : TDomElement) : TDomElement;
-    Function  FindValueKey (S : String) : TDomElement;
-    Function  CreateValueKey (S : String) : TDomElement;
+    Function  FindKey (S : UnicodeString) : TDomElement;
+    Function  FindSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
+    Function  CreateSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
+    Function  FindValueKey (S : UnicodeString) : TDomElement;
+    Function  CreateValueKey (S : UnicodeString) : TDomElement;
     Function  BufToHex(Const Buf; Len : Integer) : String;
-    Function  hexToBuf(Const Str : String; Var Buf; Var Len : Integer ) : Integer;
+    Function  HexToBuf(Const Str : UnicodeString; Var Buf; Var Len : Integer ) : Integer;
     Procedure MaybeFlush;
     Property  Document : TXMLDocument Read FDocument;
     Property  Dirty : Boolean Read FDirty write FDirty;
@@ -57,29 +58,31 @@
   Public
     Constructor Create(AFileName : String);
     Destructor  Destroy;override;
-    Function  SetKey(KeyPath : String; AllowCreate : Boolean) : Boolean ;
-    Procedure SetRootKey(Value : String);
-    Function  DeleteKey(KeyPath : String) : Boolean;
-    Function  CreateKey(KeyPath : String) : Boolean;
-    Function  GetValueSize(Name : String) : Integer;
-    Function  GetValueType(Name : String) : TDataType;
-    Function  GetValueInfo(Name : String; Out Info : TDataInfo; AsUnicode : Boolean = False) : Boolean;
+    Function  SetKey(KeyPath : UnicodeString; AllowCreate : Boolean) : Boolean ;
+    Procedure SetRootKey(Value : UnicodeString);
+    Function  DeleteKey(KeyPath : UnicodeString) : Boolean;
+    Function  CreateKey(KeyPath : UnicodeString) : Boolean;
+    Function  GetValueSize(Name : UnicodeString) : Integer;
+    Function  GetValueType(Name : UnicodeString) : TDataType;
+    Function  GetValueInfo(Name : UnicodeString; Out Info : TDataInfo; AsUnicode : Boolean = False) : Boolean;
     Function  GetKeyInfo(Out Info : TKeyInfo) : Boolean;
     Function  EnumSubKeys(List : TStrings) : Integer;
+    Function  EnumSubKeys: TUnicodeStringArray;
     Function  EnumValues(List : TStrings) : Integer;
-    Function  KeyExists(KeyPath : String) : Boolean;
-    Function  ValueExists(ValueName : String) : Boolean;
-    Function  RenameValue(Const OldName,NewName : String) : Boolean;
-    Function  DeleteValue(S : String) : Boolean;
+    Function  EnumValues: TUnicodeStringArray;
+    Function  KeyExists(KeyPath : UnicodeString) : Boolean;
+    Function  ValueExists(ValueName : UnicodeString) : Boolean;
+    Function  RenameValue(Const OldName,NewName : UnicodeString) : Boolean;
+    Function  DeleteValue(S : UnicodeString) : Boolean;
     Procedure Flush;
     Procedure Load;
-    Function GetValueData(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
-    Function SetValueData(Name : String; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
+    Function GetValueData(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
+    Function SetValueData(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
     // These interpret the Data buffer as unicode data
-    Function GetValueDataUnicode(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
-    Function SetValueDataUnicode(Name : String; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
+    Function GetValueDataUnicode(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
+    Function SetValueDataUnicode(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
     Property FileName : String Read FFileName Write SetFileName;
-    Property RootKey : String Read FRootKey Write SetRootkey;
+    Property RootKey : UnicodeString Read FRootKey Write SetRootkey;
     Property AutoFlush : Boolean Read FAutoFlush Write FAutoFlush;
   end;
 
@@ -143,13 +146,13 @@
   end;
 end;
 
-Function TXmlRegistry.NormalizeKey(KeyPath : String) : String;
+Function TXmlRegistry.NormalizeKey(KeyPath : UnicodeString) : UnicodeString;
 
 Var
   L : Integer;
 
 begin
-  Result:=StringReplace(KeyPath,'\','/',[rfReplaceAll]);
+  Result:=UnicodeStringReplace(KeyPath,'\','/',[rfReplaceAll]);
   L:=Length(Result);
   If (L>0) and (Result[L]<>'/') then
     Result:=Result+'/';
@@ -157,10 +160,10 @@
     Result:='/' + Result;
 end;
 
-Function TXmlRegistry.SetKey(KeyPath : String; AllowCreate : Boolean) : boolean;
+Function TXmlRegistry.SetKey(KeyPath : UnicodeString; AllowCreate : Boolean) : boolean;
 
 Var
-  SubKey,ResultKey : String;
+  SubKey,ResultKey : UnicodeString;
   P : Integer;
   Node,Node2 : TDomElement;
 
@@ -218,7 +221,7 @@
   MaybeFlush;
 end;
 
-Procedure TXmlRegistry.SetRootKey(Value : String);
+Procedure TXmlRegistry.SetRootKey(Value : UnicodeString);
 
 begin
   FRootKey:=NormalizeKey(Value);
@@ -228,7 +231,7 @@
   FCurrentElement:=Nil;
 end;
 
-Function TXmlRegistry.DeleteKey(KeyPath : String) : Boolean;
+Function TXmlRegistry.DeleteKey(KeyPath : UnicodeString) : Boolean;
 
 Var
   N : TDomElement;
@@ -244,10 +247,10 @@
    end;
 end;
 
-Function TXmlRegistry.CreateKey(KeyPath : String) : Boolean;
+Function TXmlRegistry.CreateKey(KeyPath : UnicodeString) : Boolean;
 
 Var
-  SubKey : String;
+  SubKey : UnicodeString;
   P : Integer;
   Node,Node2 : TDomElement;
 
@@ -290,7 +293,7 @@
   MaybeFlush;
 end;
 
-Function TXmlRegistry.DoGetValueData(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer; IsUnicode : Boolean) : Boolean;
+Function TXmlRegistry.DoGetValueData(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer; IsUnicode : Boolean) : Boolean;
 
 Type
   PCardinal = ^Cardinal;
@@ -305,22 +308,27 @@
   D : DWord;
   
 begin
+  //writeln('TXmlRegistry.DoGetValueData: Name=',Name,' IsUnicode=',IsUnicode);
   Node:=FindValueKey(Name);
   Result:=Node<>Nil;
   If Result then
     begin
+    //writeln('TXmlRegistry.DoGetValueData: Node<>nil');
     DataNode:=Node.FirstChild;
     HasData:=Assigned(DataNode) and (DataNode.NodeType=TEXT_NODE);
-    ND:=StrToIntDef(Node[Stype],0);
+    //writeln('TXmlRegistry.DoGetValueData: HasData=',hasdata);
+    ND:=StrToIntDef(String(Node[Stype]),0);
+    //writeln('TXmlRegistry.DoGetValueData: ND=',ND);
     Result:=ND<=Ord(High(TDataType));
     If Result then
       begin
       DataType:=TDataType(ND);
+      //writeln('TXmlRegistry.DoGetValueData: DataType=',DataType);
       NS:=0; // Initialize, for optional nodes.
       Case DataType of
         dtDWORD : begin   // DataNode is required
                   NS:=SizeOf(Cardinal);
-                  Result:=HasData and TryStrToDWord(DataNode.NodeValue,D) and (DataSize>=NS);
+                  Result:=HasData and TryStrToDWord(String(DataNode.NodeValue),D) and (DataSize>=NS);
                   if Result then
                     PCardinal(@Data)^:=D;
                   end;
@@ -329,7 +337,7 @@
                      begin
                      if not IsUnicode then
                        begin
-                       S:=UTF8Encode(DataNode.NodeValue); // Convert to ansistring
+                       S:=DataNode.NodeValue; // Convert to ansistring
                        NS:=Length(S);
                        Result:=(DataSize>=NS);
                        if Result then
@@ -350,8 +358,10 @@
                    if HasData then
                      begin
                      BL:=Length(DataNode.NodeValue);
+                     //writeln('TXmlRegistry.DoGetValueData: BL=',BL);
                      NS:=BL div 2;
                      Result:=DataSize>=NS;
+                     //writeln('TXmlRegistry.DoGetValueData: Result=',Result);
                      If Result then
                        // No need to check for -1, We checked NS before calling.
                        NS:=HexToBuf(DataNode.NodeValue,Data,BL);
@@ -363,7 +373,7 @@
     end;
 end;
 
-Function TXmlRegistry.DoSetValueData(Name : String; DataType : TDataType; Const Data; DataSize : Integer; IsUnicode : Boolean) : Boolean;
+Function TXmlRegistry.DoSetValueData(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer; IsUnicode : Boolean) : Boolean;
 
 Type
   PCardinal = ^Cardinal;
@@ -374,6 +384,7 @@
   SW : UnicodeString;
 
 begin
+  //writeln('TXmlRegistry.DoSetValueData A: Name=',Name,', DataType=',DataType,', DataSize=',DataSize,', IsUnicode=',IsUnicode);
   Node:=FindValueKey(Name);
   If Node=Nil then
     Node:=CreateValueKey(Name);
@@ -380,20 +391,20 @@
   Result:=(Node<>Nil);
   If Result then
     begin
-    Node[SType]:=IntToStr(Ord(DataType));
+    Node[SType]:=UnicodeString(IntToStr(Ord(DataType)));
     DataNode:=Node.FirstChild;
 
     Case DataType of
-      dtDWORD : SW:=IntToStr(PCardinal(@Data)^);
+      dtDWORD : SW:=UnicodeString(IntToStr(PCardinal(@Data)^));
       dtString : begin
                  if IsUnicode then
                    SW:=UnicodeString(PUnicodeChar(@Data))
                  else
                    SW:=UnicodeString(PAnsiChar(@Data));
-                   //S:=UTF8Encode(SW);
+                   //S:=SW;
                  end;
-      dtBinary : SW:=BufToHex(Data,DataSize);
-      dtStrings : SW:=BufToHex(Data,DataSize);
+      dtBinary : SW:=UnicodeString(BufToHex(Data,DataSize));
+      dtStrings : SW:=UnicodeString(BufToHex(Data,DataSize));
     else
       sw:='';
     end;
@@ -416,29 +427,29 @@
     end;
 end;
 
-Function TXmlRegistry.SetValueData(Name : String; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
+Function TXmlRegistry.SetValueData(Name : UnicodeString; DataType : TDataType; Const Data; DataSize : Integer) : Boolean;
 
 begin
   Result:=DoSetValueData(Name,DataType,Data,DataSize,False);
 end;
 
-Function TXmlRegistry.GetValueData(Name : String; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
+Function TXmlRegistry.GetValueData(Name : UnicodeString; Out DataType : TDataType; Var Data; Var DataSize : Integer) : Boolean;
 
 begin
   Result:=DoGetValueData(Name,DataType,Data,DataSize,False);
 end;
 
-function TXmlRegistry.GetValueDataUnicode(Name: String; out DataType: TDataType; Var Data; Var DataSize: Integer): Boolean;
+function TXmlRegistry.GetValueDataUnicode(Name: UnicodeString; out DataType: TDataType; Var Data; Var DataSize: Integer): Boolean;
 begin
   Result:=DoGetValueData(Name,DataType,Data,DataSize,True);
 end;
 
-function TXmlRegistry.SetValueDataUnicode(Name: String; DataType: TDataType; const Data; DataSize: Integer): Boolean;
+function TXmlRegistry.SetValueDataUnicode(Name: UnicodeString; DataType: TDataType; const Data; DataSize: Integer): Boolean;
 begin
   Result:=DoSetValueData(Name,DataType,Data,DataSize,True)
 end;
 
-Function TXmlRegistry.FindSubKey (S : String; N : TDomElement) : TDomElement;
+Function TXmlRegistry.FindSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
 
 Var
   Node : TDOMNode;
@@ -451,7 +462,7 @@
     While (Result=Nil) and (Assigned(Node)) do
       begin
       If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SKey) then
-        If CompareText(TDomElement(Node)[SName],S)=0 then
+        If UnicodeCompareText(TDomElement(Node)[SName],S)=0 then
           Result:=TDomElement(Node);
       Node:=Node.NextSibling;
       end;
@@ -458,7 +469,7 @@
     end;
 end;
 
-Function TXmlRegistry.CreateSubKey (S : String; N : TDomElement) : TDomElement;
+Function TXmlRegistry.CreateSubKey (S : UnicodeString; N : TDomElement) : TDomElement;
 
 begin
   Result:=FDocument.CreateElement(SKey);
@@ -468,7 +479,7 @@
   FDirty:=True;
 end;
 
-Function  TXmlRegistry.FindValueKey (S : String) : TDomElement;
+Function  TXmlRegistry.FindValueKey (S : UnicodeString) : TDomElement;
 
 Var
   Node : TDOMNode;
@@ -481,7 +492,7 @@
     While (Result=Nil) and (Assigned(Node)) do
       begin
       If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SValue) then
-        If CompareText(TDomElement(Node)[SName],S)=0 then
+        If UnicodeCompareText(TDomElement(Node)[SName],S)=0 then
           Result:=TDomElement(Node);
       Node:=Node.NextSibling;
       end;
@@ -488,7 +499,7 @@
     end;
 end;
 
-Function  TXmlRegistry.CreateValueKey (S : String) : TDomElement;
+Function  TXmlRegistry.CreateValueKey (S : UnicodeString) : TDomElement;
 
 begin
   If Assigned(FCurrentElement) then
@@ -581,38 +592,47 @@
     end;
 end;
 
-Function TXMLRegistry.hexToBuf(Const Str : String; Var Buf; Var Len : Integer ) : Integer;
+Function TXMLRegistry.HexToBuf(Const Str : UnicodeString; Var Buf; Var Len : Integer ) : Integer;
 
 Var
   NLeN,I : Integer;
   P : PByte;
-  S : String;
+  S : UnicodeString;
   B : Byte;
   Code : Integer;
 
 begin
+  //writeln('TXMLRegistry.HexToBuf A: Str=',Str,', Len=',Len);
   Result:=0;
   P:=@Buf;
+  //writeln('TXMLRegistry.HexToBuf B: (p=nil)=',p=nil);
   NLen:= Length(Str) div 2;
+  //writeln('TXMLRegistry.HexToBuf C: NLen=',NLen,', SizeOf(TDateTime)=',SizeOf(TDateTime));
   If (NLen>Len) then
     begin
     Len:=NLen;
     Exit(-1);
     end;
-  For I:=0 to Len-1 do
+  For I:=0 to NLen-1 do
     begin
+    //write('TXMLRegistry.HexToBuf: i=',i);
     S:='$'+Copy(Str,(I*2)+1,2);
+    //write(', S=',S);
     Val(S,B,Code);
+    //writeln(', Code=',Code);
     If Code<>0 then
-      begin
-      Inc(Result);
-      B:=0;
+      begin    //This means invalid data in the registry, why continue and increment result? Why not Exit(-1)?
+      //Inc(Result);   //the whole function only worked because this was called as often as when Code=0, so by change
+      //B:=0;          //it causes AV's
+      Exit(-1);
       end;
+    Inc(Result);
     P[I]:=B;
     end;
+  //writeln('TXMLRegistry.HexToBuf End: Result=',Result);
 end;
 
-Function TXMLRegistry.DeleteValue(S : String) : Boolean;
+Function TXMLRegistry.DeleteValue(S : UnicodeString) : Boolean;
 
 Var
   N : TDomElement;
@@ -628,31 +648,31 @@
     end;
 end;
 
-Function TXMLRegistry.GetValueSize(Name : String) : Integer;
+Function TXMLRegistry.GetValueSize(Name : UnicodeString) : Integer;
 
 Var
   Info : TDataInfo;
 
 begin
-  If GetValueInfo(Name,Info) then
+  If GetValueInfo(Name,Info,True) then
     Result:=Info.DataSize
   else
     Result:=-1;
 end;
 
-Function TXMLRegistry.GetValueType(Name : String) : TDataType;
+Function TXMLRegistry.GetValueType(Name : UnicodeString) : TDataType;
 
 Var
   Info : TDataInfo;
 
 begin
-  If GetValueInfo(Name,Info) then
+  If GetValueInfo(Name,Info,True) then
     Result:=Info.DataType
   else
     Result:=dtUnknown;
 end;
 
-function TXmlRegistry.GetValueInfo(Name: String; out Info: TDataInfo; AsUnicode: Boolean): Boolean;
+function TXmlRegistry.GetValueInfo(Name: UnicodeString; out Info: TDataInfo; AsUnicode: Boolean): Boolean;
 
 Var
   N  : TDomElement;
@@ -671,7 +691,7 @@
         L:=Length(DN.NodeValue)*SizeOf(UnicodeChar)
       else
         begin
-        S := UTF8Encode(DN.NodeValue);
+        S := DN.NodeValue;
         L:=Length(S);
         end
       end
@@ -679,7 +699,7 @@
       L:=0;
     With Info do
       begin
-      DataType:=TDataType(StrToIntDef(N[SType],0));
+      DataType:=TDataType(StrToIntDef(String(N[SType]),0));
       Case DataType of
         dtUnknown : DataSize:=0;
         dtDword   : Datasize:=SizeOf(Cardinal);
@@ -724,10 +744,10 @@
               ValueLen:=L;
             DataNode:=TDomElement(Node).FirstChild;
             If (DataNode<>Nil) and (DataNode is TDomText) then
-              Case TDataType(StrToIntDef(TDomElement(Node)[SType],0)) of
+              Case TDataType(StrToIntDef(String(TDomElement(Node)[SType]),0)) of
                 dtUnknown : L:=0;
                 dtDWord   : L:=4;
-                DtString  : L:=Length(UTF8Encode(DataNode.NodeValue));
+                DtString  : L:=Length(String(DataNode.NodeValue));
                 dtBinary  : L:=Length(DataNode.NodeValue) div 2;
               end
             else
@@ -761,6 +781,37 @@
     end;
 end;
 
+function TXmlRegistry.EnumSubKeys: TUnicodeStringArray;
+
+Var
+  Node : TDOMNode;
+  Len, Count: Integer;
+
+begin
+  Result:=nil;
+  If FCurrentElement<>Nil then
+    begin
+    Node:=FCurrentElement.FirstChild;
+    Len:=0;
+    Count:=0;
+    While Assigned(Node) do
+      begin
+      If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SKey) then
+        begin
+        Inc(Count);
+        if (Count>Len) then
+          begin
+          Inc(Len,10); //avoid calling SetLength on each addition
+          SetLength(Result,Len);
+          end;
+        Result[Count-1]:=TDomElement(Node)[SName];
+        end;
+      Node:=Node.NextSibling;
+      end;
+    SetLength(Result,Count);
+    end;
+end;
+
 Function TXMLRegistry.EnumValues(List : TStrings) : Integer;
 
 Var
@@ -775,7 +826,8 @@
     While Assigned(Node) do
       begin
       If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SValue) then
-        List.Add(TDomElement(Node)[SName]);
+        If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SValue) then
+          List.Add(TDomElement(Node)[SName]);
       Node:=Node.NextSibling;
       end;
     Result:=List.Count;
@@ -782,13 +834,44 @@
     end;
 end;
 
-Function TXMLRegistry.KeyExists(KeyPath : String) : Boolean;
+Function TXMLRegistry.EnumValues: TUnicodeStringArray;
 
+Var
+  Node : TDOMNode;
+  Len, Count: Integer;
 begin
+  Result:=nil;
+  If FCurrentElement<>Nil then
+    begin
+    Node:=FCurrentElement.FirstChild;
+    Count:=0;
+    Len:=0;
+    While Assigned(Node) do
+      begin
+      If (Node.NodeType=ELEMENT_NODE) and (Node.NodeName=SValue) then
+        begin
+        Inc(Count);
+        if (Count>Len) then
+          begin
+          Inc(Len,10); //avoid calling SetLength on each addition
+          SetLength(Result,Len);
+          end;
+        Result[Count-1]:=TDomElement(Node)[SName];
+        end;
+      Node:=Node.NextSibling;
+      end;
+    SetLength(Result,Count);
+    end;
+end;
+
+
+Function TXMLRegistry.KeyExists(KeyPath : UnicodeString) : Boolean;
+
+begin
   Result:=FindKey(KeyPath)<>Nil;
 end;
 
-Function TXMLRegistry.RenameValue(Const OldName,NewName : String) : Boolean;
+Function TXMLRegistry.RenameValue(Const OldName,NewName : UnicodeString) : Boolean;
 
 Var
   N : TDomElement;
@@ -804,10 +887,10 @@
     end;
 end;
 
-Function TXMLRegistry.FindKey (S : String) : TDomElement;
+Function TXMLRegistry.FindKey (S : UnicodeString) : TDomElement;
 
 Var
-  SubKey : String;
+  SubKey : UnicodeString;
   P : Integer;
   Node : TDomElement;
 
@@ -840,7 +923,7 @@
   Until (Result=Nil) or (Length(S)=0);
 end;
 
-Function  TXmlRegistry.ValueExists(ValueName : String) : Boolean;
+Function  TXmlRegistry.ValueExists(ValueName : UnicodeString) : Boolean;
 
 begin
   Result:=FindValueKey(ValueName)<>Nil;
Index: packages/fcl-registry/src/xregreg.inc
===================================================================
--- packages/fcl-registry/src/xregreg.inc	(revision 41749)
+++ packages/fcl-registry/src/xregreg.inc	(working copy)
@@ -116,7 +116,11 @@
 procedure TRegistry.SysRegCreate;
 var s : string;
 begin
+  FStringSizeIncludesNull:=False;
   s:=includetrailingpathdelimiter(GetAppConfigDir(GlobalXMLFile));
+  {$ifdef XMLRegfile_in_CurDir}
+  s:='.' + PathDelim;
+  {$endif}
   ForceDirectories(s);
   FSysData:=TXMLRegistryInstance.GetXMLRegistry(s+XFileName);
   TXmlRegistry(FSysData).AutoFlush:=False;
@@ -130,24 +134,24 @@
   TXMLRegistryInstance.FreeXMLRegistry(TXMLRegistry(FSysData));
 end;
 
-function TRegistry.SysCreateKey(const Key: String): Boolean;
+function TRegistry.SysCreateKey(Key: UnicodeString): Boolean;
 
 begin
   Result:=TXmlRegistry(FSysData).CreateKey(Key);
 end;
 
-function TRegistry.DeleteKey(const Key: string): Boolean;
+function TRegistry.DeleteKey(const Key: UnicodeString): Boolean;
 
 begin
   Result:=TXMLRegistry(FSysData).DeleteKey(Key);
 end;
 
-function TRegistry.DeleteValue(const Name: string): Boolean;
+function TRegistry.DeleteValue(const Name: UnicodeString): Boolean;
 begin
   Result:=TXmlRegistry(FSysData).DeleteValue(Name);
 end;
 
-function TRegistry.SysGetData(const Name: String; Buffer: Pointer;
+function TRegistry.SysGetData(const Name: UnicodeString; Buffer: Pointer;
           BufSize: Integer; Out RegData: TRegDataType): Integer;
 
 Var
@@ -160,7 +164,7 @@
     Result:=-1;
 end;
 
-function TRegistry.GetDataInfo(const ValueName: string; out Value: TRegDataInfo): Boolean;
+function TRegistry.GetDataInfo(const ValueName: UnicodeString; out Value: TRegDataInfo): Boolean;
 
 Var
   Info : TDataInfo;
@@ -181,7 +185,7 @@
       end;
 end;
 
-function TRegistry.GetKey(const Key: string): HKEY;
+function TRegistry.GetKey(Key: UnicodeString): HKEY;
 begin
   Result := 0;
 end;
@@ -205,17 +209,17 @@
       end;
 end;
 
-function TRegistry.KeyExists(const Key: string): Boolean;
+function TRegistry.KeyExists(const Key: UnicodeString): Boolean;
 begin
   Result:=TXmlRegistry(FSysData).KeyExists(Key);
 end;
 
-function TRegistry.LoadKey(const Key, FileName: string): Boolean;
+function TRegistry.LoadKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.OpenKey(const Key: string; CanCreate: Boolean): Boolean;
+function TRegistry.OpenKey(const Key: UnicodeString; CanCreate: Boolean): Boolean;
 
 begin
   Result:=TXmlRegistry(FSysData).SetKey(Key,CanCreate);
@@ -222,59 +226,59 @@
   FCurrentKey:=1;
 end;
 
-function TRegistry.OpenKeyReadOnly(const Key: string): Boolean;
+function TRegistry.OpenKeyReadOnly(const Key: UnicodeString): Boolean;
 
 begin
   Result:=TXmlRegistry(FSysData).SetKey(Key,False);
 end;
 
-function TRegistry.RegistryConnect(const UNCName: string): Boolean;
+function TRegistry.RegistryConnect(const UNCName: UnicodeString): Boolean;
 begin
   Result := True;
 end;
 
-function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: string): Boolean;
+function TRegistry.ReplaceKey(const Key, FileName, BackUpFileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.RestoreKey(const Key, FileName: string): Boolean;
+function TRegistry.RestoreKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.SaveKey(const Key, FileName: string): Boolean;
+function TRegistry.SaveKey(const Key, FileName: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.UnLoadKey(const Key: string): Boolean;
+function TRegistry.UnLoadKey(const Key: UnicodeString): Boolean;
 begin
   Result := False;
 end;
 
-function TRegistry.ValueExists(const Name: string): Boolean;
+function TRegistry.ValueExists(const Name: UnicodeString): Boolean;
 begin
   Result := TXmlRegistry(FSysData).ValueExists(Name);
 end;
 
-procedure TRegistry.ChangeKey(Value: HKey; const Path: string);
+procedure TRegistry.ChangeKey(Value: HKey; const Path: UnicodeString);
 begin
 
 end;
 
-procedure TRegistry.GetKeyNames(Strings: TStrings);
+function TRegistry.GetKeyNames: TUnicodeStringArray;
 begin
-  TXmlRegistry(FSysData).EnumSubKeys(Strings);
+  Result:=TXmlRegistry(FSysData).EnumSubKeys;
 end;
 
-procedure TRegistry.GetValueNames(Strings: TStrings);
+function TRegistry.GetValueNames: TUnicodeStringArray;
 begin
-  TXmlRegistry(FSysData).EnumValues(Strings);
+  Result := TXmlRegistry(FSysData).EnumValues;
 end;
 
 
-function TRegistry.SysPutData(const Name: string; Buffer: Pointer;
+function TRegistry.SysPutData(const Name: UnicodeString; Buffer: Pointer;
   BufSize: Integer; RegData: TRegDataType): Boolean;
 
 Var
@@ -281,15 +285,18 @@
   DataType : TDataType;
 
 begin
+  //writeln('TRegistry.SysPutData: Name=',Name,', RegData=',RegData,', BufSize=',BufSize);
   DataType:=RegDataTypeToXmlDataType(RegData);
+
   Result:=TXMLRegistry(FSysData).SetValueDataUnicode(Name,DataType,Buffer^,BufSize);
 end;
 
-procedure TRegistry.RenameValue(const OldName, NewName: string);
+procedure TRegistry.RenameValue(const OldName, NewName: UnicodeString);
 begin
   TXMLRegistry(FSysData).RenameValue(OldName,NewName);
 end;
 
+
 procedure TRegistry.SetCurrentKey(Value: HKEY);
 begin
   fCurrentKey := Value;
@@ -298,7 +305,7 @@
 procedure TRegistry.SetRootKey(Value: HKEY);
 
 Var
-  S: String;
+  S: UnicodeString;
 
 begin
   If (Value=HKEY_CLASSES_ROOT) then
@@ -347,3 +354,5 @@
     TXMLRegistry(FSysData).SetRootKey(TXMLRegistry(FSysData).RootKey);
   end;
 end;
+
+

Bart Broersma

2019-03-23 14:44

reporter   ~0114989

Undid the change from using FillChar() into Default(TRegKeyInfo) in registry.unicode.part7.diff

Michael Van Canneyt

2019-03-24 09:50

administrator   ~0115011

I ran all tests, including the example program testunicode.
All works.

I also made a testunicode2 program, which is a copy of the TestUnicode program, but which runs using UnicodeString instead of Utf8 string. It keeps working.
(it works even better than the original one, which fails at 1 test)

Nice job, and thank you very much for the efforts!

Bart Broersma

2019-03-24 12:00

reporter   ~0115015

Thanks.
Now we can start fixing the rest of the bugs ;-)

Issue History

Date Modified Username Field Change
2019-03-10 12:01 Bart Broersma New Issue
2019-03-10 12:01 Bart Broersma File Added: registry.no-utf8encode.diff
2019-03-10 12:07 Michael Van Canneyt Assigned To => Michael Van Canneyt
2019-03-10 12:07 Michael Van Canneyt Status new => assigned
2019-03-10 12:11 Bart Broersma Note Added: 0114766
2019-03-10 12:11 Michael Van Canneyt Note Added: 0114767
2019-03-10 12:13 Michael Van Canneyt Note Edited: 0114767 View Revisions
2019-03-10 17:50 Michael Van Canneyt Assigned To Michael Van Canneyt =>
2019-03-10 23:08 Bart Broersma Note Added: 0114782
2019-03-10 23:17 Bart Broersma Note Added: 0114783
2019-03-11 15:51 Michael Van Canneyt Assigned To => Michael Van Canneyt
2019-03-11 15:51 Michael Van Canneyt Status assigned => new
2019-03-11 15:51 Michael Van Canneyt Assigned To Michael Van Canneyt =>
2019-03-11 18:53 Bart Broersma Note Added: 0114791
2019-03-13 14:02 Bart Broersma Note Added: 0114813
2019-03-13 14:05 Bart Broersma Note Edited: 0114813 View Revisions
2019-03-13 14:22 Michael Van Canneyt Summary TRegistry should not enforce UTF8 encoding on returned string variables. => Make TRegistry fully Unicode capable
2019-03-13 14:22 Michael Van Canneyt Description Updated View Revisions
2019-03-13 14:22 Michael Van Canneyt Additional Information Updated View Revisions
2019-03-13 14:23 Michael Van Canneyt Relationship added related to 0034876
2019-03-13 14:24 Michael Van Canneyt Relationship replaced has duplicate 0034876
2019-03-13 14:24 Michael Van Canneyt Note Added: 0114816
2019-03-13 17:45 Bart Broersma File Added: registry.unicode.part1.diff
2019-03-13 20:22 Bart Broersma File Added: registry.unicode.part2.diff
2019-03-16 02:50 Serge Anvarov Note Added: 0114855
2019-03-16 10:57 Bart Broersma Note Added: 0114862
2019-03-16 10:58 Bart Broersma Note Edited: 0114862 View Revisions
2019-03-16 12:30 Bart Broersma File Added: registry.unicode.part3.diff
2019-03-16 12:31 Bart Broersma Note Edited: 0114862 View Revisions
2019-03-16 17:18 Bart Broersma File Added: registry.unicode.part4.diff
2019-03-16 17:20 Bart Broersma Note Edited: 0114862 View Revisions
2019-03-17 12:38 Bart Broersma File Added: registry.unicode.part5.diff
2019-03-17 12:46 Bart Broersma Note Added: 0114896
2019-03-17 12:53 Bart Broersma Note Edited: 0114896 View Revisions
2019-03-17 13:02 Bart Broersma Note Edited: 0114896 View Revisions
2019-03-19 19:15 Bart Broersma File Added: registry.unicode.part6.diff
2019-03-19 19:17 Bart Broersma Note Added: 0114929
2019-03-20 10:25 Serge Anvarov Note Added: 0114937
2019-03-20 15:41 Bart Broersma Note Added: 0114940
2019-03-20 15:47 Bart Broersma Note Added: 0114941
2019-03-22 18:33 Bart Broersma Note Added: 0114983
2019-03-23 09:51 Joost van der Sluis Assigned To => Joost van der Sluis
2019-03-23 09:51 Joost van der Sluis Status new => assigned
2019-03-23 10:24 Joost van der Sluis Assigned To Joost van der Sluis =>
2019-03-23 10:36 Joost van der Sluis Note Added: 0114985
2019-03-23 10:36 Joost van der Sluis Assigned To => Joost van der Sluis
2019-03-23 10:36 Joost van der Sluis Status assigned => new
2019-03-23 14:26 Bart Broersma Note Added: 0114988
2019-03-23 14:42 Bart Broersma File Added: registry.unicode.part7.diff
2019-03-23 14:44 Bart Broersma Note Added: 0114989
2019-03-23 14:45 Bart Broersma Note Edited: 0114988 View Revisions
2019-03-23 14:46 Bart Broersma Note Edited: 0114988 View Revisions
2019-03-23 14:47 Bart Broersma Note Edited: 0114988 View Revisions
2019-03-24 09:50 Michael Van Canneyt Fixed in Revision => 41784
2019-03-24 09:50 Michael Van Canneyt Note Added: 0115011
2019-03-24 09:50 Michael Van Canneyt Status new => resolved
2019-03-24 09:50 Michael Van Canneyt Fixed in Version => 3.3.1
2019-03-24 09:50 Michael Van Canneyt Resolution open => fixed
2019-03-24 09:50 Michael Van Canneyt Assigned To Joost van der Sluis => Michael Van Canneyt
2019-03-24 09:50 Michael Van Canneyt Target Version => 3.2.0
2019-03-24 12:00 Bart Broersma Note Added: 0115015
2019-03-24 12:00 Bart Broersma Status resolved => closed