Page 2 of 3

Re: Enumerating serial ports

Posted: Thu Jan 03, 2013 5:03 pm
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

Enumerating serial ports

Posted: Mon Sep 16, 2013 7:55 pm
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

Re: Enumerating serial ports

Posted: Tue Sep 17, 2013 12:16 am
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

Re: Enumerating serial ports

Posted: Tue Sep 17, 2013 1:07 am
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.

Re: Enumerating serial ports

Posted: Tue Sep 17, 2013 5:29 am
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

Enumerating serial ports

Posted: Thu Oct 10, 2013 2:31 am
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.

Enumerating serial ports

Posted: Fri Oct 11, 2013 3:50 pm
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.

Enumerating serial ports

Posted: Tue Oct 22, 2013 7:20 pm
by Pablo César
Hi Marek, have your tested this my new code ?

Re: Enumerating serial ports

Posted: Tue Oct 22, 2013 7:45 pm
by mol
I've missed your sample code. I'll test it tomorrow morning. Many thanks for sharing!

Re: Enumerating serial ports

Posted: Wed Oct 23, 2013 5:21 am
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