⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 device.cpp

📁 设备管理程序
💻 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 + -