USB
  CP2102 & Vista registry

Post New Topic  Post A Reply
profile | register | preferences | faq | search

UBBFriend: Email This Page to Someone! next newest topic | next oldest topic
Author Topic:   CP2102 & Vista registry
ignisfts
New Member
posted August 08, 2008 06:23 AM     Click Here to See the Profile for ignisfts     Edit/Delete Message
Hello all,

I'm experiencing a problem on Vista (UAC is enabled) with the cp2102 USB to UART com driver. Apparently, the port number for this is stored in a registry key under the hklm hive: [HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SerialComm]
"\\Device\\slabser0"="COM3"

My problem is that when my application attempts to open this key, but UAC is denying it access, so it cannot connect to the USB controller. Any idea why my app [ClearFit.exe] would do this instead of just doing a RegOpenReadOnly on the key? See process monitor log below:

http://img217.imageshack.us/img217/8995/picture20vk2.png

Btw, if I run my program "as an administrator," essentially bypassing UAC, everything works fine. My goal is to make this work UAC compliant. Thank you.

IP: Logged

Ueli
New Member
posted August 20, 2008 02:03 AM     Click Here to See the Profile for Ueli   Click Here to Email Ueli     Edit/Delete Message
Look at Application note 197:
SERIAL COMMUNICATIONS GUIDE FOR THE CP210X

=> chapter 7. Discovering CP210x COM Port

I think, it should run without UAC appears...

IP: Logged

Tsuneo
Member
posted September 09, 2008 01:54 AM     Click Here to See the Profile for Tsuneo   Click Here to Email Tsuneo     Edit/Delete Message
I tested this command line tool at "standard" user account on Vista SP1.
This works without any UAC claim.

Tsuneo

PS. The forum engine doesn't pass this message when "SP _DEVINFO_DATA" is written without blank.
The engine doesn't like "SP" with underscore...
Before compiling this code, please delete the blank from "SP _DEVINFO_DATA"
As usual, the formatted original post is retrieved from the Edit window of this post.


//
// CP210x_COM_port_lister.cpp
// Snippet for console tool, coded on MS VC++ 2005
// List up COM port and serial number of CP210x, currently connected to this PC
//
// Reference:
// http://www.codeproject.com/KB/system/setupdi.aspx?df=100&forumid=4368&exp=0&select=479661
// portlister.cpp : Defines the entry point for the console application.
// by Christian B
//

#include "stdafx.h"
#include "atlstr.h"
#include "Windows.h"
#include "SetupAPI.h"

// Add "SetupAPI.Lib" to the Project -> Linker -> Input


int _tmain(int argc, _TCHAR* argv[])
{
// device ID of CP210x VCP
// default VID/PID: 10C4/EA60
// for custom VID/PID, modify this string
CString deviceID( _T("USB\\VID_10C4&PID_EA60\\") );

CString instanceID;
CString serialNumer;
CString portName;
DWORD requiredSize;
// Get Class GUID for PORTS class
GUID classGuid[1];
if ( ! SetupDiClassGuidsFromName( _T("PORTS"), classGuid, 1, &requiredSize ) )
return 0;
// List up PORTS class devices in present
HDEVINFO hDevInfoSet = SetupDiGetClassDevs( classGuid, NULL, NULL, DIGCF_PRESENT );
if ( hDevInfoSet == INVALID_HANDLE_VALUE )
return 0;
// Enumerate devices in the list
SP _DEVINFO_DATA devInfo; // <------------- please delete the blank
devInfo.cbSize = sizeof( SP _DEVINFO_DATA ); // <------------- from "SP _DEVINFO_DATA"

for ( DWORD deviceIndex = 0;
SetupDiEnumDeviceInfo( hDevInfoSet, deviceIndex, &devInfo );
deviceIndex++ )
{
// Get device instance ID
SetupDiGetDeviceInstanceId( hDevInfoSet, &devInfo, NULL, 0, &requiredSize );
SetupDiGetDeviceInstanceId( hDevInfoSet, &devInfo,
instanceID.GetBuffer(requiredSize), requiredSize, NULL );
instanceID.ReleaseBuffer();
// Check device ID
if( instanceID.Find( deviceID ) != 0 )
continue;
// Split serial number
serialNumer = instanceID.Right( instanceID.GetLength() - deviceID.GetLength() );
// Open device parameters reg key
HKEY hkey = SetupDiOpenDevRegKey( hDevInfoSet, &devInfo, DICS_FLAG_GLOBAL,
0, DIREG_DEV, KEY_READ );
if ( hkey == INVALID_HANDLE_VALUE )
continue;
// Qurey for portname
RegQueryValueEx( hkey, _T("PortName"), NULL, NULL, NULL, &requiredSize );
RegQueryValueEx( hkey, _T("PortName"), NULL, NULL,
(LPBYTE)portName.GetBuffer(requiredSize), &requiredSize );
portName.ReleaseBuffer();
// Close reg key
RegCloseKey( hkey );
// Print result
_tprintf( _T("Port: %s Serial number: %s\n"), portName, serialNumer );
}
// Destroy device info list
SetupDiDestroyDeviceInfoList( hDevInfoSet );

return 0;
}

