View Issue Details

IDProjectCategoryView StatusLast Update
0021899FPCCompilerpublic2014-12-08 11:15
Reportermas Assigned ToMarco van de Voort  
Status resolvedResolutionfixed 
Platformdesktop and laptopOSwindows  
Product Version2.4.4 
Fixed in Version3.0.0 
Summary0021899: Tregistry access of bluetooth comm ports drops last char
Descriptionwhen accessing window's comm port registry the ReadString() works normally for USB and real hardware but drops the last character for any Bluetooth comm ports. the error is with Windows but a fix is needed anyway.

either the striping of the last char is fixed to check before striping or an override flag is needed in the Tregistry so the trailing Null is not striped.
Steps To Reproduceadd a Bluetooth comm port (hardware needed?). see windows fail.
or add a simulated entry elsewhere and access with TRegistry

binary view of working entry
"COM10" = [43,00,4f,00,4d,00,31,00,30,00,00,00]

binary view of bluetooth entry
"COM58" = [43,00,4f,00,4d,00,35,00,38,00]
Additional Information   reg.RootKey := HKEY_LOCAL_MACHINE;
    reg.OpenKeyReadOnly('HARDWARE\DEVICEMAP\SERIALCOMM');//, false);
    for n := 0 to l.Count - 1 do begin
// reg.StringSizeIncludesNulls := FALSE; // if I had set access to this..
    Result := v.CommaText;
TagsNo tags attached.
Fixed in Revision 29217
Attached Files


related to 0027002 resolvedMarco van de Voort ReadString from registry.pp does not read the last character of the string if the string does not end with a nil character. 



2012-04-30 20:06

reporter   ~0059135

I included some more data but I do not see it here. flaw in reporting website or is it only accessable by the repairman?


2012-05-04 03:16

reporter   ~0059227

Last edited: 2012-05-04 03:16

I verified that setting StringSizeIncludesNull := FALSE just before the call does GET the full string. (kluge) adding the strings with the extra null to tstring does not hurt anything (my access).
If I fix this issure correctly, do I/can I upload a modified registry file from 2.4.4 ??

Thorsten Schmidt

2014-02-07 16:50

reporter   ~0072896

Last edited: 2014-02-07 22:37

View 3 revisions

I have the same problem still in 2.6.2

In the function TRegistry.ReadString the GetDataInfo gets type and size of the requested registry entry. As StringSizeIncludesNull ist set to true in TRegistry.Create the returned size is decremented before the string ist fetched.

But GetDataInfo fails as it uses RegQueryValueEx to determine the size. The Microsoft API documentation says for parameter lpcbData:
"... If the data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type, this size includes any terminating null character or characters unless the data was stored without them. For more information, see Remarks..."

And in Remarks:
"If the data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type, the string may not have been stored with the proper terminating null characters. Therefore, even if the function returns ERROR_SUCCESS, the application should ensure that the string is properly terminated before using it"

So the assumed StringSizeIncludesNull=true is wrong.

Microsoft recommends: "One way an application can ensure that the string is properly terminated is to use RegGetValue, which adds terminating null characters if needed".

Ugly fix:
In TRegistry.ReadString
// discard size "correction"
// If StringSizeIncludesNull then
// SetLength(Result, Info.DataSize-1)
// else
// SetLength(Result, Info.DataSize);
// get string WITH null instead
// trim the result
     Result := Trim(Result);

Bart Broersma

2014-02-07 23:37

reporter   ~0072905

> Result := Trim(Result);
Can't strings in the registry end in spaces?

Thaddy de Koning

2014-02-08 07:12

reporter   ~0072917

Last edited: 2014-02-08 07:26

View 4 revisions

@Bart: Yes, they can. They can even contain embedded #0's (although that can only be read back with ntApi calls or with custom code, not in userspace registry api).

You have to be very careful messing with registry code.
The embedded #0's are employed in certain protection schemes and are also used in malicious code. Microsoft itself also employs it in rare cases:temporary information storage during installs, to enable recovery on compromized systems during installs for example.

