windows - Hvad er målretningen til IOCTL\_USB\_GET\_ROOT\_HUB\_NAME (USB-driverspecifik IOCTL IRQ)

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg er lidt forvirret af USB IOCTL IOCTL\_USB\_GET\_ROOT\_HUB\_NAME . Hvad er målenheden af ​​den? Selv om MSDN WDK doc tydeligt angiver målenheden, er jeg stadig forvirret af den USBVIEW-prøve, der leveres af WDK. Grunden til at jeg er forvirret er som følger:


Jeg er ny i kernel mode og USB driver skrive i Windows og studerer nu USBVIEW prøven fra Windows driver kit http://msdn.microsoft.com/en-us/library/ff558728(v=vs.85).aspx . MSDN beskriver det første trin, som USBVIEW-prøven udfører som: [9]



  Tæller værtscontrollere og root
  hubs. Værtscontrollere har symbolsk
  link navne på formularen 'HCDx', hvor x
  starter ved 0.

  
  Brug CreateFile () for at åbne hver vært
  controller
symbolsk link.

  
  Opret en node i trævisningen til
  repræsenterer hver host controller.

  
  Efter en vært controller har været
  åbnes, send værtscontrolleren an
  IOCTL\_USB\_GET\_ROOT\_HUB\_NAME anmodning om
  få rodets symbolske link navn
  hub, der er en del af værten
  controller



Men jeg kontrollerede dobbelt brug af IOCTL\_USB\_GET\_ROOT\_HUB\_NAME i MSDN http://msdn.microsoft.com/en-us/library/ff537326(v=VS.85).aspx
som siger: [10]



  IOCTL\_USB\_GET\_ROOT\_HUB\_NAME er en
  I/O-kontrolanmodning for brugertilstand. Dette
  anmodningen er rettet mod USB-hub FDO .



Bemærk, at målet for IOCTL\_USB\_GET\_ROOT\_HUB\_NAME IRP er en USB Hub FDO. Som beskrevet af USBVIEW-prøven, har vi netop genoprettet den værtsstyringens symbolske link, hvilket betyder, at enhedsobjektet er et værtscontroller-enhedsobjekt. Hvordan kunne vi sende det til en IOCTL\_USB\_GET\_ROOT\_HUB\_NAME IRP? Skal vi genoptage en USB-hub FDO på en eller anden måde?

Bedste reference


Jeg vil gætte, at det er en uheldig kopi-indsætningsfejl. IOCTL\_USB\_GET\_ROOT\_HUB\_NAME er faktisk sendt til værtscontrolleren og håndteres derfor af USB Host Controller FDO.


Forresten, bare for at sætte dig i kontekst:
Udtrykket 'FDO' vedrører kun løst brugermodus - det er ikke som om du kan få adgang til andre 'xDO'. Hvis du skulle sende denne IOCTL i kernel mode, så er det sikkert, at du kan sende en IOCTL til en bestemt enhed objekt i enhedsstakken ('kan' betyder ikke 'skal', husk dig). En DeviceIoControl fra en brugertilstandsapplikation sender dog altid IOCTLs til toppen af ​​enhedsstakken (derfor passerer alle filtre, FDO og ned til BOB).


Dette spørgsmål blev stillet den 28. marts, så jeg håber virkelig, at du har løst det nu :)

Andre referencer 1


Som det fremgår af dokumentationen, skal du bruge et håndtag til USB-værtskontrolleren, men det er ikke meget klart, hvordan du skal få et sådant håndtag. I USBView bruges noget som ligner denne funktion til at få enhedens stinavn ved at passere GUID\_DEVINTERFACE\_USB\_HOST\_CONTROLLER (inkludere initguid.h og usbiodef.h):




vector<wstring> EnumDevices(
    \_In\_    const GUID Guid
)
{
    vector<wstring> r;

    int index = 0;
    HDEVINFO hDevInfo = SetupDiGetClassDevs(&Guid, NULL, NULL, DIGCF\_PRESENT | DIGCF\_DEVICEINTERFACE);

    SP\_DEVINFO\_DATA DevInfoData;
    memset(&DevInfoData, 0, sizeof(SP\_DEVINFO\_DATA));
    DevInfoData.cbSize = sizeof(SP\_DEVINFO\_DATA);

    while (SetupDiEnumDeviceInfo(hDevInfo, index, &DevInfoData)) {
        index++;

        int jndex = 0;
        SP\_DEVICE\_INTERFACE\_DATA DevIntData;
        memset(&DevIntData, 0, sizeof(SP\_DEVICE\_INTERFACE\_DATA));
        DevIntData.cbSize = sizeof(SP\_DEVICE\_INTERFACE\_DATA);

        while (SetupDiEnumDeviceInterfaces(
            hDevInfo,
            &DevInfoData, &Guid, jndex, &DevIntData
        )) {
            jndex++;

            // Get the size required for the structure.
            DWORD RequiredSize;
            SetupDiGetDeviceInterfaceDetail(
                hDevInfo, &DevIntData, NULL, NULL, &RequiredSize, NULL
            );

            PSP\_DEVICE\_INTERFACE\_DETAIL\_DATA pDevIntDetData = (PSP\_DEVICE\_INTERFACE\_DETAIL\_DATA)malloc(
                sizeof(SP\_DEVICE\_INTERFACE\_DETAIL\_DATA) + RequiredSize
            );
            memset(pDevIntDetData, 0, sizeof(SP\_DEVICE\_INTERFACE\_DETAIL\_DATA) + RequiredSize);
            pDevIntDetData->cbSize = sizeof(SP\_DEVICE\_INTERFACE\_DETAIL\_DATA);

            SetupDiGetDeviceInterfaceDetail(
                hDevInfo,
                &DevIntData,
                pDevIntDetData, RequiredSize,
                NULL,
                &DevInfoData
            );

            r.push\_back(wstring(pDevIntDetData->DevicePath));
            free(pDevIntDetData);
        }
    }

    return r;
}


Husk at bruge ovenstående funktion, du kan også anmode om enheder af typen GUID\_DEVINTERFACE\_USB\_HUB og GUID\_DEVINTERFACE\_USB\_DEVICE, som kan eliminere ethvert behov for at interagere med værtscontrolleren eller hub'erne direkte.