Подтвердить что ты не робот

WPD API Обнаружение, если устройство является телефоном?

EDIT: запрошен полный исходный код. Ниже приведена реализация barebones для репликации ошибки. Перечисление содержимого удаляется, однако авария в любом случае вызывает обход первого вызова объекта. В этом случае объект WPD_DEVICE_OBJECT_ID.

LINK TO 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? Если да, то как я мог заранее обнаружить, что это устройство не является мобильным устройством?

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

4b9b3361

Ответ 1

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

Проблема заключалась в том, что корневой объект (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);
}