So, yes, ending spaces are allowed, and #0's can be in the middle of the content.
More information on the sysinternals website and with these utilities:

Robert Angermayr

2014-11-02 17:40

reporter   ~0078827

Last edited: 2014-11-02 17:41

View 3 revisions

Hi, i solved the problem with fpc 2.6.4

Therefor i changed the code in GetString. (only in my system, not in the repository)
This is working with Bluetooth Ports in Win7 64bit and WinXP
(i have no other system to test it)

function TRegistry.ReadString(const Name: string): string;
  Info : TRegDataInfo;
  s: String;
  i: integer;
  if info.datasize>0 then
     If Not (Info.RegData in [rdString,rdExpandString]) then
       Raise ERegistryException.CreateFmt(SInvalidRegType, [Name]);
     result := '';
     for i:=1 to Info.DataSize do
       if s[i]<>#0 then result:=result+s[i];


The problem with bluetooth serial ports is, tht there is no nullbyte in the string. In TRegistry the property StringSizeIncludesNull is set to true and it is not checked if this is the true.

Here my Registry entries


\Device\Serial0 COM1
0000 43 00 4F 00 4D 00 31 00 C.O.M.1.
0008 00 00 <<- here the null bytes

\Device\BthModem0 COM4
0000 43 00 4F 00 4D 00 34 00 C.O.M.4.
0008 <<- here no null bytes

Best regards


2014-11-06 08:05

reporter   ~0078935

Maybe it will be useful to mention, that running the following code (VB.NET), retrieves strings fine, disregarding if they end with or without #0:

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  Dim readValue As String
  readValue = My.Computer.Registry.GetValue("HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM", "\Device\BthModem10", Nothing)
  MsgBox("The value is " & readValue)
End Sub

Denis Kozlov

2014-12-03 18:53

reporter   ~0079607

Patch to address this problem is attached in: 0027002

P.S. This bug report here is very old and contains a lot of misleading or otherwise not useful information. Hence, the patch is attached to a newer (cleaner) bug report.

Marco van de Voort

2014-12-08 11:15

manager   ~0079699

Resolved as in related report. Please test with trunk

Issue History

Date Modified Username Field Change
2012-04-30 20:01 mas New Issue
2012-04-30 20:06 mas Note Added: 0059135
2012-05-04 03:16 mas Note Added: 0059227
2012-05-04 03:16 mas Note Edited: 0059227
2014-02-07 16:50 Thorsten Schmidt Note Added: 0072896
2014-02-07 19:43 Thorsten Schmidt Note Edited: 0072896 View Revisions
2014-02-07 22:37 Thorsten Schmidt Note Edited: 0072896 View Revisions
2014-02-07 23:37 Bart Broersma Note Added: 0072905
2014-02-08 07:12 Thaddy de Koning Note Added: 0072917
2014-02-08 07:15 Thaddy de Koning Note Edited: 0072917 View Revisions
2014-02-08 07:22 Thaddy de Koning Note Edited: 0072917 View Revisions
2014-02-08 07:26 Thaddy de Koning Note Edited: 0072917 View Revisions
2014-11-02 17:40 Robert Angermayr Note Added: 0078827
2014-11-02 17:40 Robert Angermayr Note Edited: 0078827 View Revisions
2014-11-02 17:41 Robert Angermayr Note Edited: 0078827 View Revisions
2014-11-06 08:05 pYskal Note Added: 0078935
2014-12-03 18:53 Denis Kozlov Note Added: 0079607
2014-12-07 21:59 Florian Relationship added related to 0027002
2014-12-08 11:15 Marco van de Voort Fixed in Revision => 29217
2014-12-08 11:15 Marco van de Voort Note Added: 0079699
2014-12-08 11:15 Marco van de Voort Status new => resolved
2014-12-08 11:15 Marco van de Voort Fixed in Version => 2.7.1
2014-12-08 11:15 Marco van de Voort Resolution open => fixed
2014-12-08 11:15 Marco van de Voort Assigned To => Marco van de Voort