枚举HUB设备

Enum.h

#include <vector>
#include<map>
#include "stdafx.h"
#include <set>

#define  NUM_HCD_TO_CHECK				10
using namespace std;
#define  MAX_DEVICE_NUMS				25
#define  NUM_HCD_TO_CHECK				10

typedef struct _INITIO_MODE_INFO
{
	USHORT nChipId;
	USHORT nModeId;
	USHORT nNvramSize;
	USHORT nOffsetNvramHw;
	BRIDGE_CHIP_TYPE nChipType;
	NVRAM_PROJECT_TYPE nNvramProjType;
	CHAR szModelName[32];
}INITIO_MODE_INFO, *PINITIO_MODE_INFO;

//记录USB树节点信息
typedef struct _TREE_NODE
{
	struct _TREE_NODE *pParent;					//指向父节点,父节点只有一个
	vector<struct _TREE_NODE*> children;//指向子节点,子节点可能有多个

	USHORT nNodeDepth;								//节点路径层
	ULONGLONG nNodePlace;						//节点路径信息

	_TREE_NODE() {
		pParent = NULL;
		nNodeDepth = 0;
		nNodePlace = 1;
	}
	~_TREE_NODE() {
		//DestroyTree( this);这里释放内存会造成递归死循环
	}

	bool operator < (const struct _TREE_NODE &node_) const
	{
		if (nNodeDepth == node_.nNodeDepth)
			return nNodePlace < node_.nNodePlace;
		else
			return nNodeDepth < node_.nNodeDepth;
	}
	bool operator == (const struct _TREE_NODE &node_) const
	{
		return(nNodePlace == node_.nNodePlace && nNodeDepth == node_.nNodeDepth);
	}
	void InsertNode(struct _TREE_NODE* pNodeChild_)
	{
		this->children.push_back(pNodeChild_);
		pNodeChild_->pParent = this;
		pNodeChild_->nNodeDepth = this->nNodeDepth + 1;
		pNodeChild_->nNodePlace =
			this->nNodePlace |
			(ULONGLONG(this->children.size())) << (8 * pNodeChild_->nNodeDepth);
	}
	static void DestroyTree(struct _TREE_NODE* pNode_)
	{
		if (!pNode_->children.empty())
		{
			for (unsigned int i = 0; i < pNode_->children.size(); i++)
				DestroyTree(pNode_->children[i]);
		}
		if (pNode_ != NULL)
		{
			delete pNode_;
			pNode_ = NULL;
		}
	}
}TREE_NODE, *PTREE_NODE;
#define MAX_DEVICE_NUMS_FOR_TOOL			16

//所有磁盘设备串信息
typedef struct _InitioDevDesc
{
	int m_phyNo;
	WCHAR m_devDesc[MAX_PATH];
	_InitioDevDesc()
	{
		m_phyNo = -1;
		memset(m_devDesc, 0x00, sizeof(m_devDesc));
	}
}InitioDevDesc, *PInitioDevDesc;



//设备串信息
typedef struct _INITIO_CD_ROM_INFO
{
	int iPhyNo;
	WCHAR szPathCdRom[MAX_PATH];
	_INITIO_CD_ROM_INFO()
	{
		iPhyNo = -1;
		memset(szPathCdRom, 0x00, sizeof(szPathCdRom));
	}
}INITIO_CD_ROM_INFO, *PINITIO_CD_ROM_INFO;

typedef struct _INITIO_DISK_INFO
{
	int iPhyNo;
	WCHAR szPathDisk[MAX_PATH];
	_INITIO_DISK_INFO()
	{
		iPhyNo = -1;
		ZeroMemory(szPathDisk, sizeof(szPathDisk));
	}
}INITIO_DISK_INFO, *PINITIO_DISK_INFO;

