Click here to Skip to main content
15,918,889 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am using SetupDiGetDeviceRegistryProperty from setupapi in Visual Studio. If I use the Multicharacter set, the byte pointer (BYTE* friendlyName) gives the correct FRIENDLYNAME. However, when I compile it using the Unicode Character set, the returned friendlyName has a NULL character behind every value in the byte array.

Here's the code snippet:

SetupDiGetDeviceRegistryProperty(hDeviceInfo, &devInfoData, SPDRP_FRIENDLYNAME, nullptr, nullptr, 0, &reqSize);
BYTE* friendlyName = new BYTE[300]; //(reqSize > 1) ? reqSize : 1];

if (!SetupDiGetDeviceRegistryProperty(hDeviceInfo, &devInfoData, SPDRP_FRIENDLYNAME, nullptr, friendlyName, sizeof(friendlyName) * reqSize, nullptr))
// device does not have this property set
memset(friendlyName, 0, reqSize > 1 ? reqSize : 1);

What I have tried:

I have tried changing the BYTE array (unsigned char) to byte with the same results. If I try to change it to char, the compiler isn't working.

I also set the array to a set size instead of allowing the function to define the reqSize because of the NULL after the first character.
Updated 17-Apr-19 13:39pm

1 solution

This behavior is by design because that is the nature of Unicode characters. The lower batch, below value 256, have a zero following them because they are (generally) a 16-bit value so the MSB will be zero.

I would use the TCHAR macros if you are going to compile in both modes. Here's an example:
const int BufferSize = 299;
TCHAR friendlyName[BufferSize+1] = { 0 };

if( ! SetupDiGetDeviceRegistryProperty( hDeviceInfo, &devInfoData,
          SPDRP_FRIENDLYNAME, nullptr,
          friendlyName, BufferSize, nullptr ) )
    TRACE( _T( "device does not have this property set\n" ) );
Share this answer
Rick York 17-Apr-19 19:56pm    
note - I'm not sure if that's the right way to use SetDiGetDeviceRegistryProperty. I was just guessing based on your code.
Member 12557572 18-Apr-19 11:30am    
Rick, Tried to use TCHAR. The compile errors return "cannot convert argument from TCHAR to PBYTE". Is there something I need to set up in the includes or properties that allows me to use TCHAR?
Rick York 18-Apr-19 12:02pm    
You have to include tchar.h and define _UNICODE and/or UNICODE in your project's preprocessor settings.
Member 12557572 18-Apr-19 13:27pm    
I did these things and still got the compile error. But then I cast friendlyName as a PBYTE. When I did that, it performed as expected, without null characters after each "valid" character. Thanks for your help.
Dean Roddey 18-Apr-19 14:54pm    
Cast it to a (BYTE*) when you pass it into the API which is expecting an array of bytes. After it is filled in, and you look at it via the TCHAR pointer, then it will be correct. OR, keep it a BYTE* type array, and then cast it to a TCHAR to look at it afterwards, one way or another.

const TCHAR* realName = reinterpret_cast<const TChar*>(friendlyName);

realName will then be looking at the buffer via the correct type and should work correctly.

Of course be sure to clean up the buffer at some point.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900