Enumerating serial ports

General Help regarding HMG, Compilation, Linking, Samples

Moderator: Rathinagiri

User avatar
mol
Posts: 3774
Joined: Thu Sep 11, 2008 5:31 am
Location: Myszków, Poland
Contact:

Re: Enumerating serial ports

Post by mol »

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
User avatar
Pablo César
Posts: 4059
Joined: Wed Sep 08, 2010 1:18 pm
Location: Curitiba - Brasil

Enumerating serial ports

Post by Pablo César »

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
HMGing a better world
"Matter tells space how to curve, space tells matter how to move."
Albert Einstein
User avatar
danielmaximiliano
Posts: 2625
Joined: Fri Apr 09, 2010 4:53 pm
Location: Argentina
Contact:

Re: Enumerating serial ports

Post by danielmaximiliano »

Hola Pablo :
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
User avatar
Pablo César
Posts: 4059
Joined: Wed Sep 08, 2010 1:18 pm
Location: Curitiba - Brasil

Re: Enumerating serial ports

Post by Pablo César »

danielmaximiliano wrote:Link RegQueryValue() :
http://www.fivetechsoft.com/wiki/doku.p ... 1266894556
Este es de otro compilador. En MinGW tiene, pero hay que elaborar algo en C.
HMGing a better world
"Matter tells space how to curve, space tells matter how to move."
Albert Einstein
User avatar
mol
Posts: 3774
Joined: Thu Sep 11, 2008 5:31 am
Location: Myszków, Poland
Contact:

Re: Enumerating serial ports

Post by mol »

Pablo 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
I thought I've solved this problem :) When 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...

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
User avatar
Pablo César
Posts: 4059
Joined: Wed Sep 08, 2010 1:18 pm
Location: Curitiba - Brasil

Enumerating serial ports

Post by Pablo César »

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.
HMGing a better world
"Matter tells space how to curve, space tells matter how to move."
Albert Einstein
User avatar
Pablo César
Posts: 4059
Joined: Wed Sep 08, 2010 1:18 pm
Location: Curitiba - Brasil

Enumerating serial ports

Post by Pablo César »

mol wrote:I thought I've solved this problem :) When 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...
Hi Marek, me again...

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:
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.
So, I do not find the right way to extract Valued of each keys... :(

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
I think we would add some C function to our libraries... Because IMO, Registry are very important functions.
HMGing a better world
"Matter tells space how to curve, space tells matter how to move."
Albert Einstein
User avatar
Pablo César
Posts: 4059
Joined: Wed Sep 08, 2010 1:18 pm
Location: Curitiba - Brasil

Enumerating serial ports

Post by Pablo César »

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
User avatar
mol
Posts: 3774
Joined: Thu Sep 11, 2008 5:31 am
Location: Myszków, Poland
Contact:

Re: Enumerating serial ports

Post by mol »

I've missed your sample code. I'll test it tomorrow morning. Many thanks for sharing!
User avatar
mol
Posts: 3774
Joined: Thu Sep 11, 2008 5:31 am
Location: Myszków, Poland
Contact:

Re: Enumerating serial ports

Post by mol »

I've tested your code in my system, but, at first detection it detects too many COM ports :lol: :

Image

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

Image
Post Reply