Forum > Windows
Odd registry behaviour in WinXP
CM630:
While fixing a bug in LazSerial I got to synaser. Here is the problematic code:
--- Code: ---function GetSerialPortNames: string;
var
reg: TRegistry;
l, v: TStringList;
n: integer;
debvalnames: string;
begin
l := TStringList.Create;
v := TStringList.Create;
reg := TRegistry.Create;
try
{$IFNDEF VER100}
{$IFNDEF VER120}
reg.Access := KEY_READ;
{$ENDIF}
{$ENDIF}
reg.RootKey := HKEY_LOCAL_MACHINE;
reg.OpenKey('\HARDWARE\DEVICEMAP\SERIALCOMM', false);
debvalnames:=reg.GetValueNames(l);
reg.GetValueNames(l);
for n := 0 to l.Count - 1 do
begin
v.Add(reg.ReadString(l[n]));
end;
Result := v.CommaText;
finally
reg.Free;
l.Free;
v.Free;
end;
end;
--- End code ---
The purpose of the function is to return a string, containing the list of the COM devices, attached to the computer. The bug occurs when the number of the COM port is higher than 9 or exactly- last digits of the COM number are trimmed. For example, my bluetooth device is attached at COM32, but in the result of the function I get COM3.
I have narrowed the search to the following code:
--- Code: ---v.Add(reg.ReadString(l[n]));
--- End code ---
I changed the code the following way:
--- Code: ---ComName:= reg.ReadString(l[n]);
ShowMessage(length(ComName ) + ' ' + ComName);
v.Add(ComName);
--- End code ---
If I put a breakpoint on the line with ShowMessage(...); when the application stops on it, when I put the mouse pointer over ComName it shows „COM32“, or exactly what it should.
But, ShowMessage(length(ComName ) + ' ' + ComName); shows „COM3 4“. It occurs that the last char is lost. If I have a longer port number, probably last two chars will be lost.
So I did:
--- Code: ---ComName:= reg.ReadString(l[n]);
SetLength (ComName, 5);
ShowMessage(length(ComName ) + ' ' + ComName);
v.Add(ComName);
--- End code ---
Now the last character is not lost, but I have a - (minus) sign in the end of the shorter COM port names, which is not a surprise.
To recapitulate: The string is correctly retrieved from the registry, but its length value is wrong. Is there a bug in windows itself, in FPC (or Lazarus) registry module or in the posted code itself? And what should I do to make it work. Definitely, I can trim the minus signs, but that is the last chance solution.
Edit: I added anoher entry in the registry: COM252.
So, actually when using SetLength (ComName, 5); I get the following strings „COM1“; „COM32-“; „COM33-“ and „COM252“. There are no minus signs after COM1 !!!
EDIT (again): Trough the registry editor I open the COM32 and COM33 values and then I pressed enter, just like editing them. Now the minus signs disappeared! I removed the SetLength statement and still everythings works fine. :( Seems like the bluetooth device gets added improperly?!?
Edit (once again): Now I remember, that some quotation marks " were shown in the registry entry names, which have now disappeared. I will move the bluetooth dongle to another usb port.
derek.john.evans:
Have you checked the binary encoding of the strings? (via regedit). Maybe its a widechar issue?
What version of Lazarus are you running?
BigChimp:
His signature mentions the Laz version...
CM630:
--- Quote from: derek.john.evans on October 24, 2014, 02:42:15 pm ---Have you checked the binary encoding of the strings? (via regedit). Maybe its a widechar issue?
--- End quote ---
I just did. So here is what I found out. It was 43 00 4F 00 4d 00 33 00 32 00. When I edited it (actually by only clicking OK in the registry editor), it got changed to 43 00 4F 00 4d 00 33 00 32 00 00 00. Maybe there is a trick to use this info.
derek.john.evans:
Thats interesting. Looks like some registry writers arn't writing correctly.
There is a StringSizeIncludesNull property, which is hardcoded to True in winreg.inc
Which causes the string to be truncated in registry.pas
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} --- If StringSizeIncludesNull then SetLength(Result, Info.DataSize-1) else SetLength(Result, Info.DataSize);
It would seem, the code "should" check to see if the end char is actually a #0, before truncating.
EDIT: I guess you will have to use your own version of ReadString() to cater for the possible non nulled strings
Navigation
[0] Message Index
[#] Next page