Platform SDK: Hardware |
An application receives a DBT_DEVICEQUERYREMOVE device event when a component in the system has decided to remove a specified device. When the application receives this event, it should determine whether it is using the specified device and either cancel or prepare for the removal.
In the following example, an application maintains an open handle, hFile, to the file or device represented by FileName. The application registers for device event notification on the underlying device by calling the RegisterDeviceNotification function, using a DBT_DEVTYP_HANDLE type notification filter and specifying hFile in the dbch_handle member of the filter.
The application processes the DBT_DEVICEQUERYREMOVE device event by closing the open file handle to the device that is to be removed. In the event that removal of this device is canceled, the application processes the DBT_DEVICEQUERYREMOVEFAILED device event to reopen the handle to the device. After the device has been removed from the system, the application processes the DBT_DEVICEREMOVECOMPLETE device event by unregistering its notification handle for the device.
LPCTSTR FileName; // path to the file or device of interest HANDLE hFile; // handle to the file or device PDEV_BROADCAST_HDR pDevBroadcastHdr; PDEV_BROADCAST_HANDLE pDevBroadcastHandle; DWORD Err; case WM_DEVICECHANGE: switch (wParam) { case DBT_DEVICEQUERYREMOVE: pDevBroadcastHdr = (PDEV_BROADCAST_HDR) lParam; switch (pDevBroadcastHdr->dbch_devicetype) { case DBT_DEVTYP_HANDLE: // A request has been made to remove the device; // close any open handles to the file or device pDevBroadcastHandle = (PDEV_BROADCAST_HANDLE) pDevBroadcastHdr; if (hFile != INVALID_HANDLE_VALUE) { CloseHandle(hFile); hFile = INVALID_HANDLE_VALUE; } } return TRUE; case DBT_DEVICEQUERYREMOVEFAILED: pDevBroadcastHdr = (PDEV_BROADCAST_HDR) lParam; switch (pDevBroadcastHdr->dbch_devicetype) { case DBT_DEVTYP_HANDLE: // Removal of the device has failed; // re-open a handle to the file or device pDevBroadcastHandle = (PDEV_BROADCAST_HANDLE) pDevBroadcastHdr; hFile = CreateFile(FileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { Err = GetLastError(); printf( "CreateFile failed: %lx.\n", Err); } } return TRUE; case DBT_DEVICEREMOVEPENDING: pDevBroadcastHdr = (PDEV_BROADCAST_HDR) lParam; switch (pDevBroadcastHdr->dbch_devicetype) { case DBT_DEVTYP_HANDLE: // All queries for removal of the device were // successful; device removal is pending ; } return TRUE; case DBT_DEVICEREMOVECOMPLETE: pDevBroadcastHdr = (PDEV_BROADCAST_HDR) lParam; switch (pDevBroadcastHdr->dbch_devicetype) { case DBT_DEVTYP_HANDLE: pDevBroadcastHandle = (PDEV_BROADCAST_HANDLE) pDevBroadcastHdr; // The device has been removed from the system; // unregister its notification handle UnregisterDeviceNotification(pDevBroadcastHandle->dbch_hdevnotify); } return TRUE; default: return TRUE; }