Condividi tramite


Scrivere un'app desktop di Windows basata sul modello WinUSB

Il modo più semplice per scrivere un'app desktop di Windows che comunica con un dispositivo USB, usa il modello WinUSB C/C++. Per questo modello è necessario un ambiente integrato con Windows Driver Kit (WDK) (con Gli strumenti di debug per Windows) e Microsoft Visual Studio (Professional o Ultimate). È possibile usare il modello come punto di partenza.

Prima di iniziare

  • Per configurare l'ambiente di sviluppo integrato, installare prima Microsoft Visual Studio Ultimate 2019 o Microsoft Visual Studio Professional 2019 e quindi installare WDK. È possibile trovare informazioni su come configurare Visual Studio e WDK nella pagina di download WDK.
  • Gli strumenti di debug per Windows vengono inclusi quando si installa WDK. Per altre informazioni, vedere Scaricare e installare strumenti di debug per Windows.

Creazione di un'applicazione WinUSB

Per creare un'applicazione dal modello:

  1. Nella finestra di dialogo Nuovo progetto nella casella di ricerca nella parte superiore digitare USB.

  2. Nel riquadro centrale selezionare Applicazione WinUSB (Universale).

  3. Selezionare Avanti.

  4. Immettere un nome del progetto, scegliere una posizione di salvataggio e selezionare Crea.

    Gli screenshot seguenti mostrano la finestra di dialogo Nuovo progetto per il modello Applicazione WinUSB (Universal).

    schermata di creazione del nuovo progetto winusb.

    nuovo modello winusb nuova schermata di creazione del progetto.

    In questo argomento si presuppone che il nome del progetto di Visual Studio sia USB Application1.

    Visual Studio crea un progetto e una soluzione. È possibile visualizzare la soluzione, il progetto e i file che appartengono al progetto nella finestra Esplora soluzioni, come illustrato nella schermata seguente. Se la finestra Esplora soluzioni non è visibile, scegliere Esplora soluzioni dal menu Visualizza. La soluzione contiene un progetto di applicazione C++ denominato USB Application1.

    Esplora soluzioni modello winusb 1.

    Il progetto USB Application1 include file di origine per l'applicazione. Se si vuole esaminare il codice sorgente dell'applicazione, è possibile aprire uno dei file visualizzati in File di origine.

  5. Aggiungere un progetto del pacchetto driver alla soluzione. Selezionare e tenere premuto (o fare clic con il pulsante destro del mouse) la soluzione (Soluzione 'USB Application1'), quindi selezionare Aggiungi>nuovo progetto come illustrato nello screenshot seguente.

    creazione di modelli winusb seconda aggiunta del progetto.

  6. Nella finestra di dialogo Nuovo progetto nella casella di ricerca nella parte superiore digitare di nuovo USB.

  7. Nel riquadro centrale selezionare Pacchetto driver WINUSB INF.

  8. Selezionare Avanti.

  9. Immettere un nome di progetto, quindi selezionare Crea.

    Gli screenshot seguenti mostrano la finestra di dialogo Nuovo progetto per il modello di pacchetto driver WINUSB INF .

    primo schermo per la creazione di un secondo progetto winusb.

    seconda schermata di creazione del progetto winusb.

    In questo argomento si presuppone che il nome del progetto di Visual Studio sia il pacchetto USB Application1.

    Il progetto pacchetto USB Application1 contiene un file INF usato per installare il driver di Winusb.sys fornito da Microsoft come driver di dispositivo.

    La Esplora soluzioni dovrebbe ora contenere entrambi i progetti, come illustrato nello screenshot seguente.

    Esplora soluzioni modello winusb 2.

  10. Nel file INF, USBApplication1.inf individuare questo codice: %DeviceName% =USB_Install, USB\VID_vvvv&PID_pppp

  11. Sostituire VID_vvvv&PID_pppp con l'ID hardware per il dispositivo. Ottenere l'ID hardware da Gestione dispositivi. In Gestione dispositivi visualizzare le proprietà del dispositivo. Nella scheda Dettagli visualizzare il valore della proprietà Ids hardware .

  12. Nella finestra Esplora soluzioni selezionare e tenere premuto (o fare clic con il pulsante destro del mouse) Soluzione "USB Application1" (2 di 2 progetti) e scegliere Configuration Manager. Scegliere una configurazione e una piattaforma per il progetto dell'applicazione e il progetto del pacchetto. In questo esercizio si sceglie Debug e x64, come illustrato nella schermata seguente.

