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

📄 mfc_usbviewdlg.cpp

📁 USB容量获取用DeviceIoControl得到U盘物理参数!
💻 CPP
📖 第 1 页 / 共 3 页
字号:
                break;
            }
            cr = CM_Get_Parent(&devInstNext, devInst, 0);
            if (cr == CR_SUCCESS)
            {
                devInst = devInstNext;
            }
            else
            {
                walkDone = 1;
                break;
            }
        }
    }
    return NULL;
}

PCHAR CMFC_USBViewDlg::GetRootHubName(HANDLE HostController)
{
	BOOL                success;
    ULONG               nBytes;
    USB_ROOT_HUB_NAME   rootHubName;
    PUSB_ROOT_HUB_NAME  rootHubNameW;
    PCHAR               rootHubNameA;
    rootHubNameW = NULL;
    rootHubNameA = NULL;
    // 把根HUB附件的名字长度给主机控制器
    success = DeviceIoControl(HostController,IOCTL_USB_GET_ROOT_HUB_NAME,0,0,
							&rootHubName,sizeof(rootHubName),&nBytes,NULL);
    if (!success)
    {
        OOPS();
        goto GetRootHubNameError;
    }
    // 分配空间非根HUB名
    nBytes = rootHubName.ActualLength;
    rootHubNameW = (_USB_ROOT_HUB_NAME *)ALLOC(nBytes);
    if (rootHubNameW == NULL)
    {
        OOPS();
        goto GetRootHubNameError;
    }
    // 把根HUB附件的名字给主机控制器
    success = DeviceIoControl(HostController,IOCTL_USB_GET_ROOT_HUB_NAME,NULL,0,
                              rootHubNameW,nBytes,&nBytes,NULL);
    if (!success)
    {
        OOPS();
        goto GetRootHubNameError;
    }
    // 转换根HUB名
    rootHubNameA = WideStrToMultiStr(rootHubNameW->RootHubName);
    // 全部完成, 自由地那不隐蔽的根HUB命名而且归还那转换根HUB名字
    FREE(rootHubNameW);
    return rootHubNameA;
GetRootHubNameError:
    // 有一个错误,被分派的自由任何事
    if (rootHubNameW != NULL)
    {
        FREE(rootHubNameW);
        rootHubNameW = NULL;
    }
    return NULL;
}

