Windows下檢測USB插拔的demo
阿新 • • 發佈:2019-02-09
#include <Windows.h> #include <stdlib.h> #include <string.h> #include <tchar.h> #include <string> #include <algorithm> #include <Dbt.h> #include <setupapi.h> #include <comdef.h> #pragma comment(lib, "Setupapi.lib") using std::string; static TCHAR szWindowClass[] = _T("win32app"); static TCHAR szTitle[] = _T("Win32 Guided Tour Application"); HINSTANCE hInst; HWND hNotificationHandl = NULL; TCHAR PcName[MAX_PATH]; // Copy from HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceClasses static const GUID GUID_DEVINTERFACE_LIST[] = { // GUID_DEVINTERFACE_USB_DEVICE { 0xA5DCBF10, 0x6530, 0x11D2, { 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED } }, // GUID_DEVINTERFACE_DISK { 0x53f56307, 0xb6bf, 0x11d0, { 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b } }, // GUID_DEVINTERFACE_HID, { 0x4D1E55B2, 0xF16F, 0x11CF, { 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } }, // GUID_NDIS_LAN_CLASS { 0xad498944, 0x762f, 0x11d0, { 0x8d, 0xcb, 0x00, 0xc0, 0x4f, 0xc3, 0x35, 0x8c } }, //// GUID_DEVINTERFACE_COMPORT { 0x86e0d1e0, 0x8089, 0x11d0, { 0x9c, 0xe4, 0x08, 0x00, 0x3e, 0x30, 0x1f, 0x73 } }, //// GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR { 0x4D36E978, 0xE325, 0x11CE, { 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 } }, //// GUID_DEVINTERFACE_PARALLEL { 0x97F76EF0, 0xF883, 0x11D0, { 0xAF, 0x1F, 0x00, 0x00, 0xF8, 0x00, 0x84, 0x5C } }, //// GUID_DEVINTERFACE_PARCLASS { 0x811FC6A5, 0xF728, 0x11D0, { 0xA5, 0x37, 0x00, 0x00, 0xF8, 0x75, 0x3E, 0xD1 } } }; LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); bool InitDeviceInterface(); UINT JudgeDevice(WPARAM wParam, LPARAM lParam); void UpdateDevice(PDEV_BROADCAST_DEVICEINTERFACE_A pDevInf, WPARAM wParam); BOOL FindDevice(HDEVINFO& hDevInfo, string& szDevId, SP_DEVINFO_DATA& spDevInfoData); string GetClassDesc(const GUID* pGuid); string& replace_all_distinct(string& str, const string& old_value, const string& new_value); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { DWORD nSize = sizeof(PcName); bool b = GetComputerName(PcName, &nSize); WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION)); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = NULL; wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION)); if (!RegisterClassEx(&wcex)) { return -1; } hInst = hInstance; HWND hWnd = CreateWindow(szWindowClass,szTitle,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,NULL,NULL,hInstance,NULL); if (!hWnd) { return -1; } ShowWindow(hWnd, SW_HIDE); UpdateWindow(hWnd); hNotificationHandl = hWnd; bool bInit = InitDeviceInterface(); if (!bInit) { return -1; } MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (int) msg.wParam; } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hdc; TCHAR greeting[] = _T("Hello, World!"); switch (message) { case WM_PAINT: hdc = BeginPaint(hWnd, &ps); TextOut(hdc,5, 5,greeting, _tcslen(greeting)); EndPaint(hWnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); break; case WM_DEVICECHANGE: switch(wParam) { case DBT_CONFIGCHANGECANCELED: { } break; case DBT_CONFIGCHANGED: { } break; case DBT_DEVICEARRIVAL: { JudgeDevice(wParam, lParam); } break; case DBT_DEVICEQUERYREMOVE: { } break; case DBT_DEVICEQUERYREMOVEFAILED: { } break; case DBT_DEVICEREMOVECOMPLETE: { JudgeDevice(wParam, lParam); } break; case DBT_DEVICEREMOVEPENDING: { } break; case DBT_DEVICETYPESPECIFIC: { } break; case DBT_QUERYCHANGECONFIG: { } break; case DBT_USERDEFINED: { } break; case WM_DEVICECHANGE: { } break; default: { } break; } default: return DefWindowProc(hWnd, message, wParam, lParam); break; } return 0; } bool InitDeviceInterface() { if (!hNotificationHandl) { MessageBox(NULL, TEXT("hNotificationHandl is NULL!"), TEXT("Notification from UkeyClient.lib:"), MB_OK); return FALSE; } HDEVNOTIFY hDevNotify; DEV_BROADCAST_DEVICEINTERFACE NotificationFilter; ZeroMemory( &NotificationFilter, sizeof(NotificationFilter) ); NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE); NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; for(int i=0; i<sizeof(GUID_DEVINTERFACE_LIST)/sizeof(GUID); i++) { NotificationFilter.dbcc_classguid = GUID_DEVINTERFACE_LIST[i]; hDevNotify = RegisterDeviceNotification(hNotificationHandl, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE); if( !hDevNotify ) { MessageBox(NULL, TEXT("Can't register device notification!"), TEXT("Notification from UkeyClient.lib:"), MB_ICONEXCLAMATION); return FALSE; } return TRUE; } return TRUE; } UINT JudgeDevice(WPARAM wParam, LPARAM lParam) { if(!(DBT_DEVICEARRIVAL == wParam || DBT_DEVICEREMOVECOMPLETE == wParam)) return S_FALSE; PDEV_BROADCAST_HDR pHdr = (PDEV_BROADCAST_HDR)lParam; PDEV_BROADCAST_DEVICEINTERFACE pDevInf; PDEV_BROADCAST_HANDLE pDevHnd; PDEV_BROADCAST_OEM pDevOem; PDEV_BROADCAST_PORT pDevPort; PDEV_BROADCAST_VOLUME pDevVolume; switch( pHdr->dbch_devicetype ) { case DBT_DEVTYP_DEVICEINTERFACE: pDevInf = (PDEV_BROADCAST_DEVICEINTERFACE)pHdr; UpdateDevice(pDevInf, wParam); break; case DBT_DEVTYP_HANDLE: pDevHnd = (PDEV_BROADCAST_HANDLE)pHdr; break; case DBT_DEVTYP_OEM: pDevOem = (PDEV_BROADCAST_OEM)pHdr; break; case DBT_DEVTYP_PORT: pDevPort = (PDEV_BROADCAST_PORT)pHdr; break; case DBT_DEVTYP_VOLUME: pDevVolume = (PDEV_BROADCAST_VOLUME)pHdr; break; } return S_OK; } void UpdateDevice(PDEV_BROADCAST_DEVICEINTERFACE pDevInf, WPARAM wParam) { if (!(strlen(pDevInf->dbcc_name) > 4)) { MessageBox(NULL, _T("pDevInf->dacc_name length error!"), _T("UpdateDevice note:"), NULL); return; } string szDevIdOld(pDevInf->dbcc_name + 4); string old_value("#"); string new_value("\\"); string szDevId = replace_all_distinct(szDevIdOld, old_value, new_value); transform(szDevId.begin(), szDevId.end(), szDevId.begin(), toupper); int idex = szDevId.find("\\"); if (-1 == idex) { MessageBox(NULL, _T("szDevId.find(\"\\\") error!"), _T("UpdateDevice note:"), NULL); return; } string szClass = szDevId.substr(0, 3); const char* pchClass = szClass.c_str(); DWORD dwFlag = DBT_DEVICEARRIVAL != wParam ? DIGCF_ALLCLASSES : (DIGCF_ALLCLASSES | DIGCF_PRESENT); HDEVINFO hDevInfo = SetupDiGetClassDevs(NULL,pchClass,NULL,dwFlag); if(INVALID_HANDLE_VALUE == hDevInfo) { MessageBox(NULL, _T("SetupDiGetClassDevs(): return ERROR!"), _T("UpdateDevice note:"), NULL); return; } SP_DEVINFO_DATA spDevInfoData; TCHAR buf[MAX_PATH]; if (FindDevice(hDevInfo, szDevId, spDevInfoData)) { DWORD DataT ; DWORD nSize = 0; /*get Friendly Name or Device Description*/ if (SetupDiGetDeviceRegistryProperty(hDevInfo, &spDevInfoData, SPDRP_FRIENDLYNAME, &DataT, (PBYTE)buf, sizeof(buf), &nSize)) { } else if (SetupDiGetDeviceRegistryProperty(hDevInfo, &spDevInfoData, SPDRP_DEVICEDESC, &DataT, (PBYTE)buf, sizeof(buf), &nSize)) { } else { lstrcpy(buf, _T("Unknown")); } } string Arrival = ": 裝置插入"; string Removel = ": 裝置移除"; string stPcName(PcName); string PC = "計算機名:" + stPcName; string stDeviceDescription(buf); string stDeviceName = GetClassDesc(&(spDevInfoData.ClassGuid)); string stShowArrival = stDeviceName + Arrival + "\n" + "[裝置描述: " + stDeviceDescription + "]"; string stShowRemove = stDeviceName + Removel + "\n" + "[裝置描述: " + stDeviceDescription + "]"; const char* chPcName = PC.c_str(); const char* chShowArrival = stShowArrival.c_str(); const char* chShowRemove = stShowRemove.c_str(); if (DBT_DEVICEARRIVAL == wParam) { MessageBox(NULL, chShowArrival, chPcName, MB_OK); } else { MessageBox(NULL, chShowRemove, chPcName, MB_OK); } SetupDiDestroyDeviceInfoList(hDevInfo); } BOOL FindDevice(HDEVINFO& hDevInfo, string& szDevId, SP_DEVINFO_DATA& spDevInfoData) { int nPos = szDevId.find("\\{"); string stDevIdShort(szDevId, 0, nPos); spDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA); for (int i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &spDevInfoData); i++) { DWORD nSize = 0; TCHAR buf[MAX_PATH]; if (!SetupDiGetDeviceInstanceId(hDevInfo, &spDevInfoData, buf, sizeof(buf), &nSize)) { MessageBox(NULL, _T("SetupDiGetDeviceInstanceId(): error"), _T("FindDevice() note:"), NULL); return FALSE; } if (stDevIdShort == buf) { return TRUE; } } return FALSE; } string GetClassDesc(const GUID* pGuid) { TCHAR buf[MAX_PATH]; DWORD size; if (SetupDiGetClassDescription(pGuid, buf, sizeof(buf), &size) ) { return string(buf); } else { return _T(""); } } string& replace_all_distinct(string& str, const string& old_value, const string& new_value) { for(string::size_type pos(0); pos != string::npos; pos += new_value.length()) { if((pos = str.find(old_value, pos)) != string::npos) { str.replace(pos,old_value.length(),new_value); } else { break; } } return str; }