Enumerating serial ports
Moderator: Rathinagiri
Re: Enumerating serial ports
Hi!
I want to return to this topic after changing windows from xp to win'7.
This sample worked great upon windows xp, works fine in windows 7 when logged as administrator, but causes TREG32 error when you're working as normal user.
The same problem appears on windows Vista.
Ordinary uses can't read registry key?
Does anybody any idea on it?
Marek
I want to return to this topic after changing windows from xp to win'7.
This sample worked great upon windows xp, works fine in windows 7 when logged as administrator, but causes TREG32 error when you're working as normal user.
The same problem appears on windows Vista.
Ordinary uses can't read registry key?
Does anybody any idea on it?
Marek
- Pablo César
- Posts: 4059
- Joined: Wed Sep 08, 2010 1:18 pm
- Location: Curitiba - Brasil
Enumerating serial ports
Hi Marek,
Have you solved this problem already ?
HMG uses win_regread function with only one argument. I also looking for RegEnumKey function and bring the results by return in array would be wonderfull. I also do not like to use TREG32 ...
This is MSDN instruction for that. The problem is to adapt in pure code C for HMG:
http://msdn.microsoft.com/en-us/library ... s.85).aspx
Have you solved this problem already ?
HMG uses win_regread function with only one argument. I also looking for RegEnumKey function and bring the results by return in array would be wonderfull. I also do not like to use TREG32 ...

