USBメモリーの挿入などを検出する

USBメモリーをUSBポートに挿したときや抜いたとき、DVDドライブにCD-ROMを入れたときなど、デバイスの状態が変化したときにはWM_DEVICECHANGEメッセージが届く。
残念ながらこのメッセージを通じて取得できるのは必要最低限の情報しかないため、続く処理を作るのはかなり面倒になる。しかし必要最低限の情報しかないため理解するのは楽だろう。
ここではメッセージを取得したときに得られる情報の一部をATLTRACEにて出力ウインドウに書き出している。


ATL/WTLアプリケーションウイザードでダイアログベースのプロジェクトを作成し、自動生成されたソースコードに変更を加える。

■stdafx.hを修正 WINVERの値を0x0500に変更する。
#define WINVER		0x0500
■MainDlg.hを修正 includeファイルを2つ追加する。
#include "atlstr.h"
#include "Dbt.h"
メッセージマップにWM_DEVICECHANGE用のハンドラーを追加、CMainDlg内にメンバークラスを追加する。
	BEGIN_MSG_MAP(CMainDlg)
		MESSAGE_HANDLER(WM_DEVICECHANGE, OnDeviceChange)
		
		(。。。省略。。。)
		
	END_MSG_MAP()

	//
	//この関数は以下のURLよりコピー&改変
	//https://support.microsoft.com/kb/163503/ja
	//
	TCHAR	FirstDriveFromMask(ULONG unitmask)
	{
		TCHAR i;

		for (i = 0; i < 26; ++i)
		{
			if (unitmask & 0x1)
				break;
			unitmask = unitmask >> 1;
		}

		return (i + _T('A'));
	}



	LRESULT OnDeviceChange(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
	{
		bool	bAddData;
		CAtlString	strMessage;

		bAddData = false;
		switch(wParam)
		{
		case	DBT_CONFIGCHANGECANCELED:
			strMessage = _T("DBT_CONFIGCHANGECANCELED:設定変更要求がキャンセルされました");
			break;

		case	DBT_CONFIGCHANGED:
			strMessage = _T("DBT_CONFIGCHANGED:設定が変更されました");
			break;

		case	DBT_CUSTOMEVENT:
			strMessage = _T("DBT_CUSTOMEVENT:ドライバー定義のカスタムイベントが発行されました");
			bAddData = true;
			break;

		case	DBT_DEVICEARRIVAL:
			strMessage = _T("DBT_DEVICEARRIVAL:デバイスが使用可能になりました");
			bAddData = true;
			break;

		case	DBT_DEVICEQUERYREMOVE:
			strMessage = _T("DBT_DEVICEQUERYREMOVE:デバイス停止要求が発行されました");
			bAddData = true;
			break;

		case	DBT_DEVICEQUERYREMOVEFAILED:
			strMessage = _T("DBT_DEVICEQUERYREMOVEFAILED:デバイス停止要求が失敗されました");
			bAddData = true;
			break;

		case	DBT_DEVICEREMOVECOMPLETE:
			strMessage = _T("DBT_DEVICEREMOVECOMPLETE:デバイスが停止されました");
			bAddData = true;
			break;

		case	DBT_DEVICEREMOVEPENDING:
			strMessage = _T("DBT_DEVICEREMOVEPENDING:デバイスを停止中です");
			bAddData = true;
			break;

		case	DBT_DEVICETYPESPECIFIC:
			strMessage = _T("DBT_DEVICETYPESPECIFIC:デバイスの独自イベントが発行されました");
			bAddData = true;
			break;

		case	DBT_DEVNODES_CHANGED:
			strMessage = _T("DBT_DEVNODES_CHANGED:システムのデバイス状態が変化しました");
			break;

		case	DBT_QUERYCHANGECONFIG:
			strMessage = _T("DBT_QUERYCHANGECONFIG:設定変更要求が発行されました");
			break;

		case	DBT_USERDEFINED:
			strMessage = _T("DBT_USERDEFINED");
			break;

		default:
			strMessage.Format(_T("unknown(%04X)"),wParam);
			{
				_DEV_BROADCAST_USERDEFINED*	pData = (_DEV_BROADCAST_USERDEFINED*)lParam;
				if(pData)
				{
					strMessage += _T("(");
					strMessage += pData->dbud_szName;
					strMessage += _T(")");

					lParam = (LPARAM)&pData->dbud_dbh;
					bAddData = true;
				}
			}
			break;
		} 


		if(bAddData)
		{
			DEV_BROADCAST_HDR*	pData = (DEV_BROADCAST_HDR*)lParam;
			if(pData)
			{
				CAtlString	strBuff;

				strBuff.Format(_T("(Size=%d DeviceType=%08d)"),pData->dbch_size,pData->dbch_devicetype);
				strMessage += strBuff;

				switch(pData->dbch_devicetype)
				{
				case	DBT_DEVTYP_OEM:
					{
						DEV_BROADCAST_OEM*	pExtend = (DEV_BROADCAST_OEM*)pData;
						if(pExtend)
						{
						}
					}
					break;

				case	DBT_DEVTYP_DEVNODE:
					{
						DEV_BROADCAST_DEVNODE*	pExtend = (DEV_BROADCAST_DEVNODE*)pData;
						if(pExtend)
						{
						}
					}
					break;

				case	DBT_DEVTYP_VOLUME:
					{
						DEV_BROADCAST_VOLUME*	pExtend = (DEV_BROADCAST_VOLUME*)pData;
						if(pExtend)
						{
							CAtlString	strBuff;

							strBuff.Format(_T("「%c:」"),FirstDriveFromMask(pExtend->dbcv_unitmask));
							strMessage += strBuff;
						}
					}
					break;

				case	DBT_DEVTYP_PORT:
					{
						DEV_BROADCAST_PORT*	pExtend = (DEV_BROADCAST_PORT*)pData;
						if(pExtend)
						{
							CAtlString	strBuff;

							strBuff.Format(_T("(PORT:%s)"),pExtend->dbcp_name);
							strMessage += strBuff;
						}
					}
					break;

				case	DBT_DEVTYP_NET:
					{
						DEV_BROADCAST_NET*	pExtend = (DEV_BROADCAST_NET*)pData;
						if(pExtend)
						{
						}
					}
					break;

				case	DBT_DEVTYP_DEVICEINTERFACE:
					{
						DEV_BROADCAST_DEVICEINTERFACE*	pExtend = (DEV_BROADCAST_DEVICEINTERFACE*)pData;
						if(pExtend)
						{
							CAtlString	strBuff;

							strBuff.Format(_T("(I/F:%s)"),pExtend->dbcc_name);
							strMessage += strBuff;
						}
					}
					break;

				case	DBT_DEVTYP_HANDLE:
					{
						DEV_BROADCAST_HANDLE*	pExtend = (DEV_BROADCAST_HANDLE*)pData;
						if(pExtend && pExtend->dbch_handle && pExtend->dbch_handle != INVALID_HANDLE_VALUE)
						{
						}
					}
					break;

				}
			}
		}

		ATLTRACE("%s\n",strMessage);

		return	0;
	}

プロジェクトファイルをダウンロード


カテゴリー「システム情報」 のエントリー