typedef struct _INITIO_USB_INFO
{
	WCHAR szPathUsbHub[MAX_PATH];
	WCHAR szPathUsbPort[MAX_PATH];
	DWORD dwHubInst;
	int iUsbPort;
	USHORT uBcdUSB;
	ULONGLONG nUsbNodePlace;
	_INITIO_USB_INFO()
	{
		iUsbPort = -1;
		dwHubInst = 0;
		ZeroMemory(szPathUsbHub, sizeof(szPathUsbHub));
		ZeroMemory(szPathUsbPort, sizeof(szPathUsbPort));
	}
}INITIO_USB_INFO, *PINITIO_USB_INFO;

//Hub相关信息
typedef struct _HUB_UNIQUE_FLAG
{
	WORD wIdVendor;
	WORD wBcdDevice;
	ULONGLONG nNodePlace;						//节点路径信息
	VOID InitStruct()
	{
		wIdVendor = 0;
		wBcdDevice = 0;
		nNodePlace = 0;
	}
	_HUB_UNIQUE_FLAG()
	{
		wIdVendor = 0;
		wBcdDevice = 0;
		nNodePlace = 0;
	}
	_HUB_UNIQUE_FLAG operator = (const struct _HUB_UNIQUE_FLAG &hubUniqueFlag)
	{
		wIdVendor = hubUniqueFlag.wIdVendor;
		wBcdDevice = hubUniqueFlag.wBcdDevice;
		nNodePlace = hubUniqueFlag.nNodePlace;
		return (*this);
	}

	BOOL operator == (const struct _HUB_UNIQUE_FLAG &hubUniqueFlag) const
	{
		return(wIdVendor == hubUniqueFlag.wIdVendor
			&&wBcdDevice == hubUniqueFlag.wBcdDevice
			/*&&nNodePlace == hubUniqueFlag.nNodePlace*/);
	}
}HUB_UNIQUE_FLAG, *PHUB_UNIQUE_FLAG;

typedef struct _STRING_DESCRIPTOR_NODE
{
	struct _STRING_DESCRIPTOR_NODE *Next;
	UCHAR                           DescriptorIndex;
	USHORT                          LanguageID;
	USB_STRING_DESCRIPTOR           StringDescriptor[1];
} STRING_DESCRIPTOR_NODE, *PSTRING_DESCRIPTOR_NODE;

typedef struct _INITIO_DEVICE_INFO
{
	INITIO_CD_ROM_INFO infoCdRom;
	INITIO_DISK_INFO infoDisk;
	INITIO_USB_INFO infoUsb;
	DEVICE_STATUS m_deviceStatus;
	ENUM_INITIO_DEVICE_FW_STATUS m_fwStatus;			//FW状态,ROM状态,RAM状态等
	HUB_UNIQUE_FLAG m_hubUniqueFlag;					//设备连接的Hub信息,此信息用于设备从U3口掉到U2口后,重新查找磁盘
	USB_DEVICE_DESCRIPTOR m_usbDeviceDes;				//设备描述信息
	PSTRING_DESCRIPTOR_NODE m_pStringDescs;				//pname,vname,sn
	USB_CONNECTION_STATUS ConnectionStatus;
	UCHAR CurrentConfigurationValue;
	USHORT DeviceAddress;
	ULONG NumberOfOpenPipes;
}INITIO_DEVICE_INFO, *PINITIO_DEVICE_INFO;

static set<ULONGLONG> g_setDevPortChain; 

class CEnumIntioUSBDevInfo
{
public:
	CEnumIntioUSBDevInfo();
	~CEnumIntioUSBDevInfo();
	void Refresh(void);
	void CleanDevcie();
	DWORD GetFirstDevice(INITIO_DEVICE_INFO *&initioDevice_);
	USHORT GetAllDevice(INITIO_DEVICE_INFO * pDevice[]);

protected:
	void _RefreshMapDisk();
	void _RefreshMapCdRom();
	void _RefreshUsbHub();
	void _RefreshMapLetter();
	void EnumerateHostController(HANDLE hHCDev_);
	void EnumerateHub(PCHAR ptrHubName_, PTREE_NODE nodeParent_, WORD wIdVendor_ = 0, WORD wBcdDevice_ = 0);
	void EnumerateHubPorts(HANDLE hHubDevice_, LPCSTR lpszHubPath_, ULONG ulNumPorts_, PTREE_NODE nodeHub_);
	PCHAR GetExternalHubName(HANDLE hHub_, ULONG ulConnectionIndex_);
	BOOL FindHubUniqueFlagbyNodePlace(PHUB_UNIQUE_FLAG pHubUniqueFlag_, ULONGLONG nNodePlace_);

