📄 device.cpp
字号:
#include "StdAfx.h"
#include "Device.h"
#include "dbt.h"
CDevice * g_device = NULL;
HINSTANCE hAppInstance = NULL;
CDevice::CDevice(void) : hWndMain(NULL),
hTimer(0),
m_EnableDev(0),
m_DisableDev(0)
{
}
CDevice::~CDevice(void)
{
Clear();
}
VOID
CDevice::EnableDevice( ULONG nDev ) // 启用设备
{
m_EnableDev = nDev;
}
VOID
CDevice::DisableDevice( ULONG nDev ) // 禁用设备
{
m_DisableDev = nDev;
}
VOID
CDevice::DeviceChang( ULONG nDev, BOOL IsDisab )
{
if ( (nDev & DEV_BLUETOOTH) == DEV_BLUETOOTH ) // 蓝牙
{
EnumDevice( GUID_DEVCLASS_BLUETOOTH, IsDisab );
}
if ( (nDev & DEV_CDROM) == DEV_CDROM ) // CDROM
{
EnumDevice( GUID_DEVCLASS_CDROM, IsDisab );
}
if ( (nDev & DEV_DISPLAY) == DEV_DISPLAY ) // 显示卡
{
EnumDevice( GUID_DEVCLASS_DISPLAY, IsDisab );
}
if ( (nDev & DEV_FLOPPY) == DEV_FLOPPY ) // 软件驱
{
EnumDevice( GUID_DEVCLASS_FLOPPYDISK, IsDisab );
}
if ( (nDev & DEV_INFRARED) == DEV_INFRARED ) // 红外
{
EnumDevice( GUID_DEVCLASS_INFRARED, IsDisab );
}
if ( (nDev & DEV_KEYBOARD) == DEV_KEYBOARD ) // 键盘
{
EnumDevice( GUID_DEVCLASS_KEYBOARD, IsDisab );
}
if ( (nDev & DEV_MEDIAD) == DEV_MEDIAD ) // 声卡
{
EnumDevice( GUID_DEVCLASS_MEDIA, IsDisab );
}
if ( (nDev & DEV_MODEM) == DEV_MODEM ) // MODEM
{
EnumDevice( GUID_DEVCLASS_MODEM, IsDisab );
}
if ( (nDev & DEV_MOUSE) == DEV_MOUSE ) // 鼠标
{
EnumDevice( GUID_DEVCLASS_MOUSE, IsDisab );
}
if ( (nDev & DEV_NET) == DEV_NET ) // 网卡
{
EnumDevice( GUID_DEVCLASS_NET, IsDisab );
}
if ( (nDev & DEV_PRINT) == DEV_PRINT ) // 打印机
{
EnumDevice( GUID_DEVCLASS_PRINTER, IsDisab );
}
if ( (nDev & DEV_PORT) == DEV_PORT ) // 端口
{
EnumDevice( GUID_DEVCLASS_PORTS, IsDisab );
}
if ( (nDev & DEV_USB) == DEV_USB ) // USB
{
GUID guidUSB;
::CLSIDFromString(L"{53f56307-b6bf-11d0-94f2-00a0c91efb8b}", &guidUSB);
EnumDevice( GUID_DEVCLASS_USB, IsDisab );
}
}
BOOL
CDevice::EnumDevice( GUID guid, BOOL IsDisab )
{
HDEVINFO hDevInfo = ::SetupDiGetClassDevs( &guid, NULL, NULL, DIGCF_PRESENT | DIGCF_PROFILE ); // 返回设备信息句柄
//HDEVINFO hDevInfo = ::SetupDiGetClassDevs( &guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE ); // 返回设备信息句柄
if ( hDevInfo == INVALID_HANDLE_VALUE )
return FALSE;
SP_DEVINFO_DATA DevInfoData = {sizeof(SP_DEVINFO_DATA)};
CDeviceInterface * m_Device;
for ( DWORD DevID = 0; ::SetupDiEnumDeviceInfo( hDevInfo, DevID, &DevInfoData ); ++DevID ) // 遍历设备
{
m_Device = new CDeviceInterface( DevInfoData.ClassGuid, DevID, IsDisab ); // 操作设备
if ( m_Device->Initial() )
{
m_DevInter.push_back( m_Device );
}else
{
delete m_Device;
}
}
::SetupDiDestroyDeviceInfoList( hDevInfo ); // 销毁设备
return TRUE;
}
VOID
CDevice::Clear( void )
{
list<CDeviceInterface*>::iterator iter = m_DevInter.begin();
while ( iter != m_DevInter.end() )
{
delete (CDeviceInterface*)(*iter);
m_DevInter.erase( iter );
iter = m_DevInter.begin();
}
m_DevInter.clear();
}
VOID
CDevice::SetDeviceRefreshInterval( UINT nInterval )
{
if ( hTimer )
::KillTimer( NULL, hTimer );
hTimer = ::SetTimer( this->hWndMain, 0, nInterval, NULL );
}
VOID
CDevice::CheckSet()
{
Clear();
DeviceChang( m_EnableDev, TRUE );
DeviceChang( m_DisableDev, FALSE );
}
VOID
CDevice::CheckChange( VOID )
{
list<CDeviceInterface*>::iterator iter = m_DevInter.begin();
CDeviceInterface * device;
while ( iter != m_DevInter.end() )
{
device = (CDeviceInterface*)(*iter);
++iter;
if ( device == NULL )
continue;
if ( device->IsDisabled() ) // 设备已被禁用
{
if ( device->m_IsDisab ) // 启用设备
{
device->EnableDevice();
}
}else
{
if ( !device->m_IsDisab ) // 禁用设备
{
device->DisableDevice();
}
}
} // end while
}
BOOL
CDevice::Run()
{
UINT ThreadId;
m_hThread = (HANDLE)_beginthreadex(NULL,
0,
ThreadFunc,
(LPVOID)this,
CREATE_SUSPENDED,
&ThreadId);
if ( m_hThread <= 0 )
return FALSE;
::ResumeThread( m_hThread );
return TRUE;
}
unsigned __stdcall
CDevice::ThreadFunc( LPVOID lpParam )
{
CDevice * _this = (CDevice*)lpParam;
WNDCLASS wce;
_this->CheckSet();
wce.style = 0;
wce.lpfnWndProc = (WNDPROC)WndProc;
wce.hCursor = 0;
wce.hIcon = 0;
wce.cbClsExtra = 0;
wce.cbWndExtra = 0;
wce.hbrBackground = 0;
wce.hInstance = hAppInstance;
wce.lpszClassName = "SimpWClass";
wce.lpszMenuName = NULL;
if ( !::RegisterClass( &wce ) )
return FALSE;
_this->hWndMain = ::CreateWindow( "SimpWClass",
"My Window",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hAppInstance,
NULL);
if ( _this->hWndMain == NULL )
return FALSE;
// 守护线程的时钟
_this->SetDeviceRefreshInterval();
/*
MSG msg;
BOOL bRet;
while ( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0 )
{
if ( bRet == -1 )
{
}else
{
::TranslateMessage( &msg );
::DispatchMessage( &msg );
}
}*/
return 0;
}
char FirstDriverFromMask( ULONG unitmask )
{
char i;
for( i = 0; i < 26; ++i )
{
if ( unitmask & 0x1 )
break;
unitmask >>= 1;
}
return (i+'A');
}
LRESULT CALLBACK
WndProc( HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // First message parameter
LPARAM lParam) // second message parameter
{
if ( g_device == NULL )
return 0;
DEV_BROADCAST_HDR * dhr;
switch ( uMsg )
{
case WM_TIMER:
g_device->CheckChange();
break;
case WM_DEVICECHANGE: //
char str[256];
dhr = (DEV_BROADCAST_HDR*)lParam;
switch( wParam )
{
case DBT_DEVICEARRIVAL:
PDEV_BROADCAST_DEVICEINTERFACE lpdbd;
PDEV_BROADCAST_VOLUME lpdbv;
switch( dhr->dbch_devicetype )
{
case DBT_DEVTYP_DEVICEINTERFACE:
lpdbd = (PDEV_BROADCAST_DEVICEINTERFACE)lParam;
sprintf( str, "GUID:%x-%x-%x-%x", lpdbd->dbcc_classguid.Data1, lpdbd->dbcc_classguid.Data2, lpdbd->dbcc_classguid.Data3, lpdbd->dbcc_classguid.Data4 );
break;
case DBT_DEVTYP_VOLUME:
lpdbv = (PDEV_BROADCAST_VOLUME)lParam;
sprintf( str, "Drive: %c 盘插入", FirstDriverFromMask(lpdbv->dbcv_unitmask) );
g_device->CheckSet();
break;
}// end switch
break;
case DBT_DEVICEREMOVECOMPLETE:
if ( dhr->dbch_devicetype == DBT_DEVTYP_VOLUME )
{
PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lParam;
sprintf( str, "Drive: %c 盘拔出", FirstDriverFromMask(lpdbv->dbcv_unitmask) );
g_device->CheckSet();
}
break;
} // end switch( wParam )
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
} // end switch
return DefWindowProc( hwnd, uMsg, wParam, lParam );
}
VOID ReplaceString( LPSTR lpBuf, CHAR c1, CHAR c2 )
{
INT nlen = (INT)strlen(lpBuf);
LPSTR lpTemp = new CHAR[nlen+1];
memset( lpTemp, 0x0, nlen+1 );
INT j = 0;
for ( INT i = 0; i < nlen; ++i )
{
if ( lpBuf[i] == c1 )
{
if ( c2 != 0x0 )
{
lpTemp[j++] = c2;
}
}else
{
lpTemp[j++] = lpBuf[i];
}
}
memset( lpBuf, 0, nlen );
strncpy( lpBuf, lpTemp, j );
delete [] lpTemp;
}
// 获取指定盘符序列号(针对USB优盘有效)
// char cDiskID: 指定的盘符,如"J"
// LPSTR lpPID: 序列号存放缓冲
BOOL GetUSBDiskID( CHAR cDiskID, LPSTR lpPID )
{
CHAR szDrv[4];
sprintf( szDrv, "%c:\\", cDiskID );
if ( ::GetDriveType(szDrv) != DRIVE_REMOVABLE )
{
return FALSE;
}
CHAR lpRegPath[512] = {0};
CHAR lpRegValue[256] = {0};
sprintf( lpRegPath, "SYSTEM\\MountedDevices" );
sprintf( lpRegValue, "\\DosDevices\\%c:", cDiskID );
DWORD dwDataSize = 0;
DWORD dwRegType = REG_BINARY;
LPBYTE lpRegBinData = NULL;
LPSTR lpUSBKeyData = NULL;
// 查询注册表中映射驱动器的设备信息
HKEY hKey;
LONG lRet = ::RegOpenKeyEx( HKEY_LOCAL_MACHINE, // 根键
lpRegPath, // 要访问的键路径
0,
KEY_READ, // 以查询方式访问
&hKey); // 保存此函数打开的键句柄
if ( lRet != ERROR_SUCCESS )
return FALSE;
lRet = ::RegQueryValueEx( hKey,
lpRegValue, // 要查询的键值名
NULL,
&dwRegType, // 查询数据的类型
lpRegBinData, // 保存查询的数据
&dwDataSize); // 预设置的数据长度
if ( lRet != ERROR_SUCCESS )
return FALSE;
lpRegBinData = new BYTE[dwDataSize];
lRet = ::RegQueryValueEx( hKey,
lpRegValue,
NULL,
&dwRegType,
lpRegBinData,
&dwDataSize);
if ( lRet != ERROR_SUCCESS )
{
delete [] lpRegBinData;
return FALSE;
}
::RegCloseKey( hKey );
// 过滤二进制串中的无用信息(将0x0字符去掉)
lpUSBKeyData = new CHAR[dwDataSize];
memset ( lpUSBKeyData, 0x0, dwDataSize );
for( DWORD i = 0, j = 0; i < dwDataSize; ++i )
{
if ( lpRegBinData[i] != 0x0 )
{
lpUSBKeyData[j++] = lpRegBinData[i];
}
}
delete [] lpRegBinData;
// 截取lpUSBKeyData中的有用信息, 例: 7&100a16f&0
// \??\STORAGE#RemovableMedia#7&100a16f&0&RM#{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}
// 63 63 72 75 6E 2E 63 6F 6D
LPSTR lpPos1 = strstr(lpUSBKeyData, "#RemovableMedia#") + 16;
LPSTR lpPos2 = strstr(lpUSBKeyData, "RM");
strncpy( lpUSBKeyData, lpPos1, lpPos2-lpPos1 );
lpUSBKeyData[lpPos2-lpPos1] = 0x0;
strcpy( lpUSBKeyData, strupr(lpUSBKeyData) );
//
GUID guidUSB;
::CLSIDFromString(L"{53f56307-b6bf-11d0-94f2-00a0c91efb8b}", &guidUSB);
HDEVINFO hDevInfo = ::SetupDiGetClassDevs( &guidUSB, NULL, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE );
if ( hDevInfo == INVALID_HANDLE_VALUE )
{
delete [] lpUSBKeyData;
return FALSE;
}
BOOL bSuccess;
DWORD nDevIndex = 0;
SP_DEVINFO_DATA DevData;
SP_DEVICE_INTERFACE_DATA DevIntData;
PSP_DEVICE_INTERFACE_DETAIL_DATA lpDevIntDetailData;
DWORD dwBytesReturned;
// 遍历磁盘设备
do
{
DevIntData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
bSuccess = ::SetupDiEnumDeviceInterfaces( hDevInfo,
NULL,
&guidUSB,
nDevIndex,
&DevIntData);
if ( bSuccess ) // 获取接口详细信息
{
DevData.cbSize = sizeof(SP_DEVINFO_DATA);
dwBytesReturned = 0;
::SetupDiGetDeviceInterfaceDetail( hDevInfo,
&DevIntData,
NULL,
0,
&dwBytesReturned,
&DevData);
if ( dwBytesReturned != 0 && ::GetLastError() != ERROR_INSUFFICIENT_BUFFER )
{
lpDevIntDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)::GlobalAlloc( GMEM_FIXED, dwBytesReturned);
lpDevIntDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
::SetupDiGetDeviceInterfaceDetail( hDevInfo,
&DevIntData,
lpDevIntDetailData,
dwBytesReturned,
&dwBytesReturned,
&DevData);
// 取得设备接口详细信息并根据转化后的路径在注册表中查询
LPSTR lpPathTemp = new CHAR[strlen(lpDevIntDetailData->DevicePath)+256];
strcpy( lpRegPath, "SYSTEM\\CurrentcontrolSet\\Enum\\" );
strcpy( lpPathTemp, lpDevIntDetailData->DevicePath );
lpPos1 = LPSTR(lpPathTemp);
lpPos2 = LPSTR(strstr(lpPathTemp, "{")-1);
strncpy( lpPathTemp, lpPos1, lpPos2-lpPos1 );
lpPathTemp[lpPos2-lpPos1] = 0x0;
ReplaceString( lpPathTemp, '#', '\\' );
strcat( lpRegPath, lpPathTemp );
if ( ::RegOpenKeyEx( HKEY_LOCAL_MACHINE,
lpRegPath,
0,
KEY_READ,
&hKey) != ERROR_SUCCESS )
{
return FALSE;
}
dwRegType = REG_SZ;
LPSTR lpRegSzData = NULL;
dwDataSize = 0;
lRet = ::RegQueryValueEx( hKey,
"ParentIdPrefix",
NULL,
&dwRegType,
(LPBYTE)lpRegSzData,
&dwDataSize);
if ( lRet!= ERROR_SUCCESS )
{
return FALSE;
} // end if
lpRegSzData = new CHAR[dwDataSize];
lRet = ::RegQueryValueEx( hKey,
"ParentIdPrefix",
NULL,
&dwRegType,
(LPBYTE)lpRegSzData,
&dwDataSize);
if ( lRet!= ERROR_SUCCESS )
{
delete [] lpRegSzData;
return FALSE;
}
strcpy( lpRegSzData, strupr(lpRegSzData) );
if ( !strcmp(lpUSBKeyData, lpRegSzData) )
{
// 经对比找到要查找的磁盘设备
strcpy( lpPathTemp, LPSTR(strstr(lpDevIntDetailData->DevicePath,"#")+1) );
lpPos1 = LPSTR(strstr(lpPathTemp, "#")+1);
lpPos2 = LPSTR(strstr(lpPathTemp, "#{"));
strncpy(lpPathTemp, lpPos1, lpPos2-lpPos1 );
lpPathTemp[lpPos2-lpPos1] = 0x0;
// 获取最终序列号
ReplaceString(lpPathTemp, '&', 0x0 );
strncpy( lpPID, strupr(lpPathTemp), 32 );
}
}
} // end if ( bSuccess )
}while ( bSuccess );
::SetupDiDestroyDeviceInfoList( hDevInfo );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -