为什么PSTR类型在不同的Visual Studio项目类型上有不同的行为?

时间:2015-08-18 12:43:21

标签: 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()
#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;
}

DeviceDescName是PSTR,您可以从代码中看到。出于某种原因,这适用于一个项目类型 Windows驱动程序应用程序。在这里,我看到完整的设备名称DeviceDescName,如&#34;高清晰度音频控制器&#34;。

相同的代码不适用于其他控制台应用程序。工具集v120 。在DeviceDescName中,我只看到第一个&#34; H&#34;(来自&#34;高清晰度音频控制器&#34;)。可能是什么原因? (你可以试试这个)

1 个答案:

答案 0 :(得分:2)

这是因为驱动程序项目编译为UNICODEPSTR编译为WCHAR *,而您的控制台应用程序未编译为UNICODEPSTR为呈现为CHAR *

您可以通过调整设置来尝试将控制台应用程序编译为UNICODE,但这可能会导致问题,除非您的代码经过仔细编写并使用正确的类型 - 而且听起来并非如此。

另一种方法是对此代码(和其他类似实例)使用PWSTR,它始终是一个宽字符串。