C 为什么PSTR类型在不同的VisualStudio项目类型上有不同的行为?
我有以下代码枚举设备并将其描述写入控制台:C 为什么PSTR类型在不同的VisualStudio项目类型上有不同的行为?,c,string,C,String,我有以下代码枚举设备并将其描述写入控制台: #include <windows.h> #include <setupapi.h> #include <stdio.h> #include <tchar.h> #ifdef DEBUG #undef DBG #define DBG 1 #endif #if DBG #define OOPS() Oops(__FILE__, __LINE__) #else #define OOPS() #en
#include <windows.h>
#include <setupapi.h>
#include <stdio.h>
#include <tchar.h>
#ifdef DEBUG
#undef DBG
#define DBG 1
#endif
#if DBG
#define OOPS() Oops(__FILE__, __LINE__)
#else
#define OOPS()
#endif
#define ALLOC(dwBytes) GlobalAlloc(GPTR,(dwBytes))
#define REALLOC(hMem, dwBytes) GlobalReAlloc((hMem), (dwBytes), (GMEM_MOVEABLE|GMEM_ZEROINIT))
#define FREE(hMem) GlobalFree((hMem))
#define CHECKFORLEAKS()
_Success_(return == TRUE)
BOOL
GetDeviceProperty(
_In_ HDEVINFO DeviceInfoSet,
_In_ PSP_DEVINFO_DATA DeviceInfoData,
_In_ DWORD Property,
_Outptr_ LPTSTR *ppBuffer
)
{
BOOL bResult;
DWORD requiredLength = 0;
DWORD lastError;
if(ppBuffer == NULL)
{
return FALSE;
}
*ppBuffer = NULL;
bResult = SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
DeviceInfoData,
Property,
NULL,
NULL,
0,
&requiredLength);
lastError = GetLastError();
if((requiredLength == 0) || (bResult != FALSE && lastError != ERROR_INSUFFICIENT_BUFFER))
{
return FALSE;
}
*ppBuffer = ALLOC(requiredLength);
if(*ppBuffer == NULL)
{
return FALSE;
}
bResult = SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
DeviceInfoData,
Property,
NULL,
(PBYTE)*ppBuffer,
requiredLength,
&requiredLength);
if(bResult == FALSE)
{
FREE(*ppBuffer);
*ppBuffer = NULL;
return FALSE;
}
return TRUE;
}
void
EnumerateAllDevices(
)
{
HDEVINFO deviceInfo = NULL;
// Getting all present devices
deviceInfo = SetupDiGetClassDevs(NULL,
NULL,
NULL,
(DIGCF_ALLCLASSES | DIGCF_PRESENT));
if(deviceInfo != INVALID_HANDLE_VALUE)
{
ULONG index;
DWORD error;
error = 0;
index = 0;
while(error != ERROR_NO_MORE_ITEMS)
{
BOOL success;
SP_DEVINFO_DATA infoData;
ZeroMemory(&infoData, sizeof(SP_DEVINFO_DATA));
PSTR DeviceDescName = NULL;
infoData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
success = SetupDiEnumDeviceInfo(deviceInfo,
index,
&infoData);
index++;
if(success == FALSE)
{
error = GetLastError();
if(error != ERROR_NO_MORE_ITEMS)
{
//OOPS();
}
}
else
{
BOOL bResult;
bResult = GetDeviceProperty(deviceInfo,
&infoData,
SPDRP_DEVICEDESC,
&DeviceDescName);
if(bResult == FALSE)
{
//OOPS();
break;
}
printf("DeviceDescName = %s\n", DeviceDescName);
}
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
EnumerateAllDevices();
return 0;
}
#包括
#包括
#包括
#包括
#ifdef调试
#未定义DBG
#定义DBG1
#恩迪夫
#if-DBG
#定义OOPS()OOPS(_文件,_行)
#否则
#定义OOPS()
#恩迪夫
#定义ALLOC(dwBytes)GlobalAlloc(GPTR(dwBytes))
#定义REALLOC(hMem,dwBytes)GlobalReAlloc((hMem),(dwBytes),(GMEM_MOVEABLE | GMEM_zeronit))
#定义自由(hMem)全局自由((hMem))
#定义CHECKFORLEAKS()
_成功(返回=TRUE)
布尔
GetDeviceProperty(
_在设备信息集中,
_在PSP设备信息数据设备信息数据中,
_在沃德酒店,
_Outptr_uLptstr*ppBuffer
)
{
布尔·布雷苏特;
DWORD requiredLength=0;
德沃德拉斯特错误;
if(ppBuffer==NULL)
{
返回FALSE;
}
*ppBuffer=NULL;
bResult=SetupDiGetDeviceRegistrProperty(设备信息集,
DeviceInfo数据,
财产,,
无效的
无效的
0,
&所需长度);
lastError=GetLastError();
if((requiredLength==0)| |(bResult!=FALSE&&lastError!=ERROR\u缓冲区不足))
{
返回FALSE;
}
*ppBuffer=ALLOC(所需长度);
如果(*ppBuffer==NULL)
{
返回FALSE;
}
bResult=SetupDiGetDeviceRegistrProperty(设备信息集,
DeviceInfo数据,
财产,,
无效的
(PBYTE)*ppBuffer,
所需长度,
&所需长度);
if(bResult==FALSE)
{
自由(*ppBuffer);
*ppBuffer=NULL;
返回FALSE;
}
返回TRUE;
}
无效的
列举所有设备(
)
{
HDEVINFO deviceInfo=NULL;
//获取所有现有设备
deviceInfo=SetupDiGetClassDevs(空,
无效的
无效的
(DIGCF_所有类别| DIGCF_存在));
if(deviceInfo!=无效的\u句柄\u值)
{
乌龙指数;
德沃德误差;
误差=0;
指数=0;
while(错误!=错误\u无\u更多项目)
{
成功;
SP_DEVINFO_数据信息数据;
零内存(&infoData,sizeof(SP_DEVINFO_DATA));
PSTR DeviceDescName=NULL;
infoData.cbSize=sizeof(SP_设备_接口_数据);
成功=SetupDiEnumDeviceInfo(设备信息,
指数
&信息数据);
索引++;
if(success==FALSE)
{
error=GetLastError();
如果(错误!=错误\u无\u更多\u项)
{
//OOPS();
}
}
其他的
{
布尔·布雷苏特;
bResult=GetDeviceProperty(deviceInfo,
&信息数据,
SPDRP_设备ESC,
&设备名称);
if(bResult==FALSE)
{
//OOPS();
打破
}
printf(“DeviceDescName=%s\n”,DeviceDescName);
}
}
}
}
int _tmain(int argc,_TCHAR*argv[]
{
枚举所有设备();
返回0;
}
正如您从代码中看到的,DeviceDescName是PSTR。出于某些原因,这非常适合于一个项目类型的Windows驱动程序应用程序。这里我看到了完整的设备名称DeviceDescName,如“高清音频控制器”
相同的代码不适用于其他控制台应用程序。工具集v120。在DeviceDescName中,我只看到后面的第一个“H”(来自“高清音频控制器”)。原因可能是什么?(您可以尝试此操作)这是因为驱动程序项目被编译为
UNICODE
,PSTR
指向WCHAR*
,而您的控制台应用程序没有编译为UNICODE
,PSTR
被呈现为CHAR*
通过调整设置,您可以尝试将控制台应用程序编译为UNICODE,但这可能会导致问题,除非您的代码编写得很仔细,并且使用了正确的类型——听起来好像不是这样
另一种方法是使用
PWSTR
来处理此代码(以及其他类似的实例),它将始终是一个宽字符串。我认为这是关于接近正确答案的不同字符编码(ascii、ansi、unicode等),但realy驱动程序项目默认情况下不是unicode,而cosole应用程序是unicode。。从项目属性中删除unicode字符集后,它就开始工作了。请回答正确,我会接受的。