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

📄 mfc_usbviewdlg.cpp

📁 USB容量获取用DeviceIoControl得到U盘物理参数!
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// MFC_USBViewDlg.cpp : implementation file
//

#include "stdafx.h"
#include "MFC_USBView.h"
#include "MFC_USBViewDlg.h"

#include <usbioctl.h>
#include <winioctl.h>
#include <usb100.h>
#include "vndrlist.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

#if DBG
#define ALLOC(dwBytes) MyAlloc(__FILE__, __LINE__, (dwBytes))
#define REALLOC(hMem, dwBytes) MyReAlloc((hMem), (dwBytes))
#define FREE(hMem)  MyFree((hMem))
#define CHECKFORLEAKS() MyCheckForLeaks()
#else
#define ALLOC(dwBytes) GlobalAlloc(GPTR,(dwBytes))
#define REALLOC(hMem, dwBytes) GlobalReAlloc((hMem), (dwBytes), (GMEM_MOVEABLE|GMEM_ZEROINIT))
#define FREE(hMem)  GlobalFree((hMem))
#define CHECKFORLEAKS()
#endif

typedef DWORD       DEVNODE, DEVINST;

#define NUM_HCS_TO_CHECK 10
#define BUFFERALLOCINCREMENT        8192
#define BUFFERMINFREESPACE          1024

PCHAR ConnectionStatuses[] =
{
    "NoDeviceConnected",
    "DeviceConnected",
    "DeviceFailedEnumeration",
    "DeviceGeneralFailure",
    "DeviceCausedOvercurrent",
    "DeviceNotEnoughPower"
};

CHAR *TextBuffer = NULL;
int   TextBufferLen = 0;
int   TextBufferPos = 0;

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMFC_USBViewDlg dialog

CMFC_USBViewDlg::CMFC_USBViewDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CMFC_USBViewDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CMFC_USBViewDlg)
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	m_iNodeValue=0;
}

void CMFC_USBViewDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CMFC_USBViewDlg)
	DDX_Control(pDX, IDC_TREE1, m_MyTree);
	DDX_Control(pDX, IDC_LIST2, m_MyList);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CMFC_USBViewDlg, CDialog)
	//{{AFX_MSG_MAP(CMFC_USBViewDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMFC_USBViewDlg message handlers

BOOL CMFC_USBViewDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	DWORD dwStyle = GetWindowLong(m_MyTree.m_hWnd,GWL_STYLE);
    dwStyle |= TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT;
    SetWindowLong(m_MyTree.m_hWnd,GWL_STYLE,dwStyle);
	RefreshTree();
	DestroyTextBuffer();
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CMFC_USBViewDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CMFC_USBViewDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CMFC_USBViewDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CMFC_USBViewDlg::RefreshTree()
{
	CHAR  statusText[128];
    ULONG devicesConnected;
	//SetDlgItemText(IDC_STATIC1,"");
    // 列举所有的USB
    EnumerateHostControllers(&devicesConnected);
    // 更新状态行设备连接数
    wsprintf(statusText, "Devices Connected: %d   Hubs Connected: %d", devicesConnected, m_TotalHubs);
	SetDlgItemText(IDC_STATIC1,statusText);
}

void CMFC_USBViewDlg::OOPS()
{
	//MessageBox("错误信息");
}

