处理删除设备的请求
当系统中的功能决定删除指定的设备时,应用程序会收到 DBT_DEVICEQUERYREMOVE 设备事件。 当应用程序收到此事件时,它应确定是使用指定的设备,还是取消或准备删除。
在以下示例中,应用程序维护由 FileName 表示的文件或设备打开的句柄 hFile。 通过使用 DBT_DEVTYP_HANDLE 类型通知筛选器并在筛选器 dbch_handle 成员中指定 hFile 变量,调用 RegisterDeviceNotification 函数,应用程序可在基础设备上注册设备事件通知。
通过将打开的文件句柄关闭到要删除的设备,应用程序可处理 DBT_DEVICEQUERYREMOVE 设备事件。 如果取消删除此设备,应用程序将处理 DBT_DEVICEQUERYREMOVEFAILED 设备事件,以重新打开设备的句柄。 从系统中删除设备后,通过注销设备的通知句柄并关闭仍对设备打开的任何句柄,应用程序可处理 DBT_DEVICEREMOVECOMPLETE 和 DBT_DEVICEREMOVEPENDING 设备事件。
#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;
}
相关主题