2017-05-01 12 views
13

편집 : 전체 소스 코드를 요청했습니다. 아래는 버그를 복제하기위한 베어 본 구현입니다. 콘텐츠 열거 형은으로 제거되지만 어쨌든 첫 번째 개체에서 충돌이 발생합니다. 이 경우, 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 실패 수익률과 내 프로그램 충돌.

일부 연구 결과 예외 코드 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

는 개체의 이름을 가져옵니다. 당신은 세부 사항을 제공 할 수 있습니다