Screenshot che mostra la finestra

Compilazione, distribuzione e debug del progetto

Finora in questo esercizio è stato usato Visual Studio per creare i progetti. È quindi necessario configurare il dispositivo a cui è connesso il dispositivo. Il modello richiede che il driver Winusb sia installato come driver per il dispositivo.

L'ambiente di test e debug può avere:

  • Configurazione di due computer: il computer host e il computer di destinazione. Sviluppare e compilare il progetto in Visual Studio nel computer host. Il debugger viene eseguito nel computer host ed è disponibile nell'interfaccia utente di Visual Studio. Quando si esegue il test e il debug dell'applicazione, il driver viene eseguito nel computer di destinazione.

  • Configurazione del singolo computer: la destinazione e l'host vengono eseguite in un computer. È possibile sviluppare e compilare il progetto in Visual Studio ed eseguire il debugger e l'applicazione.

È possibile distribuire, installare, caricare e eseguire il debug dell'applicazione e il driver seguendo questa procedura:

  • Configurazione di due computer

    1. Effettuare il provisioning del computer di destinazione seguendo le istruzioni riportate in Effettuare il provisioning di un computer per la distribuzione e il test dei driver. Nota: Il provisioning crea un utente nel computer di destinazione denominato WDKRemoteUser. Al termine del provisioning, verrà visualizzato il passaggio dell'utente a WDKRemoteUser.
    2. Nel computer host aprire la soluzione in Visual Studio.
    3. In main.cpp aggiungere questa riga prima della chiamata OpenDevice.
    system ("pause")
    

    La riga causa la sospensione dell'applicazione al momento dell'avvio. Questo è utile nel debug remoto.

    1. In pch.h includere questa riga:
    #include <cstdlib>
    

    Questa istruzione include è necessaria per la system() chiamata nel passaggio precedente.

    1. Nella finestra Esplora soluzioni selezionare e tenere premuto (o fare clic con il pulsante destro del mouse) pacchetto USB Application1 e scegliere Proprietà.

    2. Nella finestra Pagine delle proprietà del pacchetto USB Application1, nel riquadro sinistro passare alla distribuzione installazione > driver proprietà > configurazione, come illustrato nella schermata seguente.

    3. Selezionare Rimuovi versioni precedenti del driver prima della distribuzione.

    4. Per Nome computer remoto selezionare il nome del computer configurato per il test e il debug. In questo esercizio viene usato un computer denominato dbg-target.

    5. Selezionare Installa/Reinstalla e Verifica. Selezionare Applica.

      Distribuzione di modelli winusb.

    6. Nella pagina delle proprietà passare a Debug proprietà > configurazione e selezionare Strumenti di debug per Windows - Debugger remoto, come illustrato nella schermata seguente.

      debugger remoto del modello winusb.

    7. Selezionare Compila soluzione dal menu Compila . Visual Studio visualizza lo stato di avanzamento della compilazione nella finestra Output . Se la finestra Output non è visibile, scegliere Output dal menu Visualizza. In questo esercizio è stato creato il progetto per un sistema x64 che esegue Windows 10.

    8. Selezionare Distribuisci soluzione dal menu Compila .

Nel computer di destinazione verranno visualizzati gli script di installazione del driver in esecuzione. I file driver vengono copiati nella cartella %Systemdrive%\drivertest\drivers nel computer di destinazione. Verificare che i file con estensione inf, cat, certificato di test e .sys e tutti gli altri file necessari siano presenti %systemdrive%\drivertest\drivers. Il dispositivo deve essere visualizzato in Gestione dispositivi senza errori.

Nel computer host verrà visualizzato questo messaggio nella finestra Output .

Deploying driver files for project
"<path>\visual studio 14\Projects\USB Application1\USB Application1 Package\USB Application1 Package.vcxproj".
Deployment may take a few minutes...
========== Build: 1 succeeded, 0 failed, 1 up-to-date, 0 skipped ==========

Per eseguire il debug dell'applicazione

  1. Nel computer host passare a x64 > Win8.1Debug nella cartella della soluzione.

  2. Copiare l'eseguibile dell'applicazione, UsbApplication1.exe nel computer di destinazione.

  3. Nel computer di destinazione avviare l'applicazione.

  4. Nel computer host selezionare Collega al processo dal menu Debug.

  5. Nella finestra selezionare Debugger modalità utente windows (Strumenti di debug per Windows) come trasporto e il nome del computer di destinazione, in questo caso dbg-target, come qualificatore come illustrato in questa immagine.

    impostazione di debug del modello winusb.

  6. Selezionare l'applicazione dall'elenco Processi disponibili e selezionare Collega. È ora possibile eseguire il debug usando La finestra immediata o usando le opzioni nel menu Debug .

