Конференция "KOL" » GetRegKey request
 
  • Jon © (07.07.10 03:08) [0]
    The function RegKeyGetStrEx currently always expands environment variables:

    function RegKeyGetStrEx( Key: HKey; const ValueName: KOLString ): KOLString;
    Like RegKeyGetStr, but accepts REG_EXPAND_SZ type, expanding all
      environment variables in resulting string.



    Is is possible to add a parameter not to expand the variables please?

    function RegKeyGetStrEx( Key: HKey; const ValueName: KOLString; ExpandEnvVars: Boolean ): KOLString;
  • Jon © (07.07.10 04:45) [1]
    Also, I have found a bug in another registry routine. Here is a test program:


    program Test;

    uses
     Windows, Messages, KOL;

    var
     RegKey: HKEY;
     StrList: PStrList;

    begin
     StrList := NewStrList;
     RegKey := RegKeyOpenCreate(HKEY_CURRENT_USER,'Software\KOL Test');
     try
       RegKeySetStr(RegKey,'Test_String1','Test_Value1');
       RegKeySetStr(RegKey,'Test_String2','Test_Value2'); // Only crashes if more than one item
       RegKeyGetValueNames(RegKey,StrList); // Crash here if UNICODE_CTRLS is defined
     finally
       RegKeyClose(RegKey);
       StrList.Free;
     end;
    end.



    If I define UNICODE_CTRLS then the program rashes with a runtime error.
    The problem does not occur if there is only 1 value in the subkey.
    Looking at RegKeyGetValueNames in KOL.pas, the crash occurs at FreeMem(Buf).
  • MTsv DN (07.07.10 12:59) [2]
    NewWStrList?
  • Jon © (07.07.10 13:04) [3]
    No, WStrList does not fix the problem.
  • Vladimir Kladov © (07.07.10 15:54) [4]
    kol.zip is updated: KOL.pas is marked as 2.94+, only RegKeyGetValueNames is affected. Or just replace it from the code:

    //[function RegKeyGetValueNames]
    {$IFDEF OLD_REGKEYGETVALUENAMES}
    function RegKeyGetValueNames(const Key: HKEY; List: PKOLStrList): Boolean;
    var
     I, Size, NumSubKeys, NumValueNames, MaxValueNameLen: DWORD;
     ValueName: KOLString;
    begin
     List.Clear ;
     Result:=False;
     if RegQueryInfoKey(Key, nil, nil, nil, @NumSubKeys, nil, nil, @NumValueNames,
    @MaxValueNameLen, nil, nil, nil) = ERROR_SUCCESS then
     begin
        if NumValueNames > 0 then
           for I := 0 to NumValueNames - 1 do begin
             Size := MaxValueNameLen + 1;
             SetLength(ValueName, Size);
             FillChar(ValueName[1],Size,#0);
             RegEnumValue(Key, I, @ValueName[1], Size, nil, nil, nil, nil);
             ValueName := Trim(ValueName);
             List.Add(ValueName);
           end;
        Result := True;
     end ;
    end;
    {$ELSE} // new (faster) version by Alex Shyshko (Psychedelic)
    function RegKeyGetValueNames(const Key: HKEY; List: PKOLStrList) : Boolean;
    var
     i, MaxValueNameLen, Size: DWORD;
     Buf: PKOLchar;
    begin
    Result:=false;
    List.Clear;

    if RegQueryInfoKey(Key, nil, nil, nil, nil, nil, nil, nil, @MaxValueNameLen, nil,
        nil, nil) = ERROR_SUCCESS then
     begin
     if MaxValueNameLen > 0 then
       begin
         Size:=MaxValueNameLen+1;
         GetMem(Buf,Size * SizeOf(KOLChar) );
         i:=0;
         while RegEnumValue(Key,i,buf,Size,nil,nil,nil,nil) <> ERROR_NO_MORE_ITEMS do
         begin
          List.Add(KOLString(Buf));
          //Size:=MaxValueNameLen+1;
          inc(i);
         end;

         FreeMem(Buf {,MaxValueNameLen + ... system always knows how long buffer is});
       end; // if MaxValueNameLen
      Result:=true;
     end; // if RegQueryInfoKey

    end;
    {$ENDIF}

  • Vladimir Kladov © (07.07.10 15:57) [5]
    Sorry, upload was not finished when I post message minute ago. Now kol.zip is actually replaced.
  • Jon © (08.07.10 05:50) [6]
    Thank you Vladimir. I updated to v2.94+ but there is still a bug in the code. The strings read by RegKeyGetValueNames are incorrect. It occurs both with and without UNICODE_CTRLS. Here is a complete program that demonstrates the error:

    program Test;

    uses
     Windows, Messages, KOL;

    var
     RegKey: HKEY;
     StrList: PKOLStrList;
     Counter: Integer;

    begin
     StrList := NewKOLStrList;
     RegKey := RegKeyOpenCreate(HKEY_CURRENT_USER,'Software\KOL Test\'+Date2StrFmt('yyMMdd',Now)+Time2StrFmt('HHmmss',Now));
     try
       for Counter := 1 to 26 do
         RegKeySetStr(RegKey,StrRepeat(Chr($60+Counter),Counter),Int2Str(Counter));
       if RegKey <> 0 then
         RegKeyGetValueNames(RegKey,StrList);
       MsgOK(StrList.Text);
     finally
       RegKeyClose(RegKey);
       StrList.Free;
     end;
    end.

  • Vladimir Kladov © (08.07.10 15:24) [7]
    Uncomment Size:=MaxValueNameLen+1; in KOL.pas line 25098, update will be later on site.
  • Jon © (08.07.10 16:03) [8]
    Thank you Vladimir - it works perfectly.
  • Jon © (08.07.10 16:06) [9]
    For the RegKeyGetStrEx request, can it be modified to the following:


    function RegKeyGetStrEx( Key: HKey; const ValueName: KOLString; ExpandEnvVars: Boolean ): KOLString;
    var dwType, dwSize: DWORD;
       Buffer, Buffer2: PKOLChar;
       Sz: Integer;
       function Query: Boolean;
       begin
         Result := RegQueryValueEx( Key, PKOLChar( ValueName ), nil, @dwType,
                   Pointer( Buffer ), @dwSize ) = ERROR_SUCCESS;
       end;
    begin
     Result := '';
     if Key = 0 then Exit;
     dwSize := 0;
     Buffer := nil;
     if not Query or ((dwType <> REG_SZ) and (dwtype <> REG_EXPAND_SZ)) then Exit;
     GetMem( Buffer, dwSize * Sizeof( KOLChar ) );
     if Query then
     begin
       if (dwtype = REG_EXPAND_SZ) and (ExpandEnvVars) then
       begin
         Sz := ExpandEnvironmentStrings(Buffer,nil,0);  // bug in size detection! sometimes we get an additional 2 bytes at the end...
         GetMem(Buffer2,Sz * Sizeof( KOLChar ));                            //
         ExpandEnvironmentStrings(Buffer, Buffer2, Sz); //
         Result:=Buffer2;                               //
         FreeMem(Buffer2);                              //
       end
         else
       Result := Buffer;
     end;
     FreeMem( Buffer );
    end;

  • Vladimir Kladov © (08.07.10 18:38) [10]
    I have updated it (kol.zip on kolmck.net), but with a small change: add a symbol  OPTIONAL_REG_EXPAND_SZ to yours project opyions. I am not sure that earlier the function was used a lot, but for compatibility this seems more accurate.
  • Jon © (08.07.10 18:52) [11]
    Thanks again, especially for the fast responses. KOL v2.94++ works OK now.
  • Jon (18.07.10 05:02) [12]
    Vladimir, the changes that you made to RegKeyGetValueNames also need to be applied to RegKeyGetSubKeys:


    {$IFDEF OLD_REGKEYGETSUBKEYS}
    //-----------------------------------------------
    // functions by Valerian Luft <luft@valerian.de>
    //-----------------------------------------------
    //[function RegKeyGetSubKeys]
    function RegKeyGetSubKeys( const Key: HKEY; List: PKOLStrList) : Boolean;
    var
     I, Size, NumSubKeys, MaxSubKeyLen : DWORD;
     KeyName: KOLString;
    begin
     Result := False;
     List.Clear ;
     if RegQueryInfoKey(Key, nil, nil, nil, @NumSubKeys, @MaxSubKeyLen, nil, nil, nil, nil,
    nil, nil) = ERROR_SUCCESS then
       begin
         if NumSubKeys > 0 then begin
           for I := 0 to NumSubKeys-1 do
           begin
             Size := MaxSubKeyLen+1;
             SetLength(KeyName, Size);
             FillChar(KeyName[1],Size,#0);
             RegEnumKeyEx(Key, I, @KeyName[1], Size, nil, nil, nil, nil);
             KeyName := Trim(KeyName);
             List.Add(KeyName);
           end;
         end;
         Result:= True;
     end;
    end;
    {$ELSE} // new (faster) version by Alex Shyshko (Psychedelic)
    function RegKeyGetSubKeys(const Key: HKEY; List: PKOLStrList) : Boolean;
    var
     i, MaxSubKeyLen, Size: DWORD;
     Buf: PKOLChar;
    begin
    Result:=false;
    List.Clear;

    if RegQueryInfoKey(Key, nil, nil, nil, nil, @MaxSubKeyLen, nil, nil, nil, nil,
        nil, nil) = ERROR_SUCCESS then
     begin
     if MaxSubKeyLen > 0 then
       begin
         Size:=MaxSubKeyLen + 1;
         GetMem(Buf,Size * SizeOf(KOLChar) );
         i:=0;

         while RegEnumKeyEx(Key,i,buf,Size,nil,nil,nil,nil) <> ERROR_NO_MORE_ITEMS do
         begin
          List.Add(KOLString(Buf));
          Size:=MaxSubKeyLen + 1;
          inc(i);
         end;

         FreeMem(Buf{,MaxSubKeyLen + 1});
       end; // if MaxSubKeyLen
      Result:=true;
     end; // if RegQueryInfoKey

    end;
    {$ENDIF}

 
Конференция "KOL" » GetRegKey request
Есть новые Нет новых   [134463   +60][b:0][p:0.004]