	PCHAR _GetDeviceInterfaceDetail(HDEVINFO hDeviceInfoSet_, PSP_DEVICE_INTERFACE_DATA pDeviceInterfaceData_, DEVINST &dInst_);
	BOOL _GetUsbPathByDriverKeyName(LPCSTR lpszDriverKeyName_, PCHAR pBufferPath_, DEVINST &dInst_);
	PCHAR _GetDriverKeyName(HANDLE hHub_, ULONG nConnectionIndex_);
	PCHAR GetHCDDriverKeyName(HANDLE hHCD);
	PCHAR GetRootHubName(HANDLE hHostController);
	PCHAR _WideStrToMultiStr(PWCHAR WideStr);
	UINT32 CommandReadChipID(HANDLE hHubDevice, ULONG nConnectionIndex_, DWORD aOutPutDataLen, UCHAR *pDataOut);
	BOOL MatchChipID(USHORT aChipId, INITIO_MODE_INFO &aModeInfo);
	PSTRING_DESCRIPTOR_NODE GetAllStringDescriptors(HANDLE hHubDevice, ULONG ConnectionIndex, PUSB_DEVICE_DESCRIPTOR DeviceDesc);
	PSTRING_DESCRIPTOR_NODE GetStringDescriptor(HANDLE hHubDevice, ULONG ConnectionIndex, UCHAR DescriptorIndex, USHORT  LanguageID);
	HRESULT GetStringDescriptors(HANDLE hHubDevice, ULONG ConnectionIndex, UCHAR DescriptorIndex, ULONG NumLanguageIDs, USHORT *LanguageIDs, PSTRING_DESCRIPTOR_NODE StringDescNodeHead);
	UINT32 InitDevHandle(TCHAR *aDesc,HANDLE &aHandle);
	BOOL IsInitioDev(HANDLE aHandle);
public:
	INITIO_DEVICE_INFO *m_pDeviceArray[MAX_DEVICE_NUMS];	           //物理设备info
	USHORT m_nCountDevice;	                                           //物理设备个数

	map<DEVINST, INITIO_CD_ROM_INFO> *m_pMapCdRomInfo;
	map<DEVINST, INITIO_DISK_INFO> *m_pMapDiskInfo;
	map<ULONGLONG, HUB_UNIQUE_FLAG> *m_pMultimapHubUniqueFlagToPlace;  //记录Hub信息,用于复位时U2变成U3记录信息
	map<UINT32, CHAR>* m_pMapPhyNumtoLetter;
	vector<InitioDevDesc> m_devDescList;                               //所有的设备串,包括一个Bridge设备多个硬盘或者多个分区,用于给单个磁盘发送SCSI命令,主要运用于3610接多个磁盘

	PTREE_NODE m_pRootNode;		                                       //记录PC HOST 的USB设备数信息
	UINT32 m_master;			                                       //芯片信号掩码
};

Enum.cpp

void CEnumIntioUSBDevInfo::_RefreshUsbHub()
{
	WCHAR HCName[16];
	HANDLE hHCDev;

	for (int iHCD_NUM = 0; iHCD_NUM < NUM_HCD_TO_CHECK; iHCD_NUM++)
	{
		wsprintf(HCName, _T("\\\\.\\HCD%d"), iHCD_NUM);
		hHCDev = CreateFile(HCName,
			GENERIC_WRITE,
			FILE_SHARE_WRITE,
			NULL,
			OPEN_EXISTING,
			0,
			NULL);
		if (hHCDev != INVALID_HANDLE_VALUE)
		{
			EnumerateHostController(hHCDev);
			CloseHandle(hHCDev);
		}
	}
}

