다음을 통해 공유


여러 개체에 대한 속성 검색

일부 디바이스 드라이버는 단일 함수 호출에서 여러 개체에 대한 속성 검색을 지원합니다. 이를 대량 검색이라고 합니다. 대량 검색 작업에는 두 가지 유형이 있습니다. 첫 번째 형식은 개체 목록에 대한 속성을 검색하고 두 번째 형식은 지정된 형식의 모든 개체에 대한 속성을 검색합니다. 이 섹션에 설명된 예제에서는 전자를 보여 줍니다.

애플리케이션은 다음 표에 설명된 인터페이스를 사용하여 대량 검색을 수행할 수 있습니다.

인터페이스 Description
IPortableDeviceContent 인터페이스 콘텐츠별 메서드에 대한 액세스를 제공합니다.
IPortableDeviceKeyCollection 인터페이스 검색할 속성을 식별하는 데 사용됩니다.
IPortableDeviceProperties 인터페이스 지정된 드라이버가 대량 작업을 지원하는지 여부를 확인하는 데 사용됩니다.
IPortableDevicePropertiesBulk 인터페이스 대량 검색 작업을 지원합니다.
IPortableDevicePropVariantCollection 인터페이스 대량 작업에 대한 개체 식별자를 저장하는 데 사용됩니다.

 

샘플 애플리케이션의 ContentProperties.cpp 모듈에 있는 ReadContentPropertiesBulk 함수는 대량 검색 작업을 보여 줍니다.

이 샘플에서 수행된 첫 번째 작업은 지정된 드라이버가 대량 작업을 지원하는지 여부를 결정하는 것입니다. 이 작업은 IPortableDeviceProperties 인터페이스에서 QueryInterface를 호출하고 IPortableDevicePropertiesBulk의 존재를 확인하여 수행됩니다.

HRESULT                                       hr                = S_OK;
GUID                                          guidContext       = GUID_NULL;
CGetBulkValuesCallback*                       pCallback         = NULL;
CComPtr<IPortableDeviceProperties>            pProperties;
CComPtr<IPortableDevicePropertiesBulk>        pPropertiesBulk;
CComPtr<IPortableDeviceValues>                pObjectProperties;
CComPtr<IPortableDeviceContent>               pContent;
CComPtr<IPortableDeviceKeyCollection>         pPropertiesToRead;
CComPtr<IPortableDevicePropVariantCollection> pObjectIDs;


if (SUCCEEDED(hr))
{
    hr = pDevice->Content(&pContent);
    if (FAILED(hr))
    {
        printf("! Failed to get IPortableDeviceContent from IPortableDevice, hr = 0x%lx\n",hr);
    }
}



if (SUCCEEDED(hr))
{
    hr = pContent->Properties(&pProperties);
    if (FAILED(hr))
    {
        printf("! Failed to get IPortableDeviceProperties from IPortableDevice, hr = 0x%lx\n",hr);
    }
}



if (SUCCEEDED(hr))
{
    hr = pProperties->QueryInterface(IID_PPV_ARGS(&pPropertiesBulk));
    if (FAILED(hr))
    {
        printf("This driver does not support BULK property operations.\n");
    }
}

드라이버가 대량 작업을 지원하는 경우 다음 단계는 IPortableDeviceKeyCollection 인터페이스의 instance 만들고 애플리케이션이 검색할 속성에 해당하는 키를 지정하는 것입니다. 이 프로세스에 대한 설명은 단일 개체에 대한 속성 검색 항목을 참조하세요.

적절한 키를 지정한 후 샘플 애플리케이션은 IPortableDevicePropertiesBulkCallback 인터페이스의 instance 만듭니다. 애플리케이션은 이 인터페이스의 메서드를 사용하여 비동기 대량 검색 작업의 진행률을 추적합니다.

if (SUCCEEDED(hr))
{
    pCallback = new CGetBulkValuesCallback();
    if (pCallback == NULL)
    {
        hr = E_OUTOFMEMORY;
        printf("! Failed to allocate CGetBulkValuesCallback, hr = 0x%lx\n", hr);
    }
}

샘플 애플리케이션에서 호출하는 다음 함수는 CreateIPortableDevicePropVariantCollectionWithAllObjectIDs 도우미 함수입니다. 이 함수는 예를 들어 사용 가능한 모든 개체 식별자 목록을 만듭니다. (실제 애플리케이션은 식별자 목록을 특정 개체 집합으로 제한합니다. instance 경우 애플리케이션은 현재 지정된 폴더 보기에 있는 모든 개체에 대한 식별자 목록을 만들 수 있습니다.)

위에서 설명한 것처럼 도우미 함수는 지정된 디바이스의 모든 개체를 재귀적으로 열거합니다. 찾은 각 개체에 대한 식별자가 포함된 IPortableDevicePropVariantCollection 인터페이스 에서 이 목록을 반환합니다. 도우미 함수는 ContentEnumeration.cpp 모듈에 정의되어 있습니다.

// 7) Call our helper function CreateIPortableDevicePropVariantCollectionWithAllObjectIDs
// to enumerate and create an IPortableDevicePropVariantCollection with the object
// identifiers needed to perform the bulk operation on.
if (SUCCEEDED(hr))
{
    hr = CreateIPortableDevicePropVariantCollectionWithAllObjectIDs(pDevice,
                                                                    pContent,
                                                                    &pObjectIDs);
}

이전 단계가 완료되면 샘플 애플리케이션은 비동기 속성 검색을 시작합니다. 이 작업은 다음을 수행하여 수행됩니다.

  1. 대량 속성 검색에 대한 요청을 큐에 대기하는 IPortableDevicePropertiesBulk::QueueGetValuesByObjectList를 호출합니다. (요청이 큐에 대기되어 있지만 시작되지는 않습니다.)
  2. IPortableDevicePropertiesBulk::Start를 호출하여 대기 요청을 시작합니다.

이러한 단계는 샘플 애플리케이션에서 발췌한 다음 코드에서 설명합니다.

   if (SUCCEEDED(hr))
   {
       hr = pPropertiesBulk->QueueGetValuesByObjectList(pObjectIDs,
                                                        pPropertiesToRead,
                                                        pCallback,
                                                        &guidContext);


       if(SUCCEEDED(hr))
       {
           // Cleanup any previously created global event handles.
           if (g_hBulkPropertyOperationEvent != NULL)
           {
               CloseHandle(g_hBulkPropertyOperationEvent);
               g_hBulkPropertyOperationEvent = NULL;
           }

           // In order to create a simpler to follow example we create and wait infinitly
           // for the bulk property operation to complete and ignore any errors.
           // Production code should be written in a more robust manner.
           // Create the global event handle to wait on for the bulk operation
           // to complete.
           g_hBulkPropertyOperationEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
           if (g_hBulkPropertyOperationEvent != NULL)
           {
               // Call Start() to actually being the Asynchronous bulk operation.
               hr = pPropertiesBulk->Start(guidContext);
               if(FAILED(hr))
               {
                   printf("! Failed to start property operation, hr = 0x%lx\n", hr);
               }
           }
           else
           {
               printf("! Failed to create the global event handle to wait on for the bulk operation. Aborting operation.\n");
           }
       }
       else
       {
           printf("! QueueGetValuesByObjectList Failed, hr = 0x%lx\n", hr);
       }
   }

IPortableDevice 인터페이스

IPortableDeviceContent 인터페이스

IPortableDeviceKeyCollection 인터페이스

IPortableDeviceProperties 인터페이스

IPortableDevicePropertiesBulk 인터페이스

IPortableDevicePropVariantCollection 인터페이스

프로그래밍 가이드