Поделиться через


Перечисление устройств (WPD)

Первая задача, выполненная большинством приложений, — это перечисление устройств, подключенных к компьютеру. Эта задача и получение сведений об устройстве (например, о производителе, понятном имени и описании) поддерживается интерфейсом IPortableDeviceManager .

Функция EnumerateAllDevices в модуле DeviceEnumeration.cpp содержит код, демонстрирующий получение количества подключенных устройств, а после получения этого числа — получение сведений для каждого подключенного устройства.

Функция EnumerateAllDevices выполняет четыре основные задачи:

  1. Создает объект диспетчера переносимых устройств.
  2. Извлекает количество подключенных устройств.
  3. Извлекает сведения об устройстве (для подключенных устройств).
  4. Освобождает память, используемую при получении сведений об устройстве.

Каждая из этих четырех задач более подробно описана в следующих разделах.

Первым шагом в процессе перечисления устройств является создание переносимого объекта диспетчера устройств. Это делается путем вызова функции CoCreateInstance и передачи идентификатора класса (CLSID) для объекта, указания контекста, в котором будет выполняться код, указания идентификатора ссылки для интерфейса IPortableDeviceManager, а затем предоставления переменной указателя, которая получает указатель интерфейса IPortableDeviceManager.

HRESULT hr = CoCreateInstance(CLSID_PortableDeviceManager,
                              NULL,
                              CLSCTX_INPROC_SERVER,
                              IID_PPV_ARGS(&pPortableDeviceManager));
if (FAILED(hr))
{
    printf("! Failed to CoCreateInstance CLSID_PortableDeviceManager, hr = 0x%lx\n",hr);
}

Получив указатель на интерфейс IPortableDeviceManager , можно приступить к вызову методов в этом интерфейсе. Первый метод, вызываемый в функции EnumerateAllDevices, — это IPortableDeviceManager::GetDevices. При вызове этого метода с первым аргументом, равным NULL, возвращается количество подключенных устройств.

if (SUCCEEDED(hr))
{
    hr = pPortableDeviceManager->GetDevices(NULL, &cPnPDeviceIDs);
    if (FAILED(hr))
    {
        printf("! Failed to get number of devices on the system, hr = 0x%lx\n",hr);
    }
}

// Report the number of devices found.  NOTE: we will report 0, if an error
// occured.

printf("\n%d Windows Portable Device(s) found on the system\n\n", cPnPDeviceIDs);

После получения количества подключенных устройств это значение можно использовать для получения сведений об устройстве для каждого подключенного устройства. Этот процесс начинается с передачи массива строковых указателей в качестве первого аргумента и количества элементов, которые этот массив может содержать в качестве второго аргумента (это число должно быть по крайней мере равно количеству доступных устройств).

Строки, возвращаемые этим методом, являются Plug and Play именами подключенных устройств. Эти имена, в свою очередь, передаются другим методам в интерфейсе IPortableDeviceManager для получения сведений об устройстве, таких как понятное имя, имя производителя и описание устройства. (Эти имена также используются для открытия подключения к устройству, когда приложение вызывает метод IPortableDevice::Open .)

if (SUCCEEDED(hr) && (cPnPDeviceIDs > 0))
{
    pPnpDeviceIDs = new (std::nothrow) PWSTR[cPnPDeviceIDs];
    if (pPnpDeviceIDs != NULL)
    {
        DWORD dwIndex = 0;

        hr = pPortableDeviceManager->GetDevices(pPnpDeviceIDs, &cPnPDeviceIDs);
        if (SUCCEEDED(hr))
        {
            // For each device found, display the devices friendly name,
            // manufacturer, and description strings.
            for (dwIndex = 0; dwIndex < cPnPDeviceIDs; dwIndex++)
            {
                printf("[%d] ", dwIndex);
                DisplayFriendlyName(pPortableDeviceManager, pPnpDeviceIDs[dwIndex]);
                printf("    ");
                DisplayManufacturer(pPortableDeviceManager, pPnpDeviceIDs[dwIndex]);
                printf("    ");
                DisplayDescription(pPortableDeviceManager, pPnpDeviceIDs[dwIndex]);
            }
        }
        else
        {
            printf("! Failed to get the device list from the system, hr = 0x%lx\n",hr);
        }

После получения сведений об устройстве необходимо освободить память, связанную со строками, на которые указывает массив строковых указателей. Вам также потребуется удалить этот массив.

for (dwIndex = 0; dwIndex < cPnPDeviceIDs; dwIndex++)
{
    CoTaskMemFree(pPnpDeviceIDs[dwIndex]);
    pPnpDeviceIDs[dwIndex] = NULL;
}

// Delete the array of PWSTR pointers
delete [] pPnpDeviceIDs;
pPnpDeviceIDs = NULL;

Интерфейс IPortableDeviceManager

Руководство по программированию