Le istruzioni precedenti eseguino il debug dell'applicazione usando Debug Strumenti per Windows - Debugger remoto. Se si vuole usare il debugger Di Windows remoto (il debugger incluso in Visual Studio), seguire queste istruzioni:

  1. Nel computer di destinazione aggiungere msvsmon.exe all'elenco di app consentite tramite Firewall.
  2. Avviare Monitoraggio debug remoto di Visual Studio situato in C:\DriverTest\msvsmon\msvsmon.exe.
  3. Creare una cartella di lavoro, ad esempio C:\remotetemp.
  4. Copiare l'eseguibile dell'applicazione, UsbApplication1.exe nella cartella di lavoro nel computer di destinazione.
  5. Nel computer host, in Visual Studio fare clic con il pulsante destro del mouse sul progetto Pacchetto applicazione USB1 e scegliere Scarica progetto.
  6. Selezionare e tenere premuto (o fare clic con il pulsante destro del mouse) sul progetto USB Application1 , nelle proprietà del progetto espandere il nodo Proprietà di configurazione e selezionare Debug.
  7. Modificare debugger per avviare il debuggerdi Windows remoto.
  8. Modificare le impostazioni del progetto per eseguire il file eseguibile in un computer remoto seguendo le istruzioni fornite in Debug remoto di un progetto compilato in locale. Assicurarsi che le proprietà di Working Directory e Remote Command riflettano la cartella nel computer di destinazione.
  9. Per eseguire il debug dell'applicazione, nel menu Compila selezionare Avvia debug oppure premere F5.
  • Configurazione del singolo computer:

    1. Per compilare l'applicazione e il pacchetto di installazione del driver, scegliere Compila soluzione dal menu Compilazione . Visual Studio visualizza lo stato di avanzamento della compilazione nella finestra Output . Se la finestra Output non è visibile, scegliere Output dal menu Visualizza. In questo esercizio è stato creato il progetto per un sistema x64 che esegue Windows 10.

    2. Per visualizzare il pacchetto driver compilato, passare a Esplora risorse nella cartella USB Application1 e quindi passare a x64 > Debug > USB Application1 Package. Il pacchetto driver contiene diversi file: MyDriver.inf è un file di informazioni usato da Windows quando si installa il driver, mydriver.cat è un file di catalogo usato dal programma di installazione per verificare la firma di test per il pacchetto driver. Questi file vengono visualizzati nella schermata seguente.

      Modello di applicazione winusb.

      Nel pacchetto non è incluso alcun file di driver. Ciò avviene perché il file INF fa riferimento al driver in box, Winusb.sys, trovato nella cartella Windows\System32.

    3. Installare manualmente il driver. In Gestione dispositivi aggiornare il driver specificando INF nel pacchetto. Puntare al pacchetto driver che si trova nella cartella della soluzione, illustrato nella sezione precedente. Se viene visualizzato l'errore DriverVer set to a date in the future, impostare le impostazioni > del progetto del pacchetto INF Inf2Cat > General > Use Local Time > Yes.

    4. Selezionare e tenere premuto (o fare clic con il pulsante destro del mouse) sul progetto USB Application1 , nelle proprietà del progetto espandere il nodo Proprietà di configurazione e selezionare Debug.

    5. Modificare debugger per avviare il debuggerdi Windows locale.

    6. Selezionare e tenere premuto (o fare clic con il pulsante destro del mouse) sul progetto pacchetto USB Application1 e selezionare Scarica progetto.

    7. Per eseguire il debug dell'applicazione, nel menu Compila selezionare Avvia debug oppure premere F5.

Discussione del codice modello

Il modello è un punto di partenza per l'applicazione desktop. Il progetto USB Application1 include file di origine device.cpp e main.cpp.

Il file main.cpp contiene il punto di ingresso dell'applicazione, _tmain. Il dispositivo.cpp contiene tutte le funzioni helper che aprono e chiudino l'handle al dispositivo.

