2017-05-01 17 views
13

EDIT:完全なソースコードが要求されました。以下はバグを再現するためのベアボーン実装です。 コンテンツの列挙は、が削除されますが、最初のオブジェクトのクラッシュは、とにかく呼び出します。この場合、WPD_DEVICE_OBJECT_IDオブジェクト。WPD APIデバイスが電話機かどうかを検出しますか?

LINK TO CPPは、私は、モバイルデバイスの内容を読み取るためにWPD APIを使用して、私のプロジェクトでは(私はQtのを使用しています)

LINK TO QMAKE.PRO


(バグは、ライン103から始まります)。私は、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の脆弱性ですか?もしそうなら、私はこのデバイスがモバイルデバイスではないことをどのように事前に検出できますか?

ありがとうございました!

+1

その内容の列挙の完全な機能を見ずに手助けするのは非常に難しいがない場合 – geekonedge

+0

@kryptogeek遅れのために謝罪、何か他に取り組んでいた。私は問題を再現するスタンドアロンのC++アプリケーションを作成しました。この特定のTOSHIBA USBドライブが接続されていると、プログラムがクラッシュします。アンドロイド携帯電話が接続されている場合、すべて正常に動作します。 – mrg95

答えて

2

問題を特定するのに役立つお金を払ってしまった。

問題は、ルートオブジェクト(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; 
      } 
     } 
    } 

} 

ソリューションは、サンプルプロジェクトを行うことを示しまさにである、しかし、私は、ルートオブジェクトの名前をチェックするミスを犯しました。そうしないでください。何の「元のファイル名」

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

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

は、オブジェクト名を取得します。あなたは詳細を提供することができます
関連する問題