Verarbeiten einer Anforderung zum Entfernen eines Geräts

Eine Anwendung empfängt ein DBT_DEVICEQUERYREMOVE Geräteereignis, wenn ein Feature im System beschlossen hat, ein angegebenes Gerät zu entfernen. Wenn die Anwendung dieses Ereignis empfängt, sollte sie bestimmen, ob sie das angegebene Gerät verwendet, und entweder abbrechen oder die Entfernung vorbereiten.

Im folgenden Beispiel verwaltet eine Anwendung ein geöffnetes Handle (hFile) für die Datei oder das Gerät, die durch FileName dargestellt wird. Die Anwendung registriert sich für Geräteereignisbenachrichtigungen auf dem zugrunde liegenden Gerät, indem sie die Funktion RegisterDeviceNotification aufruft , einen DBT_DEVTYP_HANDLE Typbenachrichtigungsfilter verwendet und die hFile-Variable im dbch_handle Element des Filters angibt.

Die Anwendung verarbeitet das DBT_DEVICEQUERYREMOVE-Geräteereignis , indem das geöffnete Dateihandle für das gerät geschlossen wird, das entfernt werden soll. Falls das Entfernen dieses Geräts abgebrochen wird, verarbeitet die Anwendung das DBT_DEVICEQUERYREMOVEFAILED-Geräteereignis, um das Handle für das Gerät erneut zu öffnen. Nachdem das Gerät aus dem System entfernt wurde, verarbeitet die Anwendung die DBT_DEVICEREMOVECOMPLETE und DBT_DEVICEREMOVEPENDING Geräteereignisse, indem sie die Registrierung des Benachrichtigungshandles für das Gerät auf hebt und alle Handles schließt, die für das Gerät noch geöffnet sind.

#include <windows.h>
#include <dbt.h>
#include <strsafe.h>
  // ...

INT_PTR WINAPI WinProcCallback( HWND hWnd,
                                UINT message,
                                WPARAM wParam,
                                LPARAM lParam )
{
  LPCTSTR FileName = NULL;              // path to the file or device of interest
  HANDLE  hFile = INVALID_HANDLE_VALUE; // handle to the file or device

  PDEV_BROADCAST_HDR    pDBHdr;
  PDEV_BROADCAST_HANDLE pDBHandle;
  TCHAR szMsg[80];

  switch (message)
  {
  //...
  case WM_DEVICECHANGE:
    switch (wParam)
    {
      case DBT_DEVICEQUERYREMOVE:
        pDBHdr = (PDEV_BROADCAST_HDR) lParam;
        switch (pDBHdr->dbch_devicetype)
        {
          case DBT_DEVTYP_HANDLE:
            // A request has been made to remove the device;
            // close any open handles to the file or device

            pDBHandle = (PDEV_BROADCAST_HANDLE) pDBHdr;
            if (hFile != INVALID_HANDLE_VALUE) 
            {
              CloseHandle(hFile);
              hFile = INVALID_HANDLE_VALUE;
            }
        }
        return TRUE;

      case DBT_DEVICEQUERYREMOVEFAILED:
        pDBHdr = (PDEV_BROADCAST_HDR) lParam;
        switch (pDBHdr->dbch_devicetype)
        {
          case DBT_DEVTYP_HANDLE:
            // Removal of the device has failed;
            // reopen a handle to the file or device

            pDBHandle = (PDEV_BROADCAST_HANDLE) pDBHdr;
            hFile = CreateFile(FileName,
                       GENERIC_READ,
                       FILE_SHARE_READ,
                       NULL,
                       OPEN_EXISTING,
                       FILE_ATTRIBUTE_NORMAL,
                       NULL);
            if (hFile == INVALID_HANDLE_VALUE) 
            {
              StringCchPrintf( szMsg, sizeof(szMsg)/sizeof(szMsg[0]), 
                               TEXT("CreateFile failed: %lx.\n"), 
                               GetLastError());
              MessageBox(hWnd, szMsg, TEXT("CreateFile"), MB_OK);
            }
        }
        return TRUE;

      case DBT_DEVICEREMOVEPENDING:
        pDBHdr = (PDEV_BROADCAST_HDR) lParam;
        switch (pDBHdr->dbch_devicetype)
        {
          case DBT_DEVTYP_HANDLE:
          
            // The device is being removed;
            // close any open handles to the file or device

            if (hFile != INVALID_HANDLE_VALUE) 
            {
              CloseHandle(hFile);
              hFile = INVALID_HANDLE_VALUE;
            }

        }
        return TRUE;

      case DBT_DEVICEREMOVECOMPLETE:
        pDBHdr = (PDEV_BROADCAST_HDR) lParam;
        switch (pDBHdr->dbch_devicetype)
        {
          case DBT_DEVTYP_HANDLE:
            pDBHandle = (PDEV_BROADCAST_HANDLE) pDBHdr;
            // The device has been removed from the system;
            // unregister its notification handle

            UnregisterDeviceNotification(
              pDBHandle->dbch_hdevnotify);
              
            // The device has been removed;
            // close any remaining open handles to the file or device

            if (hFile != INVALID_HANDLE_VALUE) 
            {
              CloseHandle(hFile);
              hFile = INVALID_HANDLE_VALUE;
            }

        }
        return TRUE;

      default:
        return TRUE;
    }
  }
  default:
    return TRUE;
}

Geräteereignistypen