WPD API 检测设备是否为 Phone?
WPD API Detect if Device is a Phone?
编辑:已请求完整的源代码。下面是一个准系统实现,以复制错误。 内容枚举已被删除,但是无论如何在第一次对象调用时都会发生崩溃。在本例中,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
returns 失败,然后我的程序崩溃了。
经过一些研究,我发现异常代码 c0000417
意味着发生了缓冲区溢出?如果我错了请纠正我,但是,这是 WPD API 中的一个漏洞吗?如果是这样,我如何提前检测到此设备不是移动设备?
感谢您的宝贵时间!
我最终付钱请人帮我查明问题。
问题是根对象 (WPD_DEVICE_OBJECT_ID) 无论如何都不会 return 对象名称(并非所有设备都如此)。
解决方案是简单地从根对象开始内容枚举,并且只检查其子对象的名称。在我最初的实现中,我假设每个对象都有一个名称,但显然情况并非如此。根对象是例外。
这是一个片段:
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;
}
}
}
}
解决方案正是示例项目显示要做的,但是,我在检查根对象的名称时犯了错误。所以不要那样做。
如果没有则获取对象名"original file name"
hr = pObjectProperties->GetStringValue(WPD_OBJECT_ORIGINAL_FILE_NAME, &objectName);
if(FAILED(hr)) {
hr = pObjectProperties->GetStringValue(WPD_OBJECT_NAME, &objectName);
}
编辑:已请求完整的源代码。下面是一个准系统实现,以复制错误。 内容枚举已被删除,但是无论如何在第一次对象调用时都会发生崩溃。在本例中,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
returns 失败,然后我的程序崩溃了。
经过一些研究,我发现异常代码 c0000417
意味着发生了缓冲区溢出?如果我错了请纠正我,但是,这是 WPD API 中的一个漏洞吗?如果是这样,我如何提前检测到此设备不是移动设备?
感谢您的宝贵时间!
我最终付钱请人帮我查明问题。
问题是根对象 (WPD_DEVICE_OBJECT_ID) 无论如何都不会 return 对象名称(并非所有设备都如此)。
解决方案是简单地从根对象开始内容枚举,并且只检查其子对象的名称。在我最初的实现中,我假设每个对象都有一个名称,但显然情况并非如此。根对象是例外。
这是一个片段:
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;
}
}
}
}
解决方案正是示例项目显示要做的,但是,我在检查根对象的名称时犯了错误。所以不要那样做。
如果没有则获取对象名"original file name"
hr = pObjectProperties->GetStringValue(WPD_OBJECT_ORIGINAL_FILE_NAME, &objectName);
if(FAILED(hr)) {
hr = pObjectProperties->GetStringValue(WPD_OBJECT_NAME, &objectName);
}