c++ - WPD API 检测设备是否是电话?

标签 c++ debugging exception buffer-overflow wpd

编辑:请求了完整的源代码。下面是一个准系统实现,以复制该错误。 删除了内容枚举,但无论如何都会在第一个对象调用时发生崩溃。在这种情况下,WPD_DEVICE_OBJECT_ID 对象。

LINK TO CPP (错误从第 103 行开始)

LINK TO QMAKE.PRO (我正在使用 Qt)


在我的项目中,我使用 WPD API读取移动设备的内容。我按照 API 进行了开发,并成功实现了内容枚举。

但是,如果连接了 USB 驱动器,WPD API 有时也会将其检测为设备。无论如何,我的程序将继续进行内容枚举。我不想要那个。我只想列举移动设备。

问题在于,在内容枚举期间,当我的程序尝试检索 USB 驱动器上对象的属性时,它会崩溃。以下是崩溃详情:

Problem Event Name: BEX
Application Name:   UniversalMC.exe
Application Version:    0.0.0.0
Application Timestamp:  5906a8a3
Fault Module Name:  MSVCR100.dll
Fault Module Version:   10.0.40219.325
Fault Module Timestamp: 4df2be1e
Exception Offset:   0008af3e
Exception Code: c0000417
Exception Data: 00000000
OS Version: 6.1.7601.2.1.0.768.3
Locale ID:  1033
Additional Information 1:   185e
Additional Information 2:   185ef2beb7eb77a8e39d1dada57d0d11
Additional Information 3:   a852
Additional Information 4:   a85222a7fc0721be22726bd2ca6bc946

此调用发生崩溃:

hr = pObjectProperties->GetStringValue(WPD_OBJECT_ORIGINAL_FILE_NAME, &objectName);

hr 返回 FAILED 然后我的程序崩溃了。

经过一番研究,我发现异常代码 c0000417 表示发生缓冲区溢出?如果我错了,请纠正我,但这是 WPD API 中的漏洞吗?如果是这样,我怎样才能提前检测到此设备不是移动设备?

感谢您的宝贵时间!

最佳答案

我最终花钱请人帮我查明问题。

问题在于根对象 (WPD_DEVICE_OBJECT_ID) 无论如何都不会返回对象名称(并非所有设备都如此)。

解决方案是简单地从根对象开始内容枚举,并且只检查其子对象的名称。在我最初的实现中,我假设每个对象都有一个名称,但显然情况并非如此。根对象是异常(exception)。

这是一个片段:

CComPtr<IEnumPortableDeviceObjectIDs> pEnumObjectIDs;

// Print the object identifier being used as the parent during enumeration.
//qDebug("%ws\n",pszObjectID);

// Get an IEnumPortableDeviceObjectIDs interface by calling EnumObjects with the
// specified parent object identifier.
hr = pContent->EnumObjects(0,               // Flags are unused
                                   WPD_DEVICE_OBJECT_ID,     // Starting from the passed in object
                                   NULL,            // Filter is unused
                                   &pEnumObjectIDs);

// Enumerate content starting from the "DEVICE" object.
if (SUCCEEDED(hr))
{
    // Loop calling Next() while S_OK is being returned.
    while(hr == S_OK)
    {
        DWORD  cFetched = 0;
        PWSTR  szObjectIDArray[NUM_OBJECTS_TO_REQUEST] = {0};
        hr = pEnumObjectIDs->Next(NUM_OBJECTS_TO_REQUEST,   // Number of objects to request on each NEXT call
                                  szObjectIDArray,          // Array of PWSTR array which will be populated on each NEXT call
                                  &cFetched);               // Number of objects written to the PWSTR array
        if (SUCCEEDED(hr))
        {
            // Traverse the results of the Next() operation and recursively enumerate
            // Remember to free all returned object identifiers using CoTaskMemFree()
            for (DWORD dwIndex = 0; dwIndex < cFetched; dwIndex++)
            {
                //RECURSIVE CONTENT ENUMERATION CONTINUES HERE
                //OBJECT NAME CHECKING CONTINUES IN THE RECURSIVE FUNCTION

                // Free allocated PWSTRs after the recursive enumeration call has completed.
                CoTaskMemFree(szObjectIDArray[dwIndex]);
                szObjectIDArray[dwIndex] = NULL;
            }
        }
    }

}

解决方案正是示例项目所显示的,但是,我犯了检查根对象名称的错误。所以不要那样做。

关于c++ - WPD API 检测设备是否是电话?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43713994/

相关文章:

c++ - Windows 中 MSYS 与 MinGW 的需求是什么

java - 异常处理,catch导致while循环停止

充满抽象对象的 C++ 容器

c++ - boost::geometry 无法识别三个点在一条线上(boost::geometry::difference 失败)

python - PyCharm - 如何暂停所有线程

Java Runtime exec 使用中断调试 native cpp 应用程序

c++ - g++ -fno-enforce-eh-specs - 为什么/如何违反 C++ 标准?

c++ - 谁来管理参数中复制构造函数抛出的异常?

c++ - CMake 包含没有文件夹前缀的项目文件

actionscript-3 - Actionscript 3.0 中的行号常量?