2017-05-01 42 views
13

編輯:完整的源代碼被要求。下面是一個準系統實施,以複製錯誤。 內容枚舉被刪除,但是無論如何,第一個對象的調用崩潰。在這種情況下,WPD_DEVICE_OBJECT_ID對象。WPD API檢測設備是否是電話?

LINK TO CPP(錯誤始於線103)

LINK TO QMAKE.PRO(我使用Qt)


在項目中,我使用WPD API讀取移動設備的內容。我跟隨API開發了一個T恤,併成功實現了內容枚舉。

但是,如果連接了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返回,接着我的程序崩潰。

經過一番研究,我發現異常代碼c0000417意味着發生了緩衝區溢出?糾正我,如果我錯了,但是,這是WPD API中的漏洞嗎?如果是這樣,我如何提前檢測到此設備不是移動設備?

謝謝你的時間!

+1

它很努力幫助沒有看到內容列舉的全部功能。你能否提供詳情請致電 – geekonedge

+0

@ kryptogeek對於延誤的歉意,正在處理其他事情。我創建了一個複製問題的獨立C++應用程序。如果連接了特定的東芝USB驅動器,則程序崩潰。如果連接Android手機,一切運行良好。 – 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; 
      } 
     } 
    } 

} 

的解決方案是什麼樣的項目顯示了這樣做,不過,我做了檢查根對象的名稱的錯誤。所以不要這樣做。

0

獲取對象的名字,如果沒有「原文件名」

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

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