Il modello include anche un file di intestazione denominato device.h. Questo file contiene definizioni per il GUID dell'interfaccia del dispositivo (illustrato più avanti) e una struttura DEVICE_DATA che archivia le informazioni ottenute dall'applicazione. Ad esempio, archivia l'handle dell'interfaccia WinUSB ottenuto da OpenDevice e usato nelle operazioni successive.

typedef struct _DEVICE_DATA {

    BOOL                    HandlesOpen;
    WINUSB_INTERFACE_HANDLE WinusbHandle;
    HANDLE                  DeviceHandle;
    TCHAR                   DevicePath[MAX_PATH];

} DEVICE_DATA, *PDEVICE_DATA;

Recupero del percorso dell'istanza del dispositivo: vedere RetrieveDevicePath in device.cpp

Per accedere a un dispositivo USB, l'applicazione crea un handle di file valido per il dispositivo chiamando CreateFile. Per tale chiamata, l'applicazione deve ottenere l'istanza del percorso del dispositivo. Per ottenere il percorso del dispositivo, l'app usa routine SetupAPI e specifica il GUID dell'interfaccia del dispositivo nel file INF usato per installare Winusb.sys. Device.h dichiara una costante GUID denominata GUID_DEVINTERFACE_USBApplication1. Usando queste routine, l'applicazione enumera tutti i dispositivi nella classe di interfaccia del dispositivo specificata e recupera il percorso del dispositivo del dispositivo.

HRESULT
RetrieveDevicePath(
    _Out_bytecap_(BufLen) LPTSTR DevicePath,
    _In_                  ULONG  BufLen,
    _Out_opt_             PBOOL  FailureDeviceNotFound
    )
/*++

Routine description:

    Retrieve the device path that can be used to open the WinUSB-based device.

    If multiple devices have the same device interface GUID, there is no
    guarantee of which one will be returned.

Arguments:

    DevicePath - On successful return, the path of the device (use with CreateFile).

    BufLen - The size of DevicePath's buffer, in bytes

    FailureDeviceNotFound - TRUE when failure is returned due to no devices
        found with the correct device interface (device not connected, driver
        not installed, or device is disabled in Device Manager); FALSE
        otherwise.

Return value:

    HRESULT

--*/
{
    BOOL                             bResult = FALSE;
    HDEVINFO                         deviceInfo;
    SP_DEVICE_INTERFACE_DATA         interfaceData;
    PSP_DEVICE_INTERFACE_DETAIL_DATA detailData = NULL;
    ULONG                            length;
    ULONG                            requiredLength=0;
    HRESULT                          hr;

    if (NULL != FailureDeviceNotFound) {

        *FailureDeviceNotFound = FALSE;
    }

    //
    // Enumerate all devices exposing the interface
    //
    deviceInfo = SetupDiGetClassDevs(&GUID_DEVINTERFACE_USBApplication1,
                                     NULL,
                                     NULL,
                                     DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);

    if (deviceInfo == INVALID_HANDLE_VALUE) {

        hr = HRESULT_FROM_WIN32(GetLastError());
        return hr;
    }

    interfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

    //
    // Get the first interface (index 0) in the result set
    //
    bResult = SetupDiEnumDeviceInterfaces(deviceInfo,
                                          NULL,
                                          &GUID_DEVINTERFACE_USBApplication1,
                                          0,
                                          &interfaceData);

    if (FALSE == bResult) {

        //
        // We would see this error if no devices were found
        //
        if (ERROR_NO_MORE_ITEMS == GetLastError() &&
            NULL != FailureDeviceNotFound) {

            *FailureDeviceNotFound = TRUE;
        }

        hr = HRESULT_FROM_WIN32(GetLastError());
        SetupDiDestroyDeviceInfoList(deviceInfo);
        return hr;
    }

    //
    // Get the size of the path string
    // We expect to get a failure with insufficient buffer
    //
    bResult = SetupDiGetDeviceInterfaceDetail(deviceInfo,
                                              &interfaceData,
                                              NULL,
                                              0,
                                              &requiredLength,
                                              NULL);

    if (FALSE == bResult && ERROR_INSUFFICIENT_BUFFER != GetLastError()) {

        hr = HRESULT_FROM_WIN32(GetLastError());
        SetupDiDestroyDeviceInfoList(deviceInfo);
        return hr;
    }

    //
    // Allocate temporary space for SetupDi structure
    //
    detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)
        LocalAlloc(LMEM_FIXED, requiredLength);

    if (NULL == detailData)
    {
        hr = E_OUTOFMEMORY;
        SetupDiDestroyDeviceInfoList(deviceInfo);
        return hr;
    }

    detailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
    length = requiredLength;

    //
    // Get the interface's path string
    //
    bResult = SetupDiGetDeviceInterfaceDetail(deviceInfo,
                                              &interfaceData,
                                              detailData,
                                              length,
                                              &requiredLength,
                                              NULL);

    if(FALSE == bResult)
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        LocalFree(detailData);
        SetupDiDestroyDeviceInfoList(deviceInfo);
        return hr;
    }

    //
    // Give path to the caller. SetupDiGetDeviceInterfaceDetail ensured
    // DevicePath is NULL-terminated.
    //
    hr = StringCbCopy(DevicePath,
                      BufLen,
                      detailData->DevicePath);

    LocalFree(detailData);
    SetupDiDestroyDeviceInfoList(deviceInfo);

    return hr;
}