void CMFC_USBViewDlg::EnumerateHostControllers(ULONG *DevicesConnected)
{
	char        HCName[16];
    int         HCNum;
    HANDLE      hHCDev;
    //HTREEITEM   hHCItem;
    PCHAR       rootHubName;
    PCHAR       leafName;
    m_TotalDevicesConnected = 0;
    m_TotalHubs = 0;
	CString strUsbInfo;
	HTREEITEM root1,root2,root3,root4;
	HTREEITEM subRoot1,subRoot2,subRoot3,subRoot4;
	//int iNodeValue=0;
    // 在一些主机上方反复控制器名字和尝试打开他们.
    for (HCNum = 0; HCNum < NUM_HCS_TO_CHECK; HCNum++)
    {
		//HCNum=3;
        wsprintf(HCName, "\\\\.\\HCD%d", HCNum);
        hHCDev = CreateFile(HCName,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
        // 如果这句柄是正确的,然后我们已经成功地打开一个主机控制器.
        // 有关主机控制器显示一些它本身的信息,然后对主机控制器列举根HUB附件.
        if (hHCDev != INVALID_HANDLE_VALUE)
        {
            PCHAR driverKeyName, deviceDesc;
            driverKeyName = GetHCDDriverKeyName(hHCDev);
            leafName = HCName + sizeof("\\\\.\\") - sizeof("");
            if (driverKeyName)
            {
				m_iNodeValue++;
                deviceDesc = DriverNameToDeviceDesc(driverKeyName);
				strUsbInfo.Format("%s",deviceDesc);
				switch(m_iNodeValue)
				{
				case 1:
					root1=m_MyTree.InsertItem(strUsbInfo,0,1,TVI_ROOT,TVI_LAST);
					subRoot1=m_MyTree.InsertItem("RootHub",0,1,root1,TVI_LAST);
					break;
				case 2:
					root2=m_MyTree.InsertItem(strUsbInfo,0,1,TVI_ROOT,TVI_LAST);
					subRoot2=m_MyTree.InsertItem("RootHub",0,1,root2,TVI_LAST);
					break;
				case 3:
					root3=m_MyTree.InsertItem(strUsbInfo,0,1,TVI_ROOT,TVI_LAST);
					subRoot3=m_MyTree.InsertItem("RootHub",0,1,root3,TVI_LAST);
					break;
				case 4:
					root4=m_MyTree.InsertItem(strUsbInfo,0,1,TVI_ROOT,TVI_LAST);
					subRoot4=m_MyTree.InsertItem("RootHub",0,1,root4,TVI_LAST);
					break;
				}
                if(deviceDesc)
                {
                    leafName = deviceDesc;
                }
                FREE(driverKeyName);
            }         
            rootHubName = GetRootHubName(hHCDev);
            if (rootHubName != NULL)
            {
                EnumerateHub(rootHubName,NULL,NULL,NULL,"RootHub" );
            }
            CloseHandle(hHCDev);
        }
    }
    *DevicesConnected = m_TotalDevicesConnected;
}

PCHAR CMFC_USBViewDlg::GetHCDDriverKeyName(HANDLE HCD)
{	
	BOOL                    success;
    ULONG                   nBytes;
    USB_HCD_DRIVERKEY_NAME  driverKeyName;
    PUSB_HCD_DRIVERKEY_NAME driverKeyNameW;
    PCHAR                   driverKeyNameA;
    driverKeyNameW = NULL;
    driverKeyNameA = NULL;
    // 获得HCD的传动键的名字长度
    success = DeviceIoControl(HCD,
							  IOCTL_GET_HCD_DRIVERKEY_NAME,
							  &driverKeyName,sizeof(driverKeyName),
							  &driverKeyName,sizeof(driverKeyName),
							  &nBytes,NULL);
    if (!success)
    {
        OOPS();
        goto GetHCDDriverKeyNameError;
    }
    // 分配空间给传动键名
    nBytes = driverKeyName.ActualLength;
    if (nBytes <= sizeof(driverKeyName))
    {
        OOPS();
        goto GetHCDDriverKeyNameError;
    }
    driverKeyNameW = (_USB_HCD_DRIVERKEY_NAME *)ALLOC(nBytes);
    if (driverKeyNameW == NULL)
    {
        OOPS();
        goto GetHCDDriverKeyNameError;
    }
    // 获得被附上到被叙述的端口设备的传动键的名字.
    success = DeviceIoControl(HCD,IOCTL_GET_HCD_DRIVERKEY_NAME,driverKeyNameW,nBytes,
                              driverKeyNameW,nBytes,&nBytes,NULL);
    if (!success)
    {
        OOPS();
        goto GetHCDDriverKeyNameError;
    }
    // 转换传动键名
    driverKeyNameA = WideStrToMultiStr(driverKeyNameW->DriverKeyName);
    // 全部完成了, 释放被不隐蔽的传动键名字并且归还被转换的传动键名字
    FREE(driverKeyNameW);
    return driverKeyNameA;
GetHCDDriverKeyNameError:
    // 有一个错误,被分派的自由任何事
    if (driverKeyNameW != NULL)
    {
        FREE(driverKeyNameW);
        driverKeyNameW = NULL;
    }
    return NULL;
}

PCHAR CMFC_USBViewDlg::WideStrToMultiStr(PWCHAR WideStr)
{
	ULONG nBytes;
    PCHAR MultiStr;
    // 获得这修改字符串的长度
    nBytes = WideCharToMultiByte(CP_ACP,0,WideStr,-1,NULL,0,NULL,NULL);
    if (nBytes == 0)
    {
        return NULL;
    }
    // 分配空间给被修改的字符串
    MultiStr = (char *)ALLOC(nBytes);
    if (MultiStr == NULL)
    {
        return NULL;
    }
    // 转换字符串
    nBytes = WideCharToMultiByte(CP_ACP,0,WideStr,-1,MultiStr,nBytes,NULL,NULL);
    if (nBytes == 0)
    {
        FREE(MultiStr);
        return NULL;
    }
    return MultiStr;
}

PCHAR CMFC_USBViewDlg::DriverNameToDeviceDesc(PCHAR DriverName)
{
	DEVINST     devInst;
    DEVINST     devInstNext;
    CONFIGRET   cr;
    ULONG       walkDone = 0;
    ULONG       len;
	CHAR buf[512];
    // 获得根节点
    cr = CM_Locate_DevNode(&devInst, NULL, 0);
    if (cr != CR_SUCCESS)
    {
        return NULL;
    }
    // 做第一次深入搜索看DevNode里是否有匹配的DriverName值

    while (!walkDone)
    {
        // 获得DriverName值
        len = sizeof(buf);
        cr = CM_Get_DevNode_Registry_Property(devInst, CM_DRP_DRIVER, NULL, buf, &len, 0);
        // 如果DriverName值匹配,返回设备描述符
        if (cr == CR_SUCCESS && strcmp(DriverName, buf) == 0)
        {
            len = sizeof(buf);
            cr = CM_Get_DevNode_Registry_Property(devInst, CM_DRP_DEVICEDESC, NULL, buf, &len, 0);
            if (cr == CR_SUCCESS)
            {
                return buf;
            }
            else
            {
                return NULL;
            }
        }
        // 这DevNode不匹配,将转到下一个.
        cr = CM_Get_Child(&devInstNext, devInst, 0);
        if (cr == CR_SUCCESS)
        {
            devInst = devInstNext;
            continue;
        }
        // 更进一步不能变下任何,去过到下一个同属.如果没有较多的同属, 回去在直到上面有一个同属.
        // 如果我们不能上升更更进一步了,我们在根回来,而且我们完成了
        for (;;)
        {
            cr = CM_Get_Sibling(&devInstNext, devInst, 0);
            if (cr == CR_SUCCESS)
            {
                devInst = devInstNext;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -