デバイスの列挙 (WPD)

ほとんどのアプリケーションで最初に完了するタスクは、コンピューターに接続されているデバイスの列挙です。 このタスクとデバイス情報 (製造元、フレンドリ名、説明など) の取得は、 IPortableDeviceManager インターフェイスでサポートされています。

DeviceEnumeration.cpp モジュールの EnumerateAllDevices 関数には、接続されているデバイスの数の取得を示すコードと、カウントが取得されると、接続されている各デバイスのデバイス固有の情報の取得を示すコードが含まれています。

EnumerateAllDevices 関数は、次の 4 つの主要なタスクを実行します。

  1. ポータブル デバイス マネージャー オブジェクトを作成します。
  2. 接続されているデバイスの数を取得します。
  3. (接続されているデバイスの) デバイス情報を取得します。
  4. デバイス情報を取得するときに使用されるメモリを解放します。

これら 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);

接続されているデバイスの数を取得した後、この値を使用して、接続されている各デバイスのデバイス情報を取得できます。 このプロセスは、最初の引数として文字列ポインターの配列と、この配列が 2 番目の引数として保持できる要素の数を渡すことから始まります (この数は、少なくとも使用可能なデバイスの数と等しい必要があります)。

このメソッドによって返される文字列は、接続されているデバイスのプラグ アンド プレイ名です。 これらの名前は、 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 インターフェイス

プログラミング ガイド