-
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;
-
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'); RegKeyGetValueNames(RegKey,StrList); 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).
-
NewWStrList?
-
No, WStrList does not fix the problem.
-
kol.zip is updated: KOL.pas is marked as 2.94+, only RegKeyGetValueNames is affected. Or just replace it from the code:
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;
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));
inc(i);
end;
FreeMem(Buf );
end; Result:=true;
end;
end;
-
Sorry, upload was not finished when I post message minute ago. Now kol.zip is actually replaced.
-
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.
-
Uncomment Size:=MaxValueNameLen+1; in KOL.pas line 25098, update will be later on site.
-
Thank you Vladimir - it works perfectly.
-
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); GetMem(Buffer2,Sz * Sizeof( KOLChar )); ExpandEnvironmentStrings(Buffer, Buffer2, Sz); Result:=Buffer2; FreeMem(Buffer2); end
else
Result := Buffer;
end;
FreeMem( Buffer );
end;
-
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.
-
Thanks again, especially for the fast responses. KOL v2.94++ works OK now.
-
Vladimir, the changes that you made to RegKeyGetValueNames also need to be applied to 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;
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);
end; Result:=true;
end;
end;
|