WPD API Определить, является ли устройство телефоном?

РЕДАКТИРОВАТЬ: полный исходный код был запрошен. Ниже приведена базовая реализация для того, чтобы повторить ошибку. Перечисление контента удалено, однако в любом случае происходит авария на первом объекте. В этом случае объект WPD_DEVICE_OBJECT_ID.

ССЫЛКА НА CPP (Ошибка начинается со строки 103)

ССЫЛКА НА 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? Если да, то как я могу заранее определить, что это устройство не является мобильным устройством?

Спасибо за ваше время!

13

Решение

Я заплатил кому-то, чтобы помочь мне точно определить проблему.

Проблема заключалась в том, что корневой объект (WPD_DEVICE_OBJECT_ID) не возвращал бы имя объекта, несмотря ни на что (не верно для всех устройств).

Решение состояло в том, чтобы просто начать перечисление содержимого ОТ корневого объекта и проверять только имена его дочерних объектов. В моей первоначальной реализации я предполагал, что у каждого объекта есть имя, но, очевидно, это не так. Корневой объект является исключением.

Вот фрагмент:

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;
}
}
}

}

Решение — именно то, что показывает пример проекта, однако я сделал ошибку, проверив имя корневого объекта. Так что не делай этого.

2

Другие решения

Получить имя объекта, если нет «исходного имени файла»

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

if(FAILED(hr)) {
hr = pObjectProperties->GetStringValue(WPD_OBJECT_NAME, &objectName);
}
0

По вопросам рекламы [email protected]