處理移除裝置的要求
當系統中的功能決定移除指定的裝置時,應用程式會收到 DBT_DEVICEQUERYREMOVE 裝置事件。 當應用程式收到此事件時,它應該判斷它是否使用指定的裝置,並取消或準備移除。
在下列範例中,應用程式會維護 FileName 所代表之檔案或裝置的開啟句柄 hFile。 應用程式會藉由呼叫 RegisterDeviceNotification 函式,使用DBT_DEVTYP_HANDLE類型通知篩選器,並在篩選dbch_handle成員中指定 hFile 變數,以註冊基礎裝置上的裝置事件通知。
應用程式會關閉要移除之裝置的開啟檔案句柄, 以處理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;
}
相關主題