void CEnumIntioUSBDevInfo::EnumerateHostController(HANDLE hHCDev)
{
	PCHAR driverKeyName;
	PCHAR rootHubName;
	driverKeyName = GetHCDDriverKeyName(hHCDev);
	if (driverKeyName != NULL)
	{
		GlobalFree(driverKeyName);

		rootHubName = GetRootHubName(hHCDev);
		if (rootHubName != NULL)
		{
			EnumerateHub(rootHubName, m_pRootNode);
			GlobalFree(rootHubName);
		}
	}
	return;
}

void CEnumIntioUSBDevInfo::EnumerateHub(PCHAR ptrHubName_, PTREE_NODE nodeParent_, WORD wIdVendor_, WORD wBcdDevice_)
{
	PCHAR deviceName = (PCHAR)GlobalAlloc(GPTR, strlen(ptrHubName_) + sizeof("\\\\.\\"));
	if (NULL == deviceName)
		return;

	HUB_UNIQUE_FLAG hubUniqueFlag;

	strcpy_s(deviceName, sizeof("\\\\.\\"), "\\\\.\\");
	strcpy_s(deviceName + sizeof("\\\\.\\") - 1, strlen(ptrHubName_) + 1, ptrHubName_);
	HANDLE hHubDevice = CreateFileA(deviceName,
		GENERIC_WRITE,
		FILE_SHARE_WRITE,
		NULL,
		OPEN_EXISTING,
		0,
		NULL);
	if (INVALID_HANDLE_VALUE == hHubDevice)
		return;

	PUSB_NODE_INFORMATION hubInfo = (PUSB_NODE_INFORMATION)GlobalAlloc(GPTR, sizeof(USB_NODE_INFORMATION));
	if (NULL == hubInfo)
	{
		goto EnumerateHubError;
	}


	DWORD dwRequireSize = 0;
	BOOL success = DeviceIoControl(hHubDevice,
		IOCTL_USB_GET_NODE_INFORMATION,
		hubInfo,
		sizeof(USB_NODE_INFORMATION),
		hubInfo,
		sizeof(USB_NODE_INFORMATION),
		&dwRequireSize,
		NULL);
	if (!success)
		goto EnumerateHubError;

	//添加树节点,此处是一个Hub节点
	PTREE_NODE nodeHub = new TREE_NODE;
	nodeParent_->InsertNode(nodeHub);
	hubUniqueFlag.wBcdDevice = wBcdDevice_;
	hubUniqueFlag.wIdVendor = wIdVendor_;
	hubUniqueFlag.nNodePlace = nodeHub->nNodePlace;
	m_pMultimapHubUniqueFlagToPlace->insert(pair<ULONGLONG, HUB_UNIQUE_FLAG>(nodeHub->nNodePlace, hubUniqueFlag));

	UINT32 nHubPorts = hubInfo->u.HubInformation.HubDescriptor.bNumberOfPorts;
	EnumerateHubPorts(hHubDevice, deviceName, nHubPorts, nodeHub);

	GlobalFree(deviceName);
	CloseHandle(hHubDevice);
	return;

EnumerateHubError:
	if (hHubDevice != INVALID_HANDLE_VALUE)
	{
		CloseHandle(hHubDevice);
		hHubDevice = INVALID_HANDLE_VALUE;
	}
	if (hubInfo != NULL)
	{
		GlobalFree(hubInfo);
		hubInfo = NULL;
	}
	if (deviceName != NULL)
	{
		GlobalFree(deviceName);
		deviceName = NULL;
	}
}