Nella funzione precedente l'applicazione ottiene il percorso del dispositivo chiamando queste routine:

  1. SetupDiGetClassDevs per ottenere un handle per il set di informazioni sul dispositivo, una matrice che contiene informazioni su tutti i dispositivi installati che corrispondono alla classe di interfaccia del dispositivo specificata, GUID_DEVINTERFACE_USBApplication1. Ogni elemento nella matrice denominata interfaccia del dispositivo corrisponde a un dispositivo installato e registrato con il sistema. La classe dell'interfaccia del dispositivo viene identificata passando il GUID dell'interfaccia del dispositivo definito nel file INF. La funzione restituisce un handle HDEVINFO al set di informazioni sul dispositivo.

  2. SetupDiEnumDeviceInterfaces per enumerare le interfacce del dispositivo nel set di informazioni sul dispositivo e ottenere informazioni sull'interfaccia del dispositivo.

    Questa chiamata richiede gli elementi seguenti:

    • Struttura del chiamante allocata SP_DEVICE_INTERFACE_DATA inizializzata con il membro cbSize impostato sulla dimensione della struttura.

    • Handle HDEVINFO dal passaggio 1.

    • GUID dell'interfaccia del dispositivo definito nel file INF.

      SetupDiEnumDeviceInterfaces cerca la matrice del set di informazioni del dispositivo per l'indice specificato dell'interfaccia del dispositivo e riempie la struttura di SP_DEVICE_INTERFACE_DATA inizializzata con dati di base sull'interfaccia.

    Per enumerare tutte le interfacce del dispositivo nel set di informazioni del dispositivo, chiamare SetupDiEnumDeviceInterfaces in un ciclo fino a quando la funzione restituisce FALSE e il codice di errore per l'errore è ERROR_NO_MORE_ITEMS. Il codice di errore ERROR_NO_MORE_ITEMS può essere recuperato chiamando GetLastError. Con ogni iterazione, aumentare l'indice membro.

    In alternativa, è possibile chiamare SetupDiEnumDeviceInfo che enumera il set di informazioni sul dispositivo e restituisce informazioni sugli elementi dell'interfaccia del dispositivo, specificati dall'indice, in una struttura SP_DEVINFO_DATA allocata dal chiamante. È quindi possibile passare un riferimento a questa struttura nel parametro DeviceInfoData della funzione SetupDiEnumDeviceInterfaces .

  3. SetupDiGetDeviceInterfaceDetail per ottenere dati dettagliati per l'interfaccia del dispositivo. Le informazioni vengono restituite in una struttura SP_DEVICE_INTERFACE_DETAIL_DATA . Poiché le dimensioni della struttura SP_DEVICE_INTERFACE_DETAIL_DATA variano, SetupDiGetDeviceInterfaceDetail viene chiamato due volte. La prima chiamata ottiene le dimensioni del buffer da allocare per la struttura SP_DEVICE_INTERFACE_DETAIL_DATA . La seconda chiamata riempie il buffer allocato con informazioni dettagliate sull'interfaccia.

    1. Chiama SetupDiGetDeviceInterfaceDetail con il parametro DeviceInterfaceDetailData impostato su NULL. La funzione restituisce le dimensioni corrette del buffer nel parametro obbligatorio . Questa chiamata ha esito negativo con il codice di errore ERROR_INSUFFICIENT_BUFFER. Questo codice di errore è previsto.
    2. Alloca la memoria per una struttura di SP_DEVICE_INTERFACE_DETAIL_DATA in base alle dimensioni corrette del buffer recuperate nel parametro requiredlength .
    3. Chiama di nuovo SetupDiGetDeviceInterfaceDetail e lo passa a un riferimento alla struttura inizializzata nel parametro DeviceInterfaceDetailData . Quando la funzione restituisce, la struttura viene riempita con informazioni dettagliate sull'interfaccia. Il percorso del dispositivo si trova nel membro DevicePath della struttura di SP_DEVICE_INTERFACE_DETAIL_DATA.

