Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Получение статуса порта USB


Автор: ZIFIR 5.11.2012, 00:21
Получаю имя хост-контроллера, имя корневого хаба, количество портов.
Дальше пытаюсь получить статус порта

Код

for (int iPort = 0; iPort < m_usbDeviceInfo.GetCountPortHub(hRoot); iPort++)
            {
                

                NodeConnInfo.ConnectionIndex = iPort+1; 
                                                       
                DWORD BytesReturned;
                                                        // IOCTL_USB_GET_NODE_CONNECTION_INFORMATION
                               bool Success = DeviceIoControl(hRoot, 0x220448,
                                                  &NodeConnInfo, sizeof(NodeConnInfo),
                                                  &NodeConnInfo, sizeof(NodeConnInfo),
                                                  &BytesReturned, NULL
                                                   );

                if (NodeConnInfo.ConnectionStatus[1] != DeviceConnected)
                {
                    if (NodeConnInfo.ConnectionStatus[1] == NoDeviceConnected)
                    {
                        // Нет подключенных устройств.",iPort);
                    }
                    else
                    {
                        // выводим статус
                    }
                }
                else
                {
                    if (!NodeConnInfo.DeviceIsHub)
                    {
                        //подключено устройство
                    }
                    else
                    {
                        //к порту подключен хаб
                    }
                }

ConnectionStatus в структуре NodeConnInfo опред. так: BYTE ConnectionStatus[4];
DeviceConnected, NoDeviceConnected ... из перечисления (от 0 до 10)
NodeConnInfo.ConnectionStatus[1] всегда равно 12, поэтому вышеуказанные условия проходят мимо.


Автор: Dem_max 5.11.2012, 05:24
Держи весь код 100% рабочий, не пугайся что он большой, для корректной работы такой и нужен.

Код

extern "C" {
    #include "hidsdi.h"    // note: part of Windows DDK
    #include "hidpi.h"    // note: also part of Windows DDK
}

#include "usbiodef.h"
#include "usbioctl.h"


#pragma pack (push, 1)
typedef struct _tDESCRIPTOR_REQUEST
{
     ULONG ConnectionIndex;
     struct {
                UCHAR bmRequest;
                UCHAR bRequest;
                UCHAR wValue[2];
                UCHAR wIndex[2];
                UCHAR wLength[2];
          } SetupPacket;
     UCHAR Data[2048];
} DESCRIPTOR_REQUEST;

typedef struct _tHUB_DESCRIPTOR
{
     UCHAR bDescriptorLength;
     UCHAR bDescriptorType;
     UCHAR bNumberOfPorts;
     UCHAR wHubCharacteristics[2];
     UCHAR bPowerOnToPowerGood;
     UCHAR bHubControlCurrent;
     UCHAR bRemoveAndPowerMask[64];
} HUB_DESCRIPTOR;

typedef struct _tNODE_INFORMATION
{
     USB_HUB_NODE NodeType;
     HUB_DESCRIPTOR HubDescriptor;
     BOOLEAN HubIsBusPowered;
} NODE_INFORMATION;

typedef struct _tNODE_CONNECTION_INFORMATION
{
     ULONG ConnectionIndex;
     USB_DEVICE_DESCRIPTOR DeviceDescriptor;
     UCHAR CurrentConfigurationValue;
     BOOLEAN LowSpeed;
     BOOLEAN DeviceIsHub;
     UCHAR DeviceAddress[2];
     UCHAR NumberOfOpenPipes[4];
     UCHAR ConnectionStatus[4];
     USB_PIPE_INFO PipeList[32];
} NODE_CONNECTION_INFORMATION;
#pragma pack (pop)


int m_iDevicesConnected;


BOOL IsDeviceConnected(USHORT VID, USHORT PID)
{
    HANDLE hHostController;
    HANDLE hRootHub;
    DWORD BytesReturned;
    USB_NODE_INFORMATION NodeInformation;

   __try
    {
        m_iDevicesConnected = 0;

        for(int iHost = 0; iHost < 10; iHost++)
        {
            hHostController = EnumerateHostController(iHost);

            if(hHostController != INVALID_HANDLE_VALUE)
            {
                hRootHub = EnumerateHub(hHostController);
                if(hRootHub)
                {
                    DeviceIoControl(hRootHub,
                                            IOCTL_USB_GET_NODE_INFORMATION,
                                            &NodeInformation, sizeof(NodeInformation),
                                            &NodeInformation, sizeof(NodeInformation),
                                            &BytesReturned, NULL);

                    EnumerateHubPorts(hRootHub, NodeInformation.u.HubInformation.HubDescriptor.bNumberOfPorts, VID, PID);
                    CloseHandle(hRootHub);
                }
            }

            CloseHandle(hHostController);
        }

        if(m_iDevicesConnected > 0) return TRUE;
    }
    __finally
    {
        CloseHandle(hRootHub);
        CloseHandle(hHostController);
    }

    return FALSE;
}
//------------------------------------------------------------------------------
void EnumerateHubPorts(HANDLE hRootHub, int PortCount, USHORT VID, USHORT PID)
{
    typedef struct _NODE_CONNECTION_INFORMATION
    {
        ULONG ConnectionIndex;
        USB_DEVICE_DESCRIPTOR DeviceDescriptor;
        UCHAR CurrentConfigurationValue;
        BOOLEAN LowSpeed;
        BOOLEAN DeviceIsHub;
        UCHAR DeviceAddress[2];
        UCHAR NumberOfOpenPipes[4];
        UCHAR ConnectionStatus[4];
        USB_PIPE_INFO PipeList[32];
    } NODE_CONNECTION_INFORMATION;

    DWORD BytesReturned;
    UCHAR PortStatus;
    HANDLE hExternalHub;
    NODE_CONNECTION_INFORMATION ConnectionInformation;

    for(ULONG PortIndex = 1; PortIndex < (ULONG)PortCount + 1; PortIndex++)
    {
        ConnectionInformation.ConnectionIndex = PortIndex;

        DeviceIoControl(hRootHub, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION,
                                &ConnectionInformation, sizeof(ConnectionInformation),
                                &ConnectionInformation, sizeof(ConnectionInformation),
                                &BytesReturned, NULL);

        PortStatus = ConnectionInformation.ConnectionStatus[0];

        if(PortStatus == DeviceConnected)
        {
            if(!ConnectionInformation.DeviceIsHub)
            {
                if(ConnectionInformation.DeviceDescriptor.idVendor == VID
                    && ConnectionInformation.DeviceDescriptor.idProduct == PID)
                    {
                        m_iDevicesConnected++;
                    }
            }
            else
            {
                USB_NODE_INFORMATION NodeInformation;

                hExternalHub = EnumerateExternalHub(hRootHub, PortIndex);

                DeviceIoControl(hExternalHub, IOCTL_USB_GET_NODE_INFORMATION,
                                        &NodeInformation, sizeof(NodeInformation),
                                        &NodeInformation, sizeof(NodeInformation),
                                        &BytesReturned, NULL);


                EnumerateHubPorts(hExternalHub, NodeInformation.u.HubInformation.HubDescriptor.bNumberOfPorts, VID, PID);
                CloseHandle(hExternalHub);
            }
        }
    }
}

//------------------------------------------------------------------------------
HANDLE EnumerateHostController(int Index)
{
    TCHAR HostControllerName[200];
    wsprintf(HostControllerName, _T("\\\\.\\HCD%d"), Index);
    return CreateFile(HostControllerName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
}
//------------------------------------------------------------------------------
HANDLE EnumerateExternalHub(HANDLE hRootHub, int PortIndex)
{
    typedef struct _NODE_CONNECTION_NAME
    {
        ULONG ConnectionIndex;  /* INPUT */
        ULONG ActualLength;     /* OUTPUT */
        /* unicode symbolic name for this node if it is a hub or parent driver
         null if this node is a device. */
        WCHAR NodeName[256];      /* OUTPUT */
    } NODE_CONNECTION_NAME, *P_NODE_CONNECTION_NAME;

    DWORD BytesReturned;
    TCHAR ExternalHubName[256] = _T("\\\\.\\");

    NODE_CONNECTION_NAME    HubName;
    HubName.ConnectionIndex = PortIndex;

    DeviceIoControl(hRootHub, IOCTL_USB_GET_NODE_CONNECTION_NAME,
                            &HubName,
                            sizeof(HubName),
                            &HubName,
                            sizeof(HubName),
                            &BytesReturned,
                            NULL);

    lstrcat(ExternalHubName, HubName.NodeName);

    return CreateFile(ExternalHubName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
}
//------------------------------------------------------------------------------
HANDLE EnumerateHub(HANDLE hHostController)
{
    HANDLE hRootHub;
    DWORD BytesReturned;
    bool Success;


    typedef struct _USB_DRIVERKEY_NAME
    {
        ULONG  ActualLength;
        WCHAR  DriverKeyName[256];
    } USB_DRIVERKEY_NAME;

    USB_DRIVERKEY_NAME DriverName;

    wchar_t RootHubName[256] = L"\\\\.\\";

    Success = DeviceIoControl(hHostController, IOCTL_GET_HCD_DRIVERKEY_NAME, &DriverName, sizeof(DriverName), &DriverName, sizeof(DriverName), &BytesReturned, NULL);
    if(!Success) return NULL;

    DeviceIoControl(hHostController, IOCTL_USB_GET_ROOT_HUB_NAME, &DriverName, sizeof(DriverName), &DriverName, sizeof(DriverName), &BytesReturned, NULL);

    lstrcat(RootHubName, DriverName.DriverKeyName);

    hRootHub = CreateFile(RootHubName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);

    if(hRootHub == INVALID_HANDLE_VALUE) return NULL;
    return hRootHub;
}

Автор: NurMKM 28.2.2013, 20:02
Цитата(Dem_max @ 5.11.2012,  05:24)
Держи весь код 100% рабочий, не пугайся что он большой, для корректной работы такой и нужен.

Добрый день.

прошу сильно не пинать.  при запуске вашего кода выходить сообщение  fatal error C1083: Не удается открыть файл включение: hidsdi.h: No such file or directory

Может я проект не правильно создаю, или же надо где то подключить библиотеку.
Проект создавал: Создать-> Visual C++ -> Win32 -> Проект Win32. Внутри создавал файл с расширением срр. 


В папке C:\Program Files\Microsoft Visual Studio 10.0\VC\include
    #include "hidsdi.h"   
    #include "hidpi.h" 
#include "usbiodef.h"
#include "usbioctl.h"
 не одно из них.

Автор: Dem_max 1.3.2013, 06:13
Эти все файлы находятся в Windows Driver Development Kit (DDK) 

Или вот держи подкрепляю.

Автор: NurMKM 1.3.2013, 07:46
Цитата(Dem_max @ 1.3.2013,  06:13)
Эти все файлы находятся в Windows Driver Development Kit (DDK) 

Или вот держи подкрепляю.

Добрый день, Dem_max.
Я до этого системными программированием не занимался. Но пришло время заниматься. И мне сказали наши безопасники  что при вставке флешки на компьютер, записывался типа как лог. Там должный быть   VID PID и.т.д.

Как выше написал создал проект создавал  Visual C++ -> Win32 Console Application 
Application type: Console application(может тут надо выбрать DLL)

Далее создаю внутри отдельно файл usb.cpp  и вставляю ваш код и запускаю.

Думаю мне не хватает библиотеки. 

1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\hidsdi.h(32): error C2146: syntax error : missing ';' before identifier 'NTSTATUS'
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\hidsdi.h(32): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\hidsdi.h(32): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\hidusage.h(26): error C2146: syntax error : missing ';' before identifier 'USAGE'
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\hidusage.h(26): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

Заранее спасибо. 

Автор: NurMKM 1.3.2013, 08:44
Цитата(NurMKM @ 1.3.2013,  07:46)
Цитата(Dem_max @ 1.3.2013,  06:13)
Эти все файлы находятся в Windows Driver Development Kit (DDK) 

Или вот держи подкрепляю.

Добрый день, Dem_max.
Я до этого системными программированием не занимался. Но пришло время заниматься. И мне сказали наши безопасники  что при вставке флешки на компьютер, записывался типа как лог. Там должный быть   VID PID и.т.д.

Как выше написал создал проект создавал  Visual C++ -> Win32 Console Application 
Application type: Console application(может тут надо выбрать DLL)

Далее создаю внутри отдельно файл usb.cpp  и вставляю ваш код и запускаю.

Думаю мне не хватает библиотеки. 

1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\hidsdi.h(32): error C2146: syntax error : missing ';' before identifier 'NTSTATUS'
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\hidsdi.h(32): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\hidsdi.h(32): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\hidusage.h(26): error C2146: syntax error : missing ';' before identifier 'USAGE'
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\hidusage.h(26): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

Заранее спасибо.

Добавил еще библиотеки :

#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <setupapi.h>

Вообще надо эти библиотеки(иметься виду все)?

Теперь другие ошибки вышли:

Код

>CL : warning : using obsolete header file usbioctl.h
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\usbioctl.h(449): warning C4200: nonstandard extension used : zero-sized array in struct/union
1>          Cannot generate copy-ctor or copy-assignment operator when UDT contains a zero-sized array
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\usbioctl.h(472): warning C4200: nonstandard extension used : zero-sized array in struct/union
1>          Cannot generate copy-ctor or copy-assignment operator when UDT contains a zero-sized array
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\usbioctl.h(528): warning C4200: nonstandard extension used : zero-sized array in struct/union
1>          Cannot generate copy-ctor or copy-assignment operator when UDT contains a zero-sized array
1>c:\users\user\documents\visual studio 2010\projects\zzz\zzz\usb.cpp(68): error C3861: 'EnumerateHostController': identifier not found
1>c:\users\user\documents\visual studio 2010\projects\zzz\zzz\usb.cpp(71): error C3861: 'EnumerateHub': identifier not found
1>c:\users\user\documents\visual studio 2010\projects\zzz\zzz\usb.cpp(79): error C3861: 'EnumerateHubPorts': identifier not found
1>c:\users\user\documents\visual studio 2010\projects\zzz\zzz\usb.cpp(134): error C3861: 'EnumerateExternalHub': identifier not found
1>c:\users\user\documents\visual studio 2010\projects\zzz\zzz\usb.cpp(190): warning C4800: 'BOOL' : forcing value to bool 'true' or 'false' (performance warning)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========


Для каждого версии Microsoft Visual C++, своя должно быть  библиотека или же подойдут из старых версий так как в начале пишет что я пользуюсь устаревшим библиотекой.

У меня на работе устаовлено Microsoft Visual C++ 2010 Express, a дома - ultimate.  Библиотеки ваши. 

Заранее спасибо.

Автор: Dem_max 1.3.2013, 08:52
Если нужно чтобы программа висела фоном, то нужно создавать Win console application, дальше в нем создавать цикл сообщений и принимать сообщение WM_DEVICECHANGE 

Ссылка
http://forum.sources.ru/index.php?showtopic=351895
http://forum.sources.ru/index.php?showtopic=351430

вот еще примеры

Автор: Dem_max 1.3.2013, 08:53
Цитата

Библиотеки ваши. 

Я библиотеки не давал, так как они у меня в формате COFF, а тебе нужны в OMF

Автор: NurMKM 1.3.2013, 09:00
Цитата(Dem_max @ 1.3.2013,  08:53)
Цитата

Библиотеки ваши. 

Я библиотеки не давал, так как они у меня в формате COFF, а тебе нужны в OMF

Спасибо за помощь.

Но чем отличие и как можно преобразовать от COFF в OMF? Или же где можно найти эти библиотеки?

Заранее спасибо.

Автор: Dem_max 1.3.2013, 09:12
Лучше скачать 
Windows Driver Development Kit (DDK) 
и там взять

Автор: NurMKM 1.3.2013, 09:13
Цитата(Dem_max @ 1.3.2013,  09:12)
Лучше скачать 
Windows Driver Development Kit (DDK) 
и там взять

Уже качаю. Только WDK  весит 1 гб.

Спасибо.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)