void CEnumIntioUSBDevInfo::EnumerateHubPorts(HANDLE hHubDevice_, LPCSTR lpszHubPath_, ULONG ulNumPorts_, PTREE_NODE nodeHub_)
{
	PUSB_NODE_CONNECTION_INFORMATION pUsbNodeConnInfo;
	PSTRING_DESCRIPTOR_NODE pStringDescs = NULL;
	USES_CONVERSION;

	UINT8 index;
	for (index = 1; index <= ulNumPorts_; index++)
	{
		DWORD dwRequireSize = sizeof(USB_NODE_CONNECTION_INFORMATION) + sizeof(USB_PIPE_INFO) * 30;
		pUsbNodeConnInfo = (PUSB_NODE_CONNECTION_INFORMATION)GlobalAlloc(GPTR, dwRequireSize);
		if (NULL == pUsbNodeConnInfo)
			break;

		pUsbNodeConnInfo->ConnectionIndex = index;
		BOOL success = DeviceIoControl(hHubDevice_,
			IOCTL_USB_GET_NODE_CONNECTION_INFORMATION,
			pUsbNodeConnInfo,
			dwRequireSize,
			pUsbNodeConnInfo,
			dwRequireSize,
			&dwRequireSize,
			NULL);
		if (!success)
		{
			GlobalFree(pUsbNodeConnInfo);
			continue;
		}

		if (pUsbNodeConnInfo->DeviceIsHub) //如果连接的是Hub则循环枚举
		{
			PCHAR extHubName = GetExternalHubName(hHubDevice_, index);
			if (extHubName != NULL)
			{
				EnumerateHub(extHubName, nodeHub_, pUsbNodeConnInfo->DeviceDescriptor.idVendor, pUsbNodeConnInfo->DeviceDescriptor.bcdDevice);
				continue;
			}
		}
		else
		{
			PTREE_NODE nodeDevice = new TREE_NODE;
			nodeHub_->InsertNode(nodeDevice);

			BOOL foundDevice = FALSE;

			INITIO_MODE_INFO modeInfo;
			BRIDGE_CHIP_TYPE chipType;

			INITIO_DEVICE_INFO infoDevice;
			UINT32 retValue = INITIO_API_ERR_SUC;
			if (pUsbNodeConnInfo->ConnectionStatus != NoDeviceConnected)//如果连接则可能是磁盘设备
			{
				CHAR szPathUsb[MAX_PATH] = { 0 };
				PCHAR pDriverKeyName = _GetDriverKeyName(hHubDevice_, index);
				if (NULL != pDriverKeyName)
				{
					DEVINST dInst = 0;
					if (!_GetUsbPathByDriverKeyName(pDriverKeyName, szPathUsb, dInst))
						break;
					do
					{
						if (g_setDevPortChain.find(nodeDevice->nNodePlace) == g_setDevPortChain.end())
						{
							CHAR szPathScsi[MAX_PATH] = { 0 };
							ZeroMemory(szPathScsi, sizeof(szPathScsi));
							if (m_pMapDiskInfo->count(dInst) > 0)
								strcpy_s(szPathScsi, strlen(W2A(m_pMapDiskInfo->at(dInst).szPathDisk)) + 1, W2A(m_pMapDiskInfo->at(dInst).szPathDisk));
							else if (m_pMapCdRomInfo->count(dInst) > 0)
								strcpy_s(szPathScsi, strlen(W2A(m_pMapCdRomInfo->at(dInst).szPathCdRom)) + 1, W2A(m_pMapCdRomInfo->at(dInst).szPathCdRom));
							HANDLE hDevice = NULL;
							
						}
						foundDevice = TRUE;
						CM_Get_Parent(&infoDevice.infoUsb.dwHubInst, dInst, 0);
						if (m_pMapCdRomInfo->count(dInst) > 0)
						{
							infoDevice.infoCdRom = m_pMapCdRomInfo->at(dInst);
							infoDevice.m_deviceStatus = DEVICE_STATUS_CDROM;
						}
						if (m_pMapDiskInfo->count(dInst) > 0)
						{
							infoDevice.infoDisk = m_pMapDiskInfo->at(dInst);
							infoDevice.m_deviceStatus = DEVICE_STATUS_DISK;
						}

						if (m_pMapDiskInfo->count(dInst) > 0 &&
							m_pMapCdRomInfo->count(dInst) > 0)
						{
							infoDevice.m_deviceStatus = DEVICE_STATUS_CDROM_DISK;
						}
						GlobalFree(pDriverKeyName);
					} while (0);
				}
				if (foundDevice == TRUE)
				{
					HUB_UNIQUE_FLAG hubUniqueFlag;

					//根据设备路径找到所连接的Hub相关信息
					if (FindHubUniqueFlagbyNodePlace(&hubUniqueFlag, nodeDevice->pParent->nNodePlace))
					{
						infoDevice.m_hubUniqueFlag = hubUniqueFlag;
					}

					USES_CONVERSION;
					infoDevice.infoUsb.iUsbPort = index;
					infoDevice.infoUsb.uBcdUSB = pUsbNodeConnInfo->DeviceDescriptor.bcdUSB;
					wcscpy_s(infoDevice.infoUsb.szPathUsbHub, A2W(lpszHubPath_));
					wcscpy_s(infoDevice.infoUsb.szPathUsbPort, A2W(szPathUsb));
					infoDevice.infoUsb.nUsbNodePlace = nodeDevice->nNodePlace;
					pStringDescs = GetAllStringDescriptors(hHubDevice_, index, &pUsbNodeConnInfo->DeviceDescriptor);
					infoDevice.m_pStringDescs = pStringDescs;
					memcpy(&infoDevice.m_usbDeviceDes, &pUsbNodeConnInfo->DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR));
					infoDevice.ConnectionStatus = pUsbNodeConnInfo->ConnectionStatus;
					infoDevice.CurrentConfigurationValue = pUsbNodeConnInfo->CurrentConfigurationValue;
					infoDevice.DeviceAddress = pUsbNodeConnInfo->DeviceAddress;
					infoDevice.NumberOfOpenPipes = pUsbNodeConnInfo->NumberOfOpenPipes;

					m_pDeviceArray[m_nCountDevice] = new INITIO_DEVICE_INFO;
					memcpy(m_pDeviceArray[m_nCountDevice], &infoDevice, sizeof(INITIO_DEVICE_INFO));
					m_nCountDevice++;
				}
			}

		}
	}
}