This is MSDN instruction for that. The problem is to adapt in pure code C for HMG:
http://msdn.microsoft.com/en-us/library ... s.85).aspx
HMGing a better world
"Matter tells space how to curve, space tells matter how to move."
Albert Einstein
"Matter tells space how to curve, space tells matter how to move."
Albert Einstein
- danielmaximiliano
- Posts: 2625
- Joined: Fri Apr 09, 2010 4:53 pm
- Location: Argentina
- Contact:
Re: Enumerating serial ports
Hola Pablo :
no es esto lo que estan buscando ?
Enumerating Registry Subkeys
Link RegQueryValue() :
http://www.fivetechsoft.com/wiki/doku.p ... 1266894556
no es esto lo que estan buscando ?
Enumerating Registry Subkeys
Code: Select all
// QueryKey - Enumerates the subkeys of key and its associated values.
// hKey - Key whose subkeys and values are to be enumerated.
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#define MAX_KEY_LENGTH 255
#define MAX_VALUE_NAME 16383
void QueryKey(HKEY hKey)
Link RegQueryValue() :
http://www.fivetechsoft.com/wiki/doku.p ... 1266894556
*´¨)
¸.·´¸.·*´¨) ¸.·*¨)
(¸.·´. (¸.·` *
.·`. Harbour/HMG : It's magic !
(¸.·``··*
Saludos / Regards
DaNiElMaXiMiLiAnO
Whatsapp. := +54901169026142
Telegram Name := DaNiElMaXiMiLiAnO
¸.·´¸.·*´¨) ¸.·*¨)
(¸.·´. (¸.·` *
.·`. Harbour/HMG : It's magic !
(¸.·``··*
Saludos / Regards
DaNiElMaXiMiLiAnO
Whatsapp. := +54901169026142
Telegram Name := DaNiElMaXiMiLiAnO
- Pablo César
- Posts: 4059
- Joined: Wed Sep 08, 2010 1:18 pm
- Location: Curitiba - Brasil
Re: Enumerating serial ports
Este es de otro compilador. En MinGW tiene, pero hay que elaborar algo en C.danielmaximiliano wrote:Link RegQueryValue() :
http://www.fivetechsoft.com/wiki/doku.p ... 1266894556
HMGing a better world
"Matter tells space how to curve, space tells matter how to move."
Albert Einstein
"Matter tells space how to curve, space tells matter how to move."
Albert Einstein
Re: Enumerating serial ports
I thought I've solved this problemPablo César wrote:Hi Marek,
Have you solved this problem already ?
HMG uses win_regread function with only one argument. I also looking for RegEnumKey function and bring the results by return in array would be wonderfull. I also do not like to use TREG32 ...
This is MSDN instruction for that. The problem is to adapt in pure code C for HMG:
http://msdn.microsoft.com/en-us/library ... s.85).aspx

But, maybe you will find any idea...
Code: Select all
FUNCTION GetCOMports()
local oKey
local hKey := HKEY_LOCAL_MACHINE
local cReg :="HARDWARE\DEVICEMAP\SERIALCOMM\" //"SOFTWARE\MICROSOFT\WINDOWS NT\CURRENTVERSION\PORTS" //
local cName := "",;
cData:="",;
nId ,;
clist:="",;
aWinVer:=WindowsVersion()
local aComPorts := {}
local i
oKey := TReg32():New( hKey, cReg )
nId := 0
//cr_lf := chr(13)+chr(10)
While RegEnumValue( oKey:nHandle, nId++, @cName) == 0
cData := oKey:Get( cName)
//clist += cData + cr_lf
aAdd(aComPorts, val(substr(cData,4)))
EndDo
cList+="found: " + alltrim(str(nid-1)) + " COM ports" + cr_lf + "Windows version: "+aWinVer[1]
msginfo(cList)
oKey:Close()
aComPorts := aSort(aComPorts)
RETURN aComPorts
#pragma BEGINDUMP
#include <windows.h>
#include "hbapi.h"
#include "hbapiitm.h"
#include "winreg.h"
#include "tchar.h"
HB_FUNC( REGENUMVALUE )
{
DWORD lpType = 1;
TCHAR Buffer[ 255 ];
DWORD dwBuffSize = 255;
DWORD dwClass = 255;
long lError;
lError = RegEnumValueA( ( HKEY ) hb_parnl(1), hb_parnl(2), Buffer, &dwBuffSize, NULL, &lpType, NULL, &dwClass );
if( lError != ERROR_SUCCESS )
hb_retnl( -1 );
else
{
hb_storc( Buffer, 3 );
hb_stornl( ( long ) dwBuffSize, 4 );
hb_stornl( ( long ) lpType, 6 );
hb_stornl( ( long ) dwClass, 8 );
hb_retnl( lError );
}
}
HB_FUNC( REGCLOSEKEY )
{
HKEY hwHandle = ( HKEY ) hb_parnl( 1 );
if ( RegCloseKey( hwHandle ) == ERROR_SUCCESS )
{
hb_retnl( ERROR_SUCCESS );
}
else
{
hb_retnl( -1 );
}
}
HB_FUNC( REGOPENKEYEXA )
{
HKEY hwKey = ( ( HKEY ) hb_parnl( 1 ) );
LPCTSTR lpValue=hb_parc( 2 );
LONG lError;
HKEY phwHandle;
lError = RegOpenKeyExA( ( HKEY ) hwKey , lpValue , 0 , KEY_ALL_ACCESS , &phwHandle );
if ( lError > 0 )
{
hb_retnl( -1 );
}
else
{
hb_stornl( PtrToLong( phwHandle ) , 5 );
hb_retnl( 0 );
}
}
HB_FUNC( REGQUERYVALUEEXA )
{
LONG lError;
DWORD lpType=hb_parnl( 4 );
DWORD lpcbData=0;
lError=RegQueryValueExA( ( HKEY ) hb_parnl( 1 ) , ( LPTSTR ) hb_parc( 2 ) , NULL , &lpType , NULL , &lpcbData );
if ( lError == ERROR_SUCCESS )
{
BYTE *lpData;
lpData= (BYTE*) malloc( ( int ) lpcbData+1 );
lError= RegQueryValueExA( ( HKEY ) hb_parnl( 1 ) , ( LPTSTR ) hb_parc( 2 ) , NULL , &lpType , ( BYTE* ) lpData , &lpcbData );
if ( lError > 0 )
{
hb_retnl( -1 );
}
else
{
hb_storc( ( char * ) lpData , 5 );
hb_retnl( 0 );
}
free( ( BYTE* ) lpData );
}
else
hb_retnl( -1 );
}
HB_FUNC( REGENUMKEYEXA )
{
FILETIME ft;
long bErr;
TCHAR Buffer[255];
DWORD dwBuffSize = 255;
TCHAR Class[255];
DWORD dwClass = 255;
bErr = RegEnumKeyEx( ( HKEY ) hb_parnl( 1 ) , hb_parnl( 2 ) , Buffer , &dwBuffSize , NULL , Class , &dwClass , &ft );
if ( bErr != ERROR_SUCCESS )
{
hb_retnl(-1);
}
else
{
hb_storc( Buffer , 3 );
hb_stornl( ( long ) dwBuffSize , 4 );
hb_storc( Class , 6 );
hb_stornl( ( long ) dwClass , 7 );
hb_retnl( 1 );
}
}
HB_FUNC( REGSETVALUEEXA )
{
if ( RegSetValueExA( ( HKEY ) hb_parnl( 1 ) , hb_parc( 2 ) , (DWORD)NULL , hb_parnl( 4 ) , ( BYTE * const ) hb_parc( 5 ) , ( strlen( hb_parc( 5 ) ) + 1 ) ) == ERROR_SUCCESS )
{
hb_retnl( 0 );
}
else
{
hb_retnl(-1);
}
}
HB_FUNC( REGCREATEKEY )
{
HKEY hKey;
if ( RegCreateKey( ( HKEY ) hb_parnl( 1 ) , hb_parc( 2 ) , &hKey ) == ERROR_SUCCESS )
{
hb_stornl( PtrToLong( hKey ) , 3 );
hb_retnl( 0 );
}
else
{
hb_retnl( -1 );
}
}
HB_FUNC( REGENUMVALUEA )
{
DWORD lpType=1;
TCHAR Buffer[255];
DWORD dwBuffSize = 255;
DWORD dwClass = 255;
long lError;
lError = RegEnumValueA( (HKEY) hb_parnl(1),hb_parnl(2), Buffer, &dwBuffSize, NULL, &lpType, NULL, &dwClass);
if ( lError != ERROR_SUCCESS )
{
hb_retnl(-1);
}
else
{
hb_storc( Buffer , 3 );
hb_stornl( ( long ) dwBuffSize , 4 );
hb_stornl( ( long ) dwClass , 8 );
hb_retnl( 0 );
}
}
HB_FUNC( REGDELETEKEY )
{
hb_retnl( RegDeleteKey( ( HKEY ) hb_parnl( 1 ), hb_parc( 2 ) ) );
}
HB_FUNC( REGDELETEVALUEA )
{
if ( RegDeleteValueA( ( HKEY ) hb_parnl( 1 ) , hb_parc( 2 ) ) == ERROR_SUCCESS )
{
hb_retnl( ERROR_SUCCESS );
}
else
{
hb_retnl( -1 );
}
}
#pragma ENDDUMP
- Pablo César
- Posts: 4059
- Joined: Wed Sep 08, 2010 1:18 pm
- Location: Curitiba - Brasil
Enumerating serial ports
Hi Marek,
Probably the problem is on oKey := TReg32():New( hKey, cReg ). May be you need to change for RegOpenKey directly not by this old class and most probably it is trying to create a new key instead of just opening the regkey.
I will revise my code, I got already something for RegNum for key and values. When be ok for UNICODE, I will post it here.
Probably the problem is on oKey := TReg32():New( hKey, cReg ). May be you need to change for RegOpenKey directly not by this old class and most probably it is trying to create a new key instead of just opening the regkey.
I will revise my code, I got already something for RegNum for key and values. When be ok for UNICODE, I will post it here.
HMGing a better world
"Matter tells space how to curve, space tells matter how to move."
Albert Einstein
"Matter tells space how to curve, space tells matter how to move."
Albert Einstein
- Pablo César
- Posts: 4059
- Joined: Wed Sep 08, 2010 1:18 pm
- Location: Curitiba - Brasil
Enumerating serial ports
Hi Marek, me again...mol wrote:I thought I've solved this problemWhen I was working on windows XP, everything was going OK, on my home computer (w7 prof) -OK, on the client side - win7 home premium - problems with rights. Client hadn't admin rights.
But, maybe you will find any idea...
I have found half of way gone... with:
SOFTWARE\MICROSOFT\WINDOWS NT\CURRENTVERSION\PORTS works OK, in XP, Win7 (with and without special rights)
but... with:
HARDWARE\DEVICEMAP\SERIALCOMM is getting keys names but not with its Values...
I have read this:
So, I do not find the right way to extract Valued of each keys...Note that the backslash character is, as mentioned, used by QSettings to separate subkeys. As a result, you cannot read or write windows registry entries that contain slashes or backslashes; you should use a native windows API if you need to do so.

Anyway, see this code probably will helps you...
Code: Select all
/* HMG 3.1.5 */
#include <hmg.ch>
#define HKEY_CLASSES_ROOT 2147483648
#define HKEY_CURRENT_USER 2147483649
#define HKEY_LOCAL_MACHINE 2147483650
#define HKEY_USERS 2147483651
#define HKEY_PERFORMANCE_DATA 2147483652
#define HKEY_CURRENT_CONFIG 2147483653
#define HKEY_DYN_DATA 2147483654
#define ERROR_SUCCESS 0
Function Main()
Local aReg
aReg := EnumValues( HKEY_LOCAL_MACHINE, "HKEY_LOCAL_MACHINE", "SOFTWARE\MICROSOFT\WINDOWS NT\CURRENTVERSION\PORTS\" )
MsgDebug1("CURRENTVERSION\PORTS",aReg)
aReg := EnumValues( HKEY_LOCAL_MACHINE, "HKEY_LOCAL_MACHINE", "HARDWARE\DEVICEMAP\SERIALCOMM" )
MsgDebug1("DEVICEMAP\SERIALCOMM",aReg)
/*
aReg := EnumKeys( HKEY_LOCAL_MACHINE, "HKEY_LOCAL_MACHINE", "SOFTWARE\MICROSOFT\WINDOWS NT\CURRENTVERSION\" )
MsgDebug(aReg)
*/
Return Nil
Function EnumValues(nKey,cKey,cSubKey)
Local hKey, cName, uValue, n := 0, aRet:={}
RegOpenKey( nKey, cSubKey, @hKey )
Do While RegEnumValue( hKey, n++, @cName, @uValue ) == ERROR_SUCCESS
AAdd(aRet,{cName, RegistryRead(cKey+"\"+cSubKey+cName)})
// AAdd(aRet,{cName, RegQueryValueExW(cKey+"\"+cSubKey+cName)})
Enddo
RegCloseKey( hKey )
Return aRet
Function EnumKeys(nKey,cKey,cSubKey)
Local hKey, cName, n := 0, aRet:={}
RegOpenKey( nKey, cSubKey, @hKey )
Do While RegEnumKeyExW( hKey, n++, @cName ) == ERROR_SUCCESS
AAdd(aRet,cName)
Enddo
RegCloseKey( hKey )
Return aRet
Function MsgDebug1
Local i, cMsg, nParam:=PCOUNT(), nStart:=1, cTit:="DEBUG INFO"
If nParam>1 .and. ValType(PValue(1))="C"
nStart:=2
cTit:=PValue(1)
Endif
cMsg := "Called from: " + ProcName(1) + "(" + LTrim(Str(ProcLine(1))) + ") --> " + ProcFile(1) + CRLF + CRLF
For i = nStart To nParam
cMsg := cMsg + hb_ValToExp(PValue(i)) + IIf (i < nParam, ", ", "")
Next
MsgBox(cMsg, cTit)
Return cMsg
#pragma BEGINDUMP
#define COMPILE_HMG_UNICODE
#include "HMG_UNICODE.h"
#include <windows.h>
HB_FUNC( REGENUMVALUE )
{
DWORD lpType = 1;
TCHAR Buffer[ 255 ];
DWORD dwBuffSize = 255;
DWORD dwClass = 255;
long lError;
lError = RegEnumValueW( ( HKEY ) hb_parnl(1), hb_parnl(2), Buffer, &dwBuffSize, NULL, &lpType, NULL, &dwClass );
if( lError != ERROR_SUCCESS )
hb_retnl( -1 );
else
{
HMG_storc( Buffer, 3 );
hb_stornl( ( long ) dwBuffSize, 4 );
hb_stornl( ( long ) lpType, 6 );
hb_stornl( ( long ) dwClass, 8 );
hb_retnl( lError );
}
}
HB_FUNC( REGCLOSEKEY )
{
HKEY hwHandle = ( HKEY ) hb_parnl( 1 );
if ( RegCloseKey( hwHandle ) == ERROR_SUCCESS )
{
hb_retnl( ERROR_SUCCESS );
}
else
{
hb_retnl( -1 );
}
}
HB_FUNC( REGOPENKEY ) // ( nkey, cSubKey, @nHandle ) --> nResult
{
HKEY hKey = ( HKEY ) hb_parnl( 1 );
HKEY hResult;
hb_retnl( RegOpenKey( hKey, HMG_parc( 2 ), &hResult ) );
hb_stornl( ( LONG ) hResult, 3 );
}
HB_FUNC( REGENUMKEYEXW )
{
FILETIME ft;
long bErr;
TCHAR Buffer[ 255 ];
DWORD dwBuffSize = 255;
TCHAR Class[ 255 ];
DWORD dwClass = 255;
bErr = RegEnumKeyEx( ( HKEY ) hb_parnl( 1 ), hb_parnl( 2 ), Buffer, &dwBuffSize, NULL, Class, &dwClass, &ft );
if( bErr != ERROR_SUCCESS )
hb_retnl( -1 );
else
{
HMG_storc( Buffer, 3 );
hb_stornl( ( long ) dwBuffSize, 4 );
HMG_storc( Class, 6 );
hb_stornl( ( long ) dwClass, 7 );
hb_retnl( 0 );
}
}
HB_FUNC( REGENUMVALUEW )
{
DWORD lpType=1;
TCHAR Buffer[255];
DWORD dwBuffSize = 255;
DWORD dwClass = 255;
long lError;
lError = RegEnumValueW( (HKEY) hb_parnl(1),hb_parnl(2), Buffer, &dwBuffSize, NULL, &lpType, NULL, &dwClass);
if ( lError != ERROR_SUCCESS )
{
hb_retnl(-1);
}
else
{
HMG_storc( Buffer , 3 );
hb_stornl( ( long ) dwBuffSize , 4 );
hb_stornl( ( long ) dwClass , 8 );
hb_retnl( 0 );
}
}
HB_FUNC( REGQUERYVALUEEXW )
{
LONG lError;
DWORD lpType=hb_parnl( 4 );
DWORD lpcbData=0;
lError=RegQueryValueExW( ( HKEY ) hb_parnl( 1 ) , ( LPTSTR ) HMG_parc( 2 ) , NULL , &lpType , NULL , &lpcbData );
if ( lError == ERROR_SUCCESS )
{
BYTE *lpData;
lpData= (BYTE*) malloc( ( int ) lpcbData+1 );
lError= RegQueryValueExW( ( HKEY ) hb_parnl( 1 ) , ( LPTSTR ) HMG_parc( 2 ) , NULL , &lpType , ( BYTE* ) lpData , &lpcbData );
if ( lError > 0 )
{
hb_retnl( -1 );
}
else
{
hb_storc( ( char * ) lpData , 5 );
hb_retnl( 0 );
}
free( ( BYTE* ) lpData );
}
else
hb_retnl( -1 );
}
#pragma ENDDUMP
HMGing a better world
"Matter tells space how to curve, space tells matter how to move."
Albert Einstein
"Matter tells space how to curve, space tells matter how to move."
Albert Einstein
- Pablo César
- Posts: 4059
- Joined: Wed Sep 08, 2010 1:18 pm
- Location: Curitiba - Brasil
Enumerating serial ports
Hi Marek, have your tested this my new code ?
HMGing a better world
"Matter tells space how to curve, space tells matter how to move."
Albert Einstein
"Matter tells space how to curve, space tells matter how to move."
Albert Einstein
Re: Enumerating serial ports
I've missed your sample code. I'll test it tomorrow morning. Many thanks for sharing!
Re: Enumerating serial ports
I've tested your code in my system, but, at first detection it detects too many COM ports
:

second seems good, but, we need to catch COM numbers fro \Device\Serial0 or \Device\Serial1



second seems good, but, we need to catch COM numbers fro \Device\Serial0 or \Device\Serial1
