テクニカル ドキュメント #27



Doc ID: 27
製品: WinDriver
Version:  6.20 およびそれ以降

Windows PC で対象の USB デバイスの場所をどのように検出しますか?

USB デバイスの場所の検出方法は以下の手順を参考にして下さい:

USB デバイスの場所は、次のようにデバイスのハブの ID とハブのポートによって決まります: Z&ZZZZZZZ&Z&A. Z&ZZZZZZZ&Z は、ハブの ID または PrefixID、そして、A は、ハブ (1 to 4) のポート/アドレスです。
デバイスの場所の ID を取得するには、まず、デバイスの種類、Vendor ID、Product ID、ハブの ID およびポート ID で決まるデバイスのインスタンス ID を取得する必要があります: USB\VID_XXXX&PID_YYYY\Z&ZZZZZZZ&Z&A.
SetupDiGetDeviceInstanceId() 関数が DeviceInstanceId の値を返します。
以下の手順で、USB デバイスの場所を検出します:

  1. WinDriver の WD_GetDeviceProperty() と WdDevicePropertyDriverKeyName を使用して、DriverKeyName を取得します。
  2. WinDriver の WD_GetDeviceProperty() と WdDevicePropertyClassGuid を使用して、ClassGUID を取得します。
  3. 取得した DriverKeyName と ClassGUID で、GetDeviceInstanceId() (下記参照) を使用して、DeviceInstanceId を取得します。
  4. 取得した DeviceInstanceId から、USB デバイスの場所、Z&ZZZZZZZ&Z&A を取得します。
---------------------------------------------------------------------------------------
// szDriverKeyName is returned by WD_GetDeviceProperty for the 
// device. 
// It looks like {C671678C-82C1-43F3-D700-0049433E9A4B}\\0017
// szClassGUID is returned by WD_GetDeviceProperty for the 
// device.  
// It looks like {C671678C-82C1-43F3-D700-0049433E9A4B}
//
// GetDeviceInstanceId creates a list of the device 
// information for all devices of the specified class.
// The function then searches the list for the WinDriver 
// device and retrieves the device instance ID.

#include <windows.h>
#include <setupapi.h>
#include <string.h>



BOOL GetDeviceInstanceId(LPCTSTR szClassGUID, LPCTSTR 
    szDriverKeyName, PTCHAR *pszDeviceInstanceId)
{
    // Build class GUID from szClassGUID
    GUID guid;
    DWORD dwMemberIndex=0;
    SP_DEVINFO_DATA DeviceInfoData;
    BOOL bResult;
    DWORD dwError;
    DWORD dwPropertyBufferSize;
    PTCHAR pbPropertyBuffer;
    DWORD dwRequiredSize;
    DWORD dwPropertyRegDataType;
    HDEVINFO hDeviceInfoSet; 

    StringToGUID(szClassGUID,&guid);

    *pszDeviceInstanceId = NULL;

    // Create a list of the device information for all 
    // devices of the specified class

    hDeviceInfoSet = SetupDiGetClassDevs(&guid, 
                                         NULL, NULL, DIGCF_PRESENT);

    if (INVALID_HANDLE_VALUE == hDeviceInfoSet)
    {
        // Set error 
        // ..............
        return FALSE;
    }

    // Search the device information list for the WinDriver 
    // device


    DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
    do {
        // Get the next device on the list
        bResult = SetupDiEnumDeviceInfo(hDeviceInfoSet, 
                     dwMemberIndex, &DeviceInfoData);
        if (bResult)
        {
            dwRequiredSize = 0;
            // Check if there is a driver reg path for this 
            // device


            // First get the size only
            bResult = SetupDiGetDeviceRegistryProperty
                          (hDeviceInfoSet, 
                          &DeviceInfoData, SPDRP_DRIVER, 
                          &dwPropertyRegDataType, NULL
                          0
, &dwRequiredSize);

            if (bResult && dwRequiredSize > 0)
            {
                dwPropertyBufferSize = dwRequiredSize+1;
                pbPropertyBuffer = (TCHAR *)malloc(sizeof
                                       (TCHAR) *
                                       dwPropertyBufferSize);
                ASSERT(pbPropertyBuffer!=NULL);

                // Then get this driver's actual reg path
                if(SetupDiGetDeviceRegistryProperty
                       (hDeviceInfoSet, &DeviceInfoData, 
                       SPDRP_DRIVER,
&dwPropertyRegDataType, 
                       (PBYTE)pbPropertyBuffer, 
                       dwPropertyBufferSize, &dwRequiredSize))
                {
                    // Check if the reg path is the same as in 
                    // WinDriver

                    int iResult = _tcscmp
                                      (pbPropertyBuffer,
                                       szDriverKeyName);
                   
                    if (iResult == 0)
                    {
                        // This is the device we are working 
                        // with in WinDriver

                        // Get the device's instance id

                        // First get the size only

                        dwRequiredSize = 0;
                        bResult = SetupDiGetDeviceInstanceId
                                      (hDeviceInfoSet, 
                                      &DeviceInfoData, NULL
                                      0, &dwRequiredSize);
                        if (bResult && dwRequiredSize)
                        {
                            *pszDeviceInstanceId ==
                                (TCHAR *)malloc
(sizeof(TCHAR) 
                                *(dwRequiredSize+1));
                            ASSERT(*pszDeviceInstanceId!=NULL);
                            // Then get the actual device 
                            // instance id

                            if (!SetupDiGetDeviceInstanceId
                                    (hDeviceInfoSet, 
                                    &DeviceInfoData, 
                                    *pszDeviceInstanceId, 
                                    dwRequiredSize+1, NULL))
                            {
                                dwError = GetLastError();
                                // .....
                            }
                        }
                    }
                }
                                         else
                    delete pbPropertyBuffer;

            }
        }
        dwMemberIndex++;

    } while(bResult && !*pszDeviceInstanceId);

    SetupDiDestroyDeviceInfoList(hDeviceInfoSet);
    return FALSE;
}