2017-05-01 5 views
13

EDIT: Vollständiger Quellcode wurde angefordert. Unten ist eine Barebone-Implementierung, um den Fehler zu replizieren. Die Inhaltsaufzählung wurde entfernt, jedoch tritt der Absturz beim ersten Objektaufruf trotzdem auf. In diesem Fall das WPD_DEVICE_OBJECT_ID-Objekt.WPD-API Erkennen, ob Gerät ein Telefon ist?

LINK TO CPP (Bug beginnt in Zeile 103)

LINK TO QMAKE.PRO (Ich bin mit Qt)


In meinem Projekt habe ich die WPD API, um den Inhalt eines mobilen Gerätes zu lesen. Ich folgte der API zu einem T-Stück und habe Content Enumeration erfolgreich implementiert.

Wenn jedoch ein USB-Laufwerk angeschlossen ist, erkennt die WPD-API dies manchmal auch als Gerät. Mein Programm wird fortgesetzt und beginnt trotzdem mit der Inhaltsaufzählung. Ich will das nicht. Ich möchte nur mobile Geräte aufzählen.

Das Problem ist, dass während der Inhaltsauflistung, wenn mein Programm versucht, eine Eigenschaft eines Objekts auf dem USB-Laufwerk abzurufen, es abstürzt. Hier sind die Crash-Details:

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 

Der Absturz tritt bei diesem Aufruf:

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

hr kehrt FAILED und dann mein Programm stürzt ab.

Nach einigen Recherchen habe ich festgestellt, dass Ausnahmecode c0000417 bedeutet, dass ein Pufferüberlauf aufgetreten ist? Korrigiere mich, wenn ich falsch liege, aber ist das eine Schwachstelle in der WPD-API? Wenn ja, wie könnte ich im Voraus erkennen, dass dieses Gerät kein mobiles Gerät ist?

Danke für Ihre Zeit!

+1

Sein ziemlich schwer, die volle Funktion des Inhalts Aufzählung zu helfen, ohne zu sehen. Können Sie das Detail bitte zur Verfügung stellen – geekonedge

+0

@kryptogeek Entschuldigung für die Verzögerung, arbeitete an etwas anderem. Ich habe eine eigenständige C++ - Anwendung erstellt, die das Problem repliziert. Wenn dieses spezielle TOSHIBA USB-Laufwerk angeschlossen ist, stürzt das Programm ab. Wenn ein Android-Telefon angeschlossen ist, läuft alles gut. – mrg95

Antwort

2

Ich endete damit, jemanden zu bezahlen, der mir half, das Problem zu lokalisieren.

Das Problem bestand darin, dass das Stammobjekt (WPD_DEVICE_OBJECT_ID) keinen Objektnamen zurückgab, egal was (nicht für alle Geräte zutreffend).

Die Lösung bestand darin, einfach Inhaltsauflistung von dem Stammobjekt zu beginnen und nur die Namen seiner untergeordneten Objekte zu überprüfen. In meiner ursprünglichen Implementierung nahm ich an, dass jedes Objekt einen Namen hat, aber das ist offensichtlich nicht der Fall. Das Root-Objekt ist die Ausnahme. Hier

ist ein Ausschnitt:

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

} 

Die Lösung ist genau das, was das Beispielprojekt zu tun, zeigt aber machte ich den Fehler, den Namen des Root-Objekts zu überprüfen. Also tu das nicht.

0

den Objektnamen, wenn es keine „Originaldateiname“ ist

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

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