stdafx.h

// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件

#pragma once

#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN            // 从 Windows 头中排除极少使用的资料
#endif

#include "targetver.h"

#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS      // 某些 CString 构造函数将是显式的

// 关闭 MFC 对某些常见但经常可放心忽略的警告消息的隐藏
#define _AFX_ALL_WARNINGS

#include <afxwin.h>         // MFC 核心组件和标准组件
#include <afxext.h>         // MFC 扩展


#include <afxdisp.h>        // MFC 自动化类



#ifndef _AFX_NO_OLE_SUPPORT
#include <afxdtctl.h>           // MFC 对 Internet Explorer 4 公共控件的支持
#endif
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h>             // MFC 对 Windows 公共控件的支持
#endif // _AFX_NO_AFXCMN_SUPPORT

#include <afxcontrolbars.h>     // 功能区和控件条的 MFC 支持









#ifdef _UNICODE
#if defined _M_IX86
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_X64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#else
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif
#endif

#include <winioctl.h>
#include"ErrorCode.h"
#include <cfgmgr32.h>
#include <SetupAPI.h>
#pragma comment(lib,"setupapi.lib")
#include <guiddef.h>
#include <initguid.h>  
#include <no_sal2.h>
#include <usbiodef.h>
#include <usbioctl.h>
#include"SCSI.h"
#include"Enum.h"
#include <minwindef.h>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值