[This message has been edited by Tsuneo (edited September 09, 2008).]

IP: Logged

Tsuneo
Member
posted April 26, 2010 10:42 PM     Click Here to See the Profile for Tsuneo   Click Here to Email Tsuneo     Edit/Delete Message
Update of above code for C#

Tsuneo


//
// CP210x_COM_port_lister.cs
// Snippet for C# console tool, coded on MSVS 2008
// List up COM port, Product ID (just for XP) and serial number of CP210x, currently connected to this PC
//

using System;
using System.Runtime.InteropServices;
using System.Text;

namespace CP210x_COM_port_lister
{
class Program
{
private readonly static IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);

// constants for SetupDiGetClassDevs( flags )
internal const UInt32 DIGCF_PRESENT = 0x00000002;
internal const UInt32 DIGCF_DEVICEINTERFACE = 0x00000010;

// constants for SetupDiOpenDevRegKey( scope,,parameterRegistryValueKind,samDesired )
internal const UInt32 DICS_FLAG_GLOBAL = 0x00000001;
internal const UInt32 DIREG_DEV = 0x00000001;
internal const UInt32 KEY_READ = 0x00020019;

// constants for SetupDiGetDeviceRegistryProperty( Property )
internal const UInt32 SPDRP_DEVICEDESC = 0x00000000;
internal const UInt32 SPDRP_MFG = 0x0000000B;
internal const UInt32 SPDRP_FRIENDLYNAME = 0x0000000C;
internal const UInt32 SPDRP_LOCATION_INFORMATION = 0x0000000D;

[StructLayout(LayoutKind.Sequential)]
public struct DEVINFO_DATA
{
internal Int32 cbSize;
internal Guid ClassGuid;
internal UInt32 DevInst;
internal IntPtr Reserved;
}

[DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern Boolean SetupDiClassGuidsFromName(
String className,
ref Guid classGuidArray1stItem,
UInt32 classGuidArraySize,
out Int32 RequiredSize
);

[DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern IntPtr SetupDiGetClassDevs(
ref Guid classGuid,
IntPtr enumerator,
IntPtr hwndParent,
UInt32 flags
);

[DllImport("setupapi.dll", SetLastError = true)]
static extern Boolean SetupDiDestroyDeviceInfoList(
IntPtr hDevInfo
);

[DllImport("setupapi.dll", SetLastError = true)]
static extern Boolean SetupDiEnumDeviceInfo(
IntPtr DeviceInfoSet,
UInt32 MemberIndex,
out DEVINFO_DATA DeviceInfoData
);

[DllImport("setupapi.dll", EntryPoint = "SetupDiGetDeviceInstanceId", CharSet = CharSet.Auto, SetLastError = true)]
static extern Boolean SetupDiGetDeviceInstanceId_getSize(
IntPtr DeviceInfoSet,
ref DEVINFO_DATA DeviceInfoData,
IntPtr DeviceInstanceId,
Int32 DeviceInstanceIdSize,
out Int32 RequiredSize
);

[DllImport("setupapi.dll", EntryPoint = "SetupDiGetDeviceInstanceId", CharSet = CharSet.Auto, SetLastError = true)]
static extern Boolean SetupDiGetDeviceInstanceId_getString(
IntPtr DeviceInfoSet,
ref DEVINFO_DATA DeviceInfoData,
StringBuilder DeviceInstanceId,
Int32 DeviceInstanceIdSize,
IntPtr RequiredSize
);

[DllImport("setupapi.dll", EntryPoint = "SetupDiGetDeviceRegistryProperty", CharSet = CharSet.Auto, SetLastError = true)]
static extern Boolean SetupDiGetDeviceRegistryProperty_getSize(
IntPtr DeviceInfoSet,
ref DEVINFO_DATA DeviceInfoData,
UInt32 Property,
IntPtr PropertyRegDataType,
IntPtr PropertyBuffer,
Int32 PropertyBufferSize,
out Int32 RequiredSize
);

[DllImport("setupapi.dll", EntryPoint = "SetupDiGetDeviceRegistryProperty", CharSet = CharSet.Auto, SetLastError = true)]
static extern Boolean SetupDiGetDeviceRegistryProperty_getString(
IntPtr DeviceInfoSet,
ref DEVINFO_DATA DeviceInfoData,
UInt32 Property,
IntPtr PropertyRegDataType,
StringBuilder PropertyBuffer,
Int32 PropertyBufferSize,
IntPtr RequiredSize
);

[DllImport("Setupapi", SetLastError = true)]
public static extern IntPtr SetupDiOpenDevRegKey(
IntPtr hDeviceInfoSet,
ref DEVINFO_DATA deviceInfoData,
UInt32 scope,
UInt32 hwProfile,
UInt32 parameterRegistryValueKind,
UInt32 samDesired
);

[DllImport("advapi32.dll", EntryPoint = "RegQueryValueEx", CharSet = CharSet.Auto, SetLastError = true)]
static extern int RegQueryValueEx_getSize(
IntPtr hKey,
String lpValueName,
IntPtr lpReserved,
IntPtr lpType,
IntPtr lpData,
out Int32 lpcbData
);

[DllImport("advapi32.dll", EntryPoint = "RegQueryValueEx", CharSet = CharSet.Auto, SetLastError = true)]
static extern int RegQueryValueEx_getString(
IntPtr hKey,
String lpValueName,
IntPtr lpReserved,
IntPtr lpType,
StringBuilder lpData,
ref Int32 lpcbData
);

[DllImport("advapi32.dll", SetLastError = true)]
public static extern int RegCloseKey(
IntPtr hKey
);

static void Main(string[] args)
{
// device ID of CP210x VCP
// default VID/PID: 10C4/EA60
// for custom VID/PID, modify this string
String deviceID = @"USB\VID_10C4&PID_EA60\";

StringBuilder instanceID = new StringBuilder();
StringBuilder locationInfo = new StringBuilder();
StringBuilder portName = new StringBuilder();
String serialNumer;
Int32 requiredSize;

// Get Class GUID for PORTS class
Guid[] classGuidArray = new Guid[1];
if ( !SetupDiClassGuidsFromName( "PORTS", ref classGuidArray[0], 1, out requiredSize ) )
return;
// List up PORTS class devices in present
IntPtr hDevInfoSet = SetupDiGetClassDevs( ref classGuidArray[0], IntPtr.Zero, IntPtr.Zero, DIGCF_PRESENT );
if (hDevInfoSet == INVALID_HANDLE_VALUE)
return;
// Enumerate devices in the list
DEVINFO_DATA devInfo = new DEVINFO_DATA();
devInfo.cbSize = Marshal.SizeOf(devInfo);

for ( UInt32 deviceIndex = 0;
SetupDiEnumDeviceInfo( hDevInfoSet, deviceIndex, out devInfo );
deviceIndex++ )
{
// Get device instance ID
SetupDiGetDeviceInstanceId_getSize( hDevInfoSet, ref devInfo, IntPtr.Zero, 0, out requiredSize);
instanceID.EnsureCapacity( requiredSize );
SetupDiGetDeviceInstanceId_getString(hDevInfoSet, ref devInfo, instanceID, requiredSize, IntPtr.Zero);

// Check device ID
if ( !instanceID.ToString().StartsWith(deviceID, StringComparison.OrdinalIgnoreCase) )
continue;
// Split serial number
serialNumer = instanceID.ToString().Substring(deviceID.Length);

// Get location information
// For XP, LocationInformation value on registry hardware key holds
// iProduct string on the device
SetupDiGetDeviceRegistryProperty_getSize(hDevInfoSet, ref devInfo, SPDRP_LOCATION_INFORMATION, IntPtr.Zero,
IntPtr.Zero, 0, out requiredSize);
locationInfo.EnsureCapacity(requiredSize);
SetupDiGetDeviceRegistryProperty_getString(hDevInfoSet, ref devInfo, SPDRP_LOCATION_INFORMATION, IntPtr.Zero,
locationInfo, requiredSize, IntPtr.Zero);

// Open device parameters reg key
IntPtr hkey = SetupDiOpenDevRegKey(hDevInfoSet, ref devInfo, DICS_FLAG_GLOBAL,
0, DIREG_DEV, KEY_READ );
if (hkey == INVALID_HANDLE_VALUE)
continue;
// Qurey for portname
RegQueryValueEx_getSize( hkey, "PortName", IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, out requiredSize);
portName.EnsureCapacity( requiredSize );
RegQueryValueEx_getString(hkey, "PortName", IntPtr.Zero, IntPtr.Zero, portName, ref requiredSize);

// Close reg key
RegCloseKey( hkey );

Console.WriteLine("Port: " + portName + " Product ID: " + locationInfo + " Serial number: " + serialNumer);
}
// Destroy device info list
SetupDiDestroyDeviceInfoList( hDevInfoSet );
}
}
}

[This message has been edited by Tsuneo (edited April 27, 2010).]

IP: Logged

All times are CT (US)

next newest topic | next oldest topic

Administrative Options: Close Topic | Archive/Move | Delete Topic
Post New Topic  Post A Reply
Hop to:

Contact Us | MCU User Forum

Have you seen our MCU Knowledge Base?


Ultimate Bulletin Board 5.47b