Creazione di un handle di file per il dispositivo

Vedere OpenDevice in device.cpp.

Per interagire con il dispositivo, è necessario un handle di interfaccia WinUSB per la prima interfaccia (predefinita) nel dispositivo. Il codice modello ottiene l'handle di file e l'handle dell'interfaccia WinUSB e li archivia nella struttura DEVICE_DATA.

HRESULT
OpenDevice(
    _Out_     PDEVICE_DATA DeviceData,
    _Out_opt_ PBOOL        FailureDeviceNotFound
    )
/*++

Routine description:

    Open all needed handles to interact with the device.

    If the device has multiple USB interfaces, this function grants access to
    only the first interface.

    If multiple devices have the same device interface GUID, there is no
    guarantee of which one will be returned.

Arguments:

    DeviceData - Struct filled in by this function. The caller should use the
        WinusbHandle to interact with the device, and must pass the struct to
        CloseDevice when finished.

    FailureDeviceNotFound - TRUE when failure is returned due to no devices
        found with the correct device interface (device not connected, driver
        not installed, or device is disabled in Device Manager); FALSE
        otherwise.

Return value:

    HRESULT

--*/
{
    HRESULT hr = S_OK;
    BOOL    bResult;

    DeviceData->HandlesOpen = FALSE;

    hr = RetrieveDevicePath(DeviceData->DevicePath,
                            sizeof(DeviceData->DevicePath),
                            FailureDeviceNotFound);

    if (FAILED(hr)) {

        return hr;
    }

    DeviceData->DeviceHandle = CreateFile(DeviceData->DevicePath,
                                          GENERIC_WRITE | GENERIC_READ,
                                          FILE_SHARE_WRITE | FILE_SHARE_READ,
                                          NULL,
                                          OPEN_EXISTING,
                                          FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
                                          NULL);

    if (INVALID_HANDLE_VALUE == DeviceData->DeviceHandle) {

        hr = HRESULT_FROM_WIN32(GetLastError());
        return hr;
    }

    bResult = WinUsb_Initialize(DeviceData->DeviceHandle,
                                &DeviceData->WinusbHandle);

    if (FALSE == bResult) {

        hr = HRESULT_FROM_WIN32(GetLastError());
        CloseHandle(DeviceData->DeviceHandle);
        return hr;
    }

    DeviceData->HandlesOpen = TRUE;
    return hr;
}
  1. L'app chiama CreateFile per creare un handle di file per il dispositivo specificando il percorso del dispositivo recuperato in precedenza. Usa il flag FILE_FLAG_OVERLAPPED perché WinUSB dipende da questa impostazione.
  2. Usando l'handle di file per il dispositivo, l'app crea un handle di interfaccia WinUSB. Le funzioni WinUSB usano questo handle per identificare il dispositivo di destinazione anziché l'handle di file. Per ottenere un handle di interfaccia WinUSB, l'app chiama WinUsb_Initialize passando l'handle di file. Usare l'handle ricevuto nelle chiamate successive per ottenere informazioni dal dispositivo e inviare richieste di I/O al dispositivo.

Rilasciare gli handle del dispositivo : vedere CloseDevice in device.cpp

Il codice modello implementa il codice per rilasciare l'handle di file e l'handle dell'interfaccia WinUSB per il dispositivo.

VOID
CloseDevice(
    _Inout_ PDEVICE_DATA DeviceData
    )
/*++

Routine description:

    Perform required cleanup when the device is no longer needed.

    If OpenDevice failed, do nothing.

Arguments:

    DeviceData - Struct filled in by OpenDevice

Return value:

    None

--*/
{
    if (FALSE == DeviceData->HandlesOpen) {

        //
        // Called on an uninitialized DeviceData
        //
        return;
    }

    WinUsb_Free(DeviceData->WinusbHandle);
    CloseHandle(DeviceData->DeviceHandle);
    DeviceData->HandlesOpen = FALSE;

    return;
}

Passaggi successivi

Leggere quindi questi argomenti per inviare informazioni sul dispositivo e inviare trasferimenti di dati al dispositivo: