View Issue Details

IDProjectCategoryView StatusLast Update
0036809FPCFCLpublic2020-03-30 17:42
ReporterMichel Assigned ToMichael Van Canneyt  
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
Fixed in Version3.3.1 
Summary0036809: Return value ERROR_NO_MORE_ITEMS should not raise an exception in TRegistry.GetKeyNames/TRegistry.GetValueNames
DescriptionThe rewritten code now generates exceptions, but for the return value "ERROR_NO_MORE_ITEMS" it should not do so.

Please refer to the documentation from Microsoft.
https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regenumvaluew

Return value
If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a system error code. If there are no more values available, the function returns ERROR_NO_MORE_ITEMS.

If the lpData buffer is too small to receive the value, the function returns ERROR_MORE_DATA.

Additional InformationSince "ERROR_NO_MORE_ITEMS" is no error, the procedure should simply be left directly.

if lResult<>ERROR_NO_MORE_ITEMS then
  exit
else if lResult<>ERROR_SUCCESS then
  raise ERegistryException.Create(SysErrorMessage(lResult));


TagsNo tags attached.
Fixed in Revision44429
FPCOldBugId
FPCTarget3.2.0
Attached Files

Activities

Bart Broersma

2020-03-20 18:15

reporter   ~0121664

Patch attached.
There was also an range check error if the number of keys/values was 0, because the for loop counter is unsigned.

Can this be applied to 3.2 fixes?
registry.getkeynames.diff (1,377 bytes)   
Index: packages/fcl-registry/src/winreg.inc
===================================================================
--- packages/fcl-registry/src/winreg.inc	(revision 44297)
+++ packages/fcl-registry/src/winreg.inc	(working copy)
@@ -341,7 +341,7 @@
 
 begin
   Result:=nil;
-  if GetKeyInfo(Info) then
+  if GetKeyInfo(Info) and (Info.NumSubKeys > 0) then
   begin
     dwLen:=Info.MaxSubKeyLen+1;
     GetMem(lpName,dwLen*SizeOf(WideChar));
@@ -352,6 +352,8 @@
       begin
         dwLen:=Info.MaxSubKeyLen+1;
         lResult:=RegEnumKeyExW(CurrentKey,dwIndex,lpName,dwLen,Nil,Nil,Nil,Nil);
+        if lResult=ERROR_NO_MORE_ITEMS then
+          Break;
         if lResult<>ERROR_SUCCESS then
           raise ERegistryException.Create(SysErrorMessage(lResult));
         if dwLen=0 then
@@ -381,7 +383,7 @@
 
 begin
   Result:=nil;
-  if GetKeyInfo(Info) then
+  if GetKeyInfo(Info) and (Info.NumValues > 0) then
   begin
     dwLen:=Info.MaxValueLen+1;
     GetMem(lpName,dwLen*SizeOf(WideChar));
@@ -390,6 +392,8 @@
       for dwIndex:=0 to Info.NumValues-1 do
       begin
         dwLen:=Info.MaxValueLen+1;
+        if lResult=ERROR_NO_MORE_ITEMS then
+          Break;
         lResult:=RegEnumValueW(CurrentKey,dwIndex,lpName,dwLen,Nil,Nil,Nil,Nil);
         if lResult<>ERROR_SUCCESS then
           raise ERegistryException.Create(SysErrorMessage(lResult));
registry.getkeynames.diff (1,377 bytes)   

Michel

2020-03-21 15:45

reporter   ~0121674

Why is "if lResult=ERROR_NO_MORE_ITEMS then" before " lResult:=RegEnumValueW(" ?

@@ -390,6 +392,8 @@
       for dwIndex:=0 to Info.NumValues-1 do
       begin
         dwLen:=Info.MaxValueLen+1;
+ if lResult=ERROR_NO_MORE_ITEMS then
+ Break;
         lResult:=RegEnumValueW(CurrentKey,dwIndex,lpName,dwLen,Nil,Nil,Nil,Nil);
         if lResult<>ERROR_SUCCESS then
           raise ERegistryException.Create(SysErrorMessage(lResult));

Bart Broersma

2020-03-21 17:45

reporter  

registry.getkeynames.2.diff (1,357 bytes)   
Index: packages/fcl-registry/src/winreg.inc
===================================================================
--- packages/fcl-registry/src/winreg.inc	(revision 44297)
+++ packages/fcl-registry/src/winreg.inc	(working copy)
@@ -341,7 +341,7 @@
 
 begin
   Result:=nil;
-  if GetKeyInfo(Info) then
+  if GetKeyInfo(Info) and (Info.NumSubKeys > 0) then
   begin
     dwLen:=Info.MaxSubKeyLen+1;
     GetMem(lpName,dwLen*SizeOf(WideChar));
@@ -352,6 +352,8 @@
       begin
         dwLen:=Info.MaxSubKeyLen+1;
         lResult:=RegEnumKeyExW(CurrentKey,dwIndex,lpName,dwLen,Nil,Nil,Nil,Nil);
+        if lResult=ERROR_NO_MORE_ITEMS then
+          Break;
         if lResult<>ERROR_SUCCESS then
           raise ERegistryException.Create(SysErrorMessage(lResult));
         if dwLen=0 then
@@ -381,7 +383,7 @@
 
 begin
   Result:=nil;
-  if GetKeyInfo(Info) then
+  if GetKeyInfo(Info) and (Info.NumValues > 0) then
   begin
     dwLen:=Info.MaxValueLen+1;
     GetMem(lpName,dwLen*SizeOf(WideChar));
@@ -391,6 +393,8 @@
       begin
         dwLen:=Info.MaxValueLen+1;
         lResult:=RegEnumValueW(CurrentKey,dwIndex,lpName,dwLen,Nil,Nil,Nil,Nil);
+        if lResult=ERROR_NO_MORE_ITEMS then
+          Break;
         if lResult<>ERROR_SUCCESS then
           raise ERegistryException.Create(SysErrorMessage(lResult));
         if dwLen=0 then
registry.getkeynames.2.diff (1,357 bytes)   

Bart Broersma

2020-03-21 17:45

reporter   ~0121675

Sorry, copy/paste error.
Thanks for checking that.
New patch uploaded: registry.getkeynames.2.diff

Michael Van Canneyt

2020-03-30 11:33

administrator   ~0121764

Applied patch2, thank you!

Will try to get it in rc2 for 3.2.0

Issue History

Date Modified Username Field Change
2020-03-19 19:18 Michel New Issue
2020-03-20 18:15 Bart Broersma File Added: registry.getkeynames.diff
2020-03-20 18:15 Bart Broersma Note Added: 0121664
2020-03-21 15:45 Michel Note Added: 0121674
2020-03-21 17:45 Bart Broersma File Added: registry.getkeynames.2.diff
2020-03-21 17:45 Bart Broersma Note Added: 0121675
2020-03-30 11:33 Michael Van Canneyt Assigned To => Michael Van Canneyt
2020-03-30 11:33 Michael Van Canneyt Status new => resolved
2020-03-30 11:33 Michael Van Canneyt Resolution open => fixed
2020-03-30 11:33 Michael Van Canneyt Fixed in Version => 3.3.1
2020-03-30 11:33 Michael Van Canneyt Fixed in Revision => 44429
2020-03-30 11:33 Michael Van Canneyt FPCTarget => 3.2.0
2020-03-30 11:33 Michael Van Canneyt Note Added: 0121764