void CMFC_USBViewDlg::EnumerateHub(PCHAR HubName, 
								   PUSB_NODE_CONNECTION_INFORMATION ConnectionInfo, 
								   PUSB_DESCRIPTOR_REQUEST ConfigDesc, 
								   PSTRING_DESCRIPTOR_NODE StringDescs, 
								   PCHAR DeviceDesc)
{
	HANDLE          hHubDevice;
    //HTREEITEM       hItem;
    PCHAR           deviceName;
    BOOL            success;
    ULONG           nBytes;
    PUSBDEVICEINFO  info;
    CHAR            leafName[512]; // XXXXX 这到底有多么大?
    // 对不分派的州设定本地人初值,如此错误清除常式只试到被成功地分派的清除事物
    info        = NULL;
    hHubDevice  = INVALID_HANDLE_VALUE;
    // 为USBDEVICEINFO结构支持HUB信息分派一些空间,hub名,
    // 而且连接信息指针.GPTR为零是我们设定结构初值.
    info = (PUSBDEVICEINFO) ALLOC(sizeof(USBDEVICEINFO));
    if (info == NULL)
    {
        OOPS();
        goto EnumerateHubError;
    }
    // 维持HUB名字,连接信息和配置描述符指示器
    info->HubName = HubName;
    info->ConnectionInfo = ConnectionInfo;
    info->ConfigDesc = ConfigDesc;
    info->StringDescs = StringDescs;
    // 为这一个HUB分派一些USB_NODE_INFORMATION结构的空间,
    info->HubInfo = (PUSB_NODE_INFORMATION)ALLOC(sizeof(USB_NODE_INFORMATION));
    if (info->HubInfo == NULL)
    {
        OOPS();
        goto EnumerateHubError;
    }
    // 为完整的HUB设备名分配一个临时缓冲区.
    deviceName = (PCHAR)ALLOC(strlen(HubName) + sizeof("\\\\.\\"));
    if (deviceName == NULL)
    {
        OOPS();
        goto EnumerateHubError;
    }
    // 创建这完整的HUB设备名
    strcpy(deviceName, "\\\\.\\");
    strcpy(deviceName + sizeof("\\\\.\\") - 1, info->HubName);
	//deviceName = "\\\\.\\USB#ROOT_HUB#4&173bc1af&0#{f18a0e88-c30c-11d0-8815-00a0c906bed8}";
    // 设法打开这HUB设备
    hHubDevice = CreateFile(deviceName,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
    // 完成这完整的HUB设备名临时缓冲区
    //FREE(deviceName);
    if (hHubDevice == INVALID_HANDLE_VALUE)
    {
        OOPS();
        goto EnumerateHubError;
    }
    // 现在为这一个HUB为 USB_NODE_INFORMATION 结构体 USBHUB.
    // 这将会告诉我们下游的端口数字列举,在其他的事物之中.
    success = DeviceIoControl(hHubDevice,IOCTL_USB_GET_NODE_INFORMATION,info->HubInfo,sizeof(USB_NODE_INFORMATION),
                              info->HubInfo,sizeof(USB_NODE_INFORMATION),&nBytes,NULL);
    if (!success)
    {
        OOPS();
        goto EnumerateHubError;
    }
    // 从这端口数建立页名和设备描述符
    if (ConnectionInfo)
    {
        wsprintf(leafName, "[Port%d] ", ConnectionInfo->ConnectionIndex);
        strcat(leafName, ConnectionStatuses[ConnectionInfo->ConnectionStatus]);
        strcat(leafName, " :  ");
    }
    else
    {
        leafName[0] = 0;
    }
    if (DeviceDesc)
    {
        strcat(leafName, DeviceDesc);
    }
    else
    {
        strcat(leafName, info->HubName);
    }
    // 现在用 PUSBDEVICEINFO 指针信息把一个项目加入 TreeView 如 LPARAM 叁考价值包含我们知道HUB的每件事物.
    //hItem = AddLeaf(hTreeParent,(LPARAM)info,leafName);
    //if (hItem == NULL)
    //{
    //    OOPS();
    //    goto EnumerateHubError;
    //}
    // 现在递归地 enumrate 这一个HUB的端口.
    EnumerateHubPorts(hHubDevice,info->HubInfo->u.HubInformation.HubDescriptor.bNumberOfPorts);
    CloseHandle(hHubDevice);
    return;
EnumerateHubError:
    // 清除分配得到任何的东西
    if (hHubDevice != INVALID_HANDLE_VALUE)
    {
        CloseHandle(hHubDevice);
        hHubDevice = INVALID_HANDLE_VALUE;
    }
    if (info != NULL)
    {
        if (info->HubName != NULL)
        {
            FREE(info->HubName);
            info->HubName = NULL;
        }
        if (info->HubInfo != NULL)
        {
            FREE(info->HubInfo);
            info->HubInfo;
        }
        FREE(info);
        info = NULL;
    }
    if (ConnectionInfo)
    {
        FREE(ConnectionInfo);
    }
    if (ConfigDesc)
    {
        FREE(ConfigDesc);
    }
    if (StringDescs != NULL)
    {
        PSTRING_DESCRIPTOR_NODE Next;
        do {
            Next = StringDescs->Next;
            FREE(StringDescs);
            StringDescs = Next;
        } while (StringDescs != NULL);
    }
}

void CMFC_USBViewDlg::EnumerateHubPorts(HANDLE hHubDevice, ULONG NumPorts)
{
	//HTREEITEM   hItem;
    ULONG       index;
    BOOL        success;
    PUSB_NODE_CONNECTION_INFORMATION    connectionInfo;
    PUSB_DESCRIPTOR_REQUEST             configDesc;
    PSTRING_DESCRIPTOR_NODE             stringDescs;
    PUSBDEVICEINFO                      info;
    PCHAR driverKeyName;
    PCHAR deviceDesc;
    CHAR  leafName[512]; // XXXXX 这到底有多大?
	//HTREEITEM mSubRoot1,mSubRoot2,mSubRoot3,mSubRoot4;
    // 循环遍及所有的HUB端口
    // 端口是基于1,非0建立
    for (index=1; index <= NumPorts; index++)
    {
        ULONG nBytes;
        // 分配空间为这一个端口支撑连接信息.
        // 即于现在,分派它大的充足为 30个管支撑信息.
        // 端点数是 0-15.  端点 0 号是标准不被在结构描述符中明确地列出的控制端点.  
        // 可能有一在端点1号-15的端点和外面的端点中因此可能有每装置结构30端点的最大值
        // 应该在一些点动态地或许按规定尺寸制作这.
        nBytes = sizeof(USB_NODE_CONNECTION_INFORMATION) + sizeof(USB_PIPE_INFO) * 30;
        connectionInfo = (PUSB_NODE_CONNECTION_INFORMATION)ALLOC(nBytes);
        if (connectionInfo == NULL)
        {
            OOPS();
            break;
        }
        // 现在为这一个端口为 USB_NODE_CONNECTION_INFORMATION 结构 USBHUB.如果一个装置被插上到这一个端口,
		//这将会告诉我们,在其他的事物之中.
        connectionInfo->ConnectionIndex = index;
        success = DeviceIoControl(hHubDevice,IOCTL_USB_GET_NODE_CONNECTION_INFORMATION,connectionInfo,
                                  nBytes,connectionInfo,nBytes,&nBytes,NULL);
        if (!success)
        {
            FREE(connectionInfo);
            continue;
        }
        // 更新连接的设备数
        if (connectionInfo->ConnectionStatus == DeviceConnected)
        {
            m_TotalDevicesConnected++;
        }
        if (connectionInfo->DeviceIsHub)
        {
            m_TotalHubs++;
        }
        // 如果那儿有一个设备连接,获得这设备描述符
        deviceDesc = NULL;
        if (connectionInfo->ConnectionStatus != NoDeviceConnected)
        {
            driverKeyName = GetDriverKeyName(hHubDevice, index);
            if (driverKeyName)
            {
                deviceDesc = DriverNameToDeviceDesc(driverKeyName);
                FREE(driverKeyName);
            }
        }
        // 如果那儿有一个设备连接到端口,设法取回来自设备的结构体描述符.
        if (m_bDoConfigDesc && connectionInfo->ConnectionStatus == DeviceConnected)
        {
            configDesc = GetConfigDescriptor(hHubDevice,index,0);
        }
        else
        {
            configDesc = NULL;
        }

        if (configDesc != NULL && AreThereStringDescriptors(&connectionInfo->DeviceDescriptor,(PUSB_CONFIGURATION_DESCRIPTOR)(configDesc+1)))
        {
            stringDescs = GetAllStringDescriptors(hHubDevice,index,&connectionInfo->DeviceDescriptor,(PUSB_CONFIGURATION_DESCRIPTOR)(configDesc+1));
        }
        else
        {
            stringDescs = NULL;
        }
        // 如果这设备连接到的端口是外部HUB,将获得外部HUB名并且递归的列举它
        if (connectionInfo->DeviceIsHub)
        {
            PCHAR extHubName;
            extHubName = GetExternalHubName(hHubDevice,index);
            if (extHubName != NULL)
            {
                EnumerateHub(extHubName,connectionInfo,configDesc,stringDescs,deviceDesc);
                // 在到下一个端口之上
                continue;
            }
        }
        // 为USBDEVICEINFO结构支撑HUB信息分派一些空间,hub名,与连接信息指针.GPTR 零为我们设定结构初值.
        info = (PUSBDEVICEINFO) ALLOC(sizeof(USBDEVICEINFO));
        if (info == NULL)
        {
            OOPS();
            if (configDesc != NULL)
            {
                FREE(configDesc);
            }
            FREE(connectionInfo);
            break;
        }
        info->ConnectionInfo = connectionInfo;
        info->ConfigDesc = configDesc;
        info->StringDescs = stringDescs;
        wsprintf(leafName, "[Port%d] ", index);
        strcat(leafName, ConnectionStatuses[connectionInfo->ConnectionStatus]);
        if (deviceDesc)
        {
            strcat(leafName, " :  ");
            strcat(leafName, deviceDesc);
			m_strUsbInfo.Format("%s",leafName);
			m_MyList.AddString(m_strUsbInfo);
			DisplayConnectionInfo(info->ConnectionInfo,info->StringDescs);
        }
		m_strUsbInfo.Format("%s",leafName);
		/*switch(m_iNodeValue)
		{
		case 1:
			mSubRoot1=m_MyTree.InsertItem(m_strUsbInfo,0,1,subRoot1,TVI_LAST);
			break;
		case 2:
			mSubRoot2=m_MyTree.InsertItem(m_strUsbInfo,0,1,subRoot2,TVI_LAST);
			break;
		case 3:
			mSubRoot3=m_MyTree.InsertItem(m_strUsbInfo,0,1,subRoot3,TVI_LAST);
			break;
		case 4:
			mSubRoot4=m_MyTree.InsertItem(m_strUsbInfo,0,1,subRoot4,TVI_LAST);
			break;
		}*/
        //hItem = AddLeaf(hTreeParent,(LPARAM)info,leafName);
    }
}

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

PUSB_DESCRIPTOR_REQUEST CMFC_USBViewDlg::GetConfigDescriptor(HANDLE hHubDevice, ULONG ConnectionIndex, UCHAR DescriptorIndex)
{
	BOOL    success;
    ULONG   nBytes;
    ULONG   nBytesReturned;
    UCHAR   configDescReqBuf[sizeof(USB_DESCRIPTOR_REQUEST) + sizeof(USB_CONFIGURATION_DESCRIPTOR)];
    PUSB_DESCRIPTOR_REQUEST         configDescReq;
    PUSB_CONFIGURATION_DESCRIPTOR   configDesc;
    // 请求结构描述符第一次使用我们的局部缓冲区, 哪一为外形记述件够确实大它本身.
    nBytes = sizeof(configDescReqBuf);
    configDescReq = (PUSB_DESCRIPTOR_REQUEST)configDescReqBuf;
    configDesc = (PUSB_CONFIGURATION_DESCRIPTOR)(configDescReq+1);
    // 将整个结构初始化为0
    memset(configDescReq, 0, nBytes);
    // 指出端口从哪一描述符将会被请求
    configDescReq->ConnectionIndex = ConnectionIndex;
    // SBHUB 使用 URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE 处理这 IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION 请求.
    // USBD 将会自动地设定这些领域初值:
    //     bmRequest = 0x80
    //     bRequest  = 0x06
    // 我们必须初始化这些:
    //     wValue    = 描述符类型 (高) 与描述符索引 (低字节)
    //     wIndex    = 0 (或者语言ID字符串描述符)
    //     wLength   = 描述符缓冲区的长度
    configDescReq->SetupPacket.wValue = (USB_CONFIGURATION_DESCRIPTOR_TYPE << 8) | DescriptorIndex;
    configDescReq->SetupPacket.wLength = (USHORT)(nBytes - sizeof(USB_DESCRIPTOR_REQUEST));
    // 现在发出获得描述符请求
    success = DeviceIoControl(hHubDevice,IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION,configDescReq,
                              nBytes,configDescReq,nBytes,&nBytesReturned,NULL);
    if (!success)
    {
        OOPS();
        return NULL;
    }
    if (nBytes != nBytesReturned)
    {
        OOPS();
        return NULL;
    }
    if (configDesc->wTotalLength < sizeof(USB_CONFIGURATION_DESCRIPTOR))

⌨️ 快捷键说明

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