crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

14 страниц V  « < 10 11 12 13 14 >  
Ответить в данную темуНачать новую тему
> QtSerialPort, Проблема сборки QtSerialPort под Windows
kuzulis
  опции профиля:
сообщение 21.10.2014, 10:23
Сообщение #111


Активный участник
***

Группа: Участник
Сообщений: 393
Регистрация: 29.6.2009
Пользователь №: 862

Спасибо сказали: 36 раз(а)




Репутация:   7  


Блин, что за ересь... Я даже не буду комментировать эту кашу в голове...
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ahalaj
  опции профиля:
сообщение 21.10.2014, 14:01
Сообщение #112


Студент
*

Группа: Участник
Сообщений: 47
Регистрация: 14.6.2014
Пользователь №: 4166

Спасибо сказали: 13 раз(а)




Репутация:   1  


Цитата(borune @ 21.10.2014, 8:31) *
Цитата(kuzulis @ 20.10.2014, 22:54) *
А, что?

QSerialPortInfo::availablePorts() возвращает вообще все устройства которые определились в системе.


Именно, определилИСЬ. А если в данный момент к виртуальному порту ничего не подключено, то его нет в диспетчере устройств, соотвественно, и в списке его тоже нет.

Знакомо. Я в своё время использовал SetupAPI чтобы найти устройства, которых нет в диспетчере устройств потому как физическое устройство не подключено, но фактически такое устройства в системе имеются потому как были однажды подключены. Конечно это далеко не Qt и далеко не переносимо, будет работать только под виндами, но работать будет. И найдёт все устройства. Копай в сторону тут и далее.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kuzulis
  опции профиля:
сообщение 21.10.2014, 18:57
Сообщение #113


Активный участник
***

Группа: Участник
Сообщений: 393
Регистрация: 29.6.2009
Пользователь №: 862

Спасибо сказали: 36 раз(а)




Репутация:   7  


Ах, если имелось ввиду найти все у-ва которые когда-либо были подключены и определены, а теперь являются "скрытыми" hidden (т.к. их например, выдернули из USB) и кстати, их можно отобразить в диспетчере устройств.

То это не проблема, достаточно удалить (закомментировать) DIGCF_PRESENT в qserialportinfo_win.cpp и пересобрать. Но это не

Цитата
"а мне нужно все вообще".


как говорит ТС. Да и непонятно зачем это вообще надо.




Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
borune
  опции профиля:
сообщение 22.10.2014, 6:09
Сообщение #114


Участник
**

Группа: Участник
Сообщений: 152
Регистрация: 1.1.2011
Пользователь №: 2314

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(kuzulis @ 21.10.2014, 19:57) *
Но это не
Цитата
"а мне нужно все вообще".
как говорит ТС.

именно то, все установленные виртуальные порты. Внимательнее читайте вопрос прежде, чем делать какие-то заключения.

Цитата(kuzulis @ 21.10.2014, 19:57) *
Да и непонятно зачем это вообще надо

Зачем нужно? Да вариантов можно придумать много, зачем это может быть нужно. Объясняю, зачем нужно именно мне. Разрабатываю программу, которая должна автоматически подхватывать устройство при его подключении. Для этого требуется постоянно опрашивать все установленные порты.

Сообщение отредактировал borune - 22.10.2014, 10:41
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kuzulis
  опции профиля:
сообщение 22.10.2014, 19:42
Сообщение #115


Активный участник
***

Группа: Участник
Сообщений: 393
Регистрация: 29.6.2009
Пользователь №: 862

Спасибо сказали: 36 раз(а)




Репутация:   7  


Изначальный вопрос был некорректен.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
borune
  опции профиля:
сообщение 22.10.2014, 20:17
Сообщение #116


Участник
**

Группа: Участник
Сообщений: 152
Регистрация: 1.1.2011
Пользователь №: 2314

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(kuzulis @ 22.10.2014, 20:42) *
Изначальный вопрос был некорректен.

не бывает некорректных вопросов, бывают неумные отвечающие, это как раз твой случай, сочувствую
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
borune
  опции профиля:
сообщение 23.10.2014, 19:37
Сообщение #117


Участник
**

Группа: Участник
Сообщений: 152
Регистрация: 1.1.2011
Пользователь №: 2314

Спасибо сказали: 0 раз(а)




Репутация:   0  


Господа, вопрос актуален, ибо тов. kuzulis мало того, что не понимает русского языка, так еще и дает неверные советы. Как получить список всех когда-либо установленных ком портов средствами QSerialPort?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ahalaj
  опции профиля:
сообщение 23.10.2014, 21:13
Сообщение #118


Студент
*

Группа: Участник
Сообщений: 47
Регистрация: 14.6.2014
Пользователь №: 4166

Спасибо сказали: 13 раз(а)




Репутация:   1  


Цитата(borune @ 23.10.2014, 20:37) *
Господа, вопрос актуален, ибо тов. kuzulis мало того, что не понимает русского языка, так еще и дает неверные советы. Как получить список всех когда-либо установленных ком портов средствами QSerialPort?

Единственное что лично я могу предложить, это мой маленький кусочек из исходника 10-тилетней давности. Но он на Delphi и естественно никаким QSerialPort там и не пахнет. Мне в то время надо было ловить подключение мобильных телефонов Nokia через интерфейс DKU-2. При каждом подключении создавался виртуальный ком-порт, при первом подключении система его у себя прописывала и запоминала, при отключении этот виртуальный ком-порт из диспетчера задач пропадал, но система созданную запись о нём не забывала и в системе он всё равно присутствовал, правда был hidden пока телефон физически не подключишь. И вот мне надо было ловить и видимые в диспетчере устройства, подключенные реально, и невидимые, но про которые система знала.

Использовался SetupApi.pas из JEDI Visual Component Library (в 2004-м году этот юнит назывался SetupApi.pas, сейчас он же называется по-моему JvSetupApi.pas, я с тех пор в эту библиотеку не лазил, как 10 лет назад сделал так и забыл, принцип программиста "работает -- не трожь!" :lol: )

Вот моя функция на Delphi, которая этот SetupApi.pas использует.

Раскрывающийся текст
unit Dku2;

interface

uses Windows;

const
   aDevGUID:array[0..3] of TGUID = (
            '{4F919104-4ADF-11D5-882D-00B0D02FE381}',
            '{4F919102-4ADF-11D5-882D-00B0D02FE381}',
            '{4F919100-4ADF-11D5-882D-00B0D02FE381}',
            '{86E0D1E0-8089-11D0-9CE4-08003E301F73}'
   );

type
  HDEVINFO = Pointer;

function GetDKU2List:string;

implementation

uses
  SetupApi, SysUtils;

function GetDKU2List:string;
var iDevClass,iDevice:integer;
     DevInfo:HDEVINFO;
     DevInfoData:TSpDevInfoData;
     DeviceInterfaceData:TSPDeviceInterfaceData;
     cbSize:DWORD;
     DevIFCDetailData:PSPDeviceInterfaceDetailData;
     InstanceID:PChar;
begin

  // начинаем просмотр всех возможных классов устройств в поисках
  // подходящего дивайса
  For iDevClass:=Low(aDevGUID) to High(aDevGUID) do begin
    DevInfo:=SetupDiGetClassDevs(@(aDevGUID[iDevClass]), nil, 0, DIGCF_PRESENT or DIGCF_DEVICEINTERFACE);
    If DevInfo=Pointer(INVALID_HANDLE_VALUE) then Exit
    else begin
      // дивайсы в этом классе есть
      DevInfoData.cbSize:=sizeof(SP_DEVINFO_DATA);
      // пробежимся по всем дивайсам данного класса начиная с нулевого,
      // пока функция SetupDiEnumDeviceInfo не вернёт FALSE
      iDevice:=0;
      While SetupDiEnumDeviceInfo(DevInfo,iDevice,DevInfoData) do begin
        // дивайс с таким номером найден
        // смотрим какие интерфейсы поддерживает данный дивайс
        DeviceInterfaceData.cbSize:=sizeof(SP_DEVICE_INTERFACE_DATA);
        If not SetupDiEnumDeviceInterfaces(DevInfo, nil, aDevGUID[iDevClass], iDevice, DeviceInterfaceData) then begin
          //*****ошибка
        end
        else begin
          SetupDiGetDeviceInterfaceDetail(DevInfo, @DeviceInterfaceData, nil, 0, cbSize, nil);
          GetLastError();
          DevIFCDetailData:=AllocMem(cbSize);
          DevIFCDetailData.cbSize:=sizeof(TSPDeviceInterfaceDetailData);

          If SetupDiGetDeviceInterfaceDetail(DevInfo, @DeviceInterfaceData, DevIFCDetailData, cbSize, cbSize, nil) then begin
            SetupDiGetDeviceInstanceId(DevInfo, @DevInfoData, nil, 0, @cbSize);
            GetLastError();
            InstanceID:=AllocMem(cbSize);
            SetupDiGetDeviceInstanceId(DevInfo, @DevInfoData, InstanceID, cbSize, nil);
            Dispose(InstanceID);

            If (iDevClass=1) or ((iDevClass=333) (*and (DevIFCDetailData.DevicePath[4]=Ord('u'))*)) then begin
              Result:=Result+';'+StrPas(DevIFCDetailData.DevicePath);
            end;
          end;
          Dispose(DevIFCDetailData);
        end;

        Inc(iDevice);
      end;
    end;
  end;
end;

end.


Расчитано именно на DKU-2 и именно для мобильных телефонов Nokia, но по аналогии думаю можно разобраться что там к чему. Больше помочь ничем не могу, извини.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ahalaj
  опции профиля:
сообщение 23.10.2014, 22:27
Сообщение #119


Студент
*

Группа: Участник
Сообщений: 47
Регистрация: 14.6.2014
Пользователь №: 4166

Спасибо сказали: 13 раз(а)




Репутация:   1  


Цитата(ahalaj @ 23.10.2014, 22:13) *
Единственное что лично я могу предложить, это мой маленький кусочек из исходника 10-тилетней давности. Но он на Delphi и естественно никаким QSerialPort там и не пахнет.

[...]

Нашёл ещё кое-что. Докопался я тогда до этого дела путём наглого и бессовестного реверсинга trial копии LogoManager For Nokia phones. В те времена это был единственный софт помимо родной для телефонов Nokia программы Nokia PC Suite который умел находить виртуальные порты DKU-2 как для подключенных, так и для неподключенных физически телефонов. Весь путь реверсинга я сохранял в C со своими коментариями по ходу чтобы после было легче понять что там к чему. Потом уже переделал на Delphi потому что в продакшн надо было на Delphi отдавать. Так что вот то, из чего после был сделан предыдущий паскальный исходник. Опять не Qt, но думаю что C всё же поближе должно быть чем Pascal. Тут и коментариев чуть больше, и SetupApi.pas не требуется, всё в обычном стандартном Microsoft Windows SDK имеется. Ищутся исключительно виртуальные порты DKU-2 для мобильных телефонов Nokia как и реально подключенные, так и hidden, которые в диспетчере устройств не показаны, но в системе тем не менее есть.

Стиль кода, определение ошибок и сами ошибки -- это всё не моё, данная функция отреверсена из LogoManager For Nokia phones практически "один в один", в оригинале не было только никаких вызовов logData(const char *format, ...), а всё остальное оттуда © 2004 год.

Раскрывающийся текст
#include <ctype.h>
#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#pragma pack(push,1)

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

#pragma pack(pop)

// тут мы будем хранить информацию о найденных устройствах
//
struct CDevice
{
    CDevice *pNext;
    bool     fNeedOpen;
    HANDLE   h;
    TCHAR    path[ANYSIZE_ARRAY];
};

// ПОРЯДОК ЭТИХ КЛАССОВ В МАССИВЕ ВАЖЕН!!!

static GUID aDevGUID[] = {
    {
        0x4D36E978,
        0xE325,
        0x11CE,
        {0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18}
    },
    {
        0x4F919104,
        0x4ADF,
        0x11D5,
        {0x88, 0x2D, 0x00, 0xB0, 0xD0, 0x2F, 0xE3, 0x81}
    },
    {
        0x4F919102,
        0x4ADF,
        0x11D5,
        {0x88, 0x2D, 0x00, 0xB0, 0xD0, 0x2F, 0xE3, 0x81}
    },
    {
        0x4F919100,
        0x4ADF,
        0x11D5,
        {0x88, 0x2D, 0x00, 0xB0, 0xD0, 0x2F, 0xE3, 0x81}
    },
    {
        0x86E0D1E0,
        0x8089,
        0x11D0,
        {0x9C, 0xE4, 0x08, 0x00, 0x3E, 0x30, 0x1F, 0x73}
    }
};

static char szLogFName[] = "dku-2.log";
static bool fNeedLog     = false;

static void logData(const char *format, ...)
{
    if (fNeedLog)
    {
        FILE *pFLog = fopen(szLogFName, "a+t");

        if (pFLog)
        {
            time_t timer = time(NULL);
            struct tm *stm = localtime(&timer);
            char *p = asctime(stm);
            p[strlen(p) - 1] = '\0';

            fprintf(pFLog, "%s: ", p);

            va_list args;
            va_start(args, format);
            vfprintf(pFLog, format, args);
            va_end(args);

            fclose(pFLog);
        }
    }
}

static void logStart()
{
    if (fNeedLog)
    {
        if (!access(szLogFName, 6))
        {
            FILE *pFLog = fopen(szLogFName, "a+t");

            if (pFLog)
            {
                fprintf(pFLog, "\n");
                fclose(pFLog);
            }
        }
    }
}

static void GUID2str(const GUID& guid, char *str)
{
    sprintf(str, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
            guid.Data1, guid.Data2, guid.Data3,
            guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
            guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
}

static void scanForDevices(CDevice **paDevices)
{
    CDevice  *aDevices = NULL;
    bool      fError = false;
    HDEVINFO  hDevInfo;
    char      szGUID[39];

    // начинаем просмотр всех возможных классов устройств в поисках
    // подходящего дивайса
    //
    for (int iDevClass = 0;
         iDevClass < sizeof(aDevGUID) / sizeof (aDevGUID[0]);
         iDevClass++)
    {
        GUID2str(aDevGUID[iDevClass], szGUID);

        hDevInfo = SetupDiGetClassDevs(&aDevGUID[iDevClass],
                                       0,
                                       0,
                                       DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);

        // попробуем посмотреть есть ли у нас какие-нибудь дивайсы
        // в этом классе
        //
        if (hDevInfo == INVALID_HANDLE_VALUE)
        {
            // нифига, литовский национальный праздник ``Обломайтис''
            // вываливаемся сразу же, все четыре класса должны быть
            //
            logData("hmm... couldn't find device class %s\n", szGUID);
            fError = true;
            break;
        }
        else
        {
            // дивайсы в этом классе есть
            //
            logData("found device class %s\n", szGUID);

            SP_DEVINFO_DATA DevInfoData;

            DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

            // пробежимся по всем дивайсам данного класса начиная с нулевого,
            // пока функция SetupDiEnumDeviceInfo не вернёт FALSE
            //
            bool fFound = false;

            for (int iDevice = 0;
                 SetupDiEnumDeviceInfo(hDevInfo, iDevice, &DevInfoData);
                 iDevice++)
            {
                fFound = true;
                // дивайс с таким номером найден
                //
                logData("  device number: #%d\n", iDevice);

                // смотрим какие интерфейсы поддерживает данный дивайс
                //
                SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;

                DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

                if (!SetupDiEnumDeviceInterfaces(hDevInfo,
                                                 NULL,
                                                 &aDevGUID[iDevClass],
                                                 iDevice,
                                                 &DeviceInterfaceData))
                {
                    // какая-то ошибка в потрохах Weendoze, такого быть
                    // не должно по хорошему
                    //
                    logData("failed to get SP_DEVICE_INTERFACE_DATA for "
                            "device #%d: %08X\n", iDevice, GetLastError());
                }
                else
                {
                    // узнаем про этот интерфейс поподробнее
                    //

                    // тут мы получим необходимый размер буфера
                    //
                    ULONG cbSize;

                    // а это сам буфер
                    //
                    PSP_DEVICE_INTERFACE_DETAIL_DATA pDevIFCDetailData = NULL;

                    // во время первого вызова SetupDiGetDeviceInterfaceDetail
                    // передаём NULL в качестве указателя на буфер,
                    // 0 в качестве размера буфера и в результате Windows
                    // должен вернуть нам требуемый размер буфера в cbSize
                    //
                    SetupDiGetDeviceInterfaceDetail(hDevInfo,
                                                    &DeviceInterfaceData,
                                                    NULL,
                                                    0,
                                                    &cbSize,
                                                    NULL);

                    // ДОЛЖНА БЫТЬ ОШИБКА ПРО МАЛЫЙ РАЗМЕР БУФЕРА !!!
                    //
                    int ec = GetLastError();

                    if (ec != ERROR_INSUFFICIENT_BUFFER)
                    {
                        // не повезло, ошибка какая-то другая, вываливаемся
                        //
                        logData("error getting interface detail: %08X, "
                                "skip going any further\n", ec);
                    }
                    else
                    {
                        // выделяем памяти ровно столько, сколько надо
                        //
                        pDevIFCDetailData =
                            (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(cbSize);

                        if (!pDevIFCDetailData)
                        {
                            logData("insufficient memory, "
                                    "skip going any further\n");
                        }
                        else
                        {
/*
* ТУТ НАЧИНАЮТСЯ ПОЛНЫЕ НЕПОНЯТКИ. НЕСМОТРЯ НА ТО, ЧТО ВСЕ ПАРАМЕТРЫ
* ТЕПЕРЬ БУДУТ УСТАНОВЛЕНЫ КОРРЕКТНО, LMMPC ОЖИДАЕТ, ЧТО ФУНКЦИЯ ВЕРНЁТ
* ОШИБКУ (SIC!). ЕСЛИ ЖЕ ФУНКЦИЯ ВЫПОЛНИЛАСЬ БЕЗ ОШИБКИ, ТО LMMPC
* ЗАЧЕМ-ТО ПОЛУЧАЕТ INSTANCE ID ДАННОГО ИНТЕРФЕЙСА (ЧТО МЫ И ДЕЛАЕМ
* НИЖЕ ПО ТЕКСТУ) И ТОЖЕ ОЖИДАЕТ, ЧТО ФУНКЦИЯ ВЕРНЁТ ОШИБКУ! СУДЯ
* ПО ТЕКСТУ LMMPC, ТАКОЕ ПОВЕДЕНИЕ ВПОЛНЕ ВОЗМОЖНО, НО НЕ ДЛЯ ВСЕХ
* КЛАССОВ УСТРОЙСТВ (ВСЕГО ТАМ ЧЕТЫРЕ ВОЗМОЖНЫХ КЛАССА).
*
* БЫТЬ МОЖЕТ ВСЯ ЭТА БАДЯГА ТУТ НАДЕЛАНА ДЛЯ ТОГО, ЧТОБЫ ИЗБЕЖАТЬ
* ПОВТОРНОГО ОТКРЫТИЯ УЖЕ ОТКРЫТОГО ДИВАЙСА, ФИГ ЗНАЕТ
*/

/*
  * BIZARRE BEGIN
  */
                            // подготавливаем структуру
                            // SP_DEVICE_INTERFACE_DETAIL_DATA
                            //
                            pDevIFCDetailData->cbSize =
                                sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

                            // и опять вызываем SetupDiGetDeviceInterfaceDetail,
                            // но уже с установленными значениями параметров
                            //
/*
* В LMMPC ДАЛЕЕ ВЫПОЛНЕНИЕ ИДЁТ НА ОТКРЫТИЕ ДИВАЙСА ЕСЛИ ЭТА ФУНКЦИЯ ВЕРНУЛА
* ОШИБКУ И КЛАСС ДИВАЙСА РАВЕН ОПРЕДЕЛЁННОМУ ЗНАЧЕНИЮ. ЖУТЬ КАКАЯ-ТО, ЯВНО
* КАКИЕ-ТО МАНЬЯКИ ТАКОЕ ПРИДУМЫВАЛИ
*/
                            if (!SetupDiGetDeviceInterfaceDetail(
                                hDevInfo,
                                &DeviceInterfaceData,
                                pDevIFCDetailData,
                                cbSize,
                                NULL,
                                NULL))
                            {
/*
* НА ВСЯКИЙ СЛУЧАЙ ЗАПИСЫВАЕМ КОД ОШИБКИ В ЖУРНАЛ, МОЖЕТ БЫТЬ
* ЧУТЬ ПОНЯТНЕЕ СТАНЕТ (ПРОВЕРИТЬ ВОТ НЕ НА ЧЕМ)
*/
                                logData("bizarre error code 0: %08X\n",
                                        GetLastError());
                            }
                            else
                            {
/*
* ОШИБКИ НЕ БЫЛО, ЗНАЧИТ СМОТРИМ НА DEVICE INSTANCE ID
*/
                                logData("    device path: %s\n",
                                        pDevIFCDetailData->DevicePath);

                                // используем такой же способ определения
                                // требуемого размера буфера, как и выше
                                // для SetupDiGetDeviceInterfaceDetail
                                //
                                SetupDiGetDeviceInstanceId(hDevInfo,
                                                           &DevInfoData,
                                                           NULL,
                                                           0,
                                                           &cbSize);

                                ec = GetLastError();

                                if (ec != ERROR_SUCCESS)
                                {
                                    if (ec != ERROR_INSUFFICIENT_BUFFER)
                                    {
/*
* И ЭТУ СТРАННУЮ ОШИБКУ ТОЖЕ ПИШЕМ В ЖУРНАЛ
*/
                                        logData("bizarre error code 1: %08X\n",
                                                GetLastError());
                                    }
                                    else
                                    {
/*
* ПОПАДАЕМ СЮДА ТОЛЬКО В ТОМ СЛУЧАЕ, ЕСЛИ БЫЛА ОШИБКА ПРО МАЛЫЙ
* РАЗМЕР БУФЕРА. В ПРОТИВНОМ СЛУЧАЕ ПРОСТО ИДЁМ НА ОТКРЫТИЕ ДИВАЙСА
*/
                                        // выделяем памяти ровно столько,
                                        //  сколько надо
                                        //
                                        char *pInstanceID =
                                            (char*)malloc(cbSize);

                                        if (pInstanceID)
                                        {
                                            if (!SetupDiGetDeviceInstanceId(
                                                hDevInfo,
                                                &DevInfoData,
                                                pInstanceID,
                                                cbSize,
                                                NULL))
                                            {
/*
* ЖУРНАЛИРУЕМ ЕЩЁ ОДНУ СТРАННУЮ ОШИБКУ
*/
                                                logData(
                                                    "bizarre error code 2: "
                                                    "%08X\n",
                                                    GetLastError());
                                            }
                                            else
                                            {
                                                // на всякий случай записываем
                                                // device instance id в лог
                                                //
                                                logData("    instance ID: %s\n",
                                                        pInstanceID);
                                            }
                                            // следим за heap
                                            //
                                            free(pInstanceID);
                                        }
                                    }
                                }
                            }
/*
  * BIZARRE END
  */
                            // смотрим к какому классу относится устройство
                            // (СМ. НАВЕРХУ ПРО ТО, ЧТО ПОРЯДОК КЛАССОВ В
                            // МАССИВЕ [i.e. ИХ НУМЕРАЦИЯ] ВАЖЕН!!!)
                            //
                            // устройства классов
                            // {4F919104-4ADF-11D5-882D-00B0D02FE381}
                            // {4F919100-4ADF-11D5-882D-00B0D02FE381},
                            // индексируемые через 0 и 2 соответственно,
                            // мы просто игнорируем (то есть мы проверяем
                            // эти классы только на присутствие, больше они
                            // нас никак не интересуют)
                            //
                            // устройство класса
                            // {4F919102-4ADF-11D5-882D-00B0D02FE381},
                            // индексируемое через 1, надлежит открыть
                            //
                            // устройство класса
                            // {86E0D1E0-8089-11D0-9CE4-08003E301F73},
                            // индексируемое через 3 и имеющее четвёртым
                            // символом пути букву `u' (USB?) тоже
                            // попадает под нашу юрисдикцию, однако
                            // открытия не требует (было открыто ранее?)
                            //
                            if ((iDevClass == 1) ||
                                    (iDevClass == 3 &&
                                    pDevIFCDetailData->DevicePath[4] == 'u'))
                            {
                                CDevice *pDevice =
                                    (CDevice*)malloc(sizeof (CDevice) +
                                    strlen(pDevIFCDetailData->DevicePath));

                                if(!pDevice)
                                {
                                    logData("insufficient memory to keep "
                                            "device info\n");
                                }
                                else
                                {
                                    fFound = true;

                                    if (aDevices)
                                        aDevices->pNext = pDevice;
                                    else
                                        aDevices = pDevice;

                                    pDevice->pNext = NULL;
                                    pDevice->fNeedOpen = (iDevClass == 1)
                                                                ? true
                                                                : false;
                                    pDevice->h = INVALID_HANDLE_VALUE;
                                    strcpy(pDevice->path,
                                        pDevIFCDetailData->DevicePath);
                                }
                            }

                            // следим за heap
                            //
                            free(pDevIFCDetailData);
                        }
                    }
                 }
             }
             if (!fFound)
             {
                 // в этом классе дивайсов нет
                 //
                 logData("  no any device(s)\n");
             }
             // больше нам этот класс не нужен
             //
             SetupDiDestroyDeviceInfoList(hDevInfo);
         }
    }

    // если выходим по ошибке, то освобождаем всю занятую память
    //
    if (fError)
    {
        for (CDevice *p = aDevices; p;)
        {
            CDevice *pTmp = p->pNext;
            free(p);
            p = pTmp;
        }
        aDevices = NULL;
    }

    *paDevices = aDevices;
}

static bool openDevice(CDevice&  device,
                       DWORD     IOCode,
                       BYTE     *pOutBuf,
                       DWORD    *cOutBytes)
{
    bool rc = false;

    logData("  about to open %s\n", device.path);

    if ((device.h = CreateFile(device.path,
                              0xC0000000,
                              0,
                              NULL,
                              OPEN_EXISTING,
                              FILE_FLAG_OVERLAPPED | FILE_ATTRIBUTE_NORMAL,
                              NULL)) == INVALID_HANDLE_VALUE)
    {
        logData("  error: %08X\n", GetLastError());
    }
    else
    {
        logData("  HANDLE: %08X\n", device.h);
        logData("  about to create event semaphore\n");

        HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

        logData("  HANDLE: %08X\n", hEvent);

        if (hEvent)
        {
            DWORD sysErr = ERROR_WAIT_NO_CHILDREN;
            OVERLAPPED ovrlpd;

            memset(&ovrlpd, 0, sizeof (OVERLAPPED));
            logData("  about to send %08X IOCTL code\n", IOCode);
            if (DeviceIoControl(device.h,
                                 IOCode,
                                 NULL,
                                 0,
                                 pOutBuf,
                                 *cOutBytes,
                                 cOutBytes,
                                 &ovrlpd));
            {
                logData("  success\n");
                sysErr = ERROR_SUCCESS;
            }
            if (sysErr)
            {
                sysErr = GetLastError();
                logData("  failed: %08X\n", sysErr);
                if (sysErr == ERROR_IO_PENDING)
                    sysErr = WaitForSingleObject(hEvent, 5000);
                    logData("  after waiting for 5000 ms: %08X\n", sysErr);
            }
            CloseHandle(hEvent);

            if (sysErr == ERROR_SUCCESS)
                rc = true;
        }
        CloseHandle(device.h);
        device.h = INVALID_HANDLE_VALUE;
    }
    return rc;
}

static void processDevice(CDevice& device)
{
    if (device.fNeedOpen)
    {
        DWORD cBytes;
        BYTE  buf[512];

        cBytes = sizeof(buf);
        memset(buf, 0, sizeof(buf));

        openDevice(device, 0x22203C, buf, &cBytes);
        openDevice(device, 0x222034, buf, &cBytes);
    }
}

static void dumpData(const char *buf, size_t len)
{
    char *dst = (char*)malloc(80);

    if (dst)
    {
        for (size_t i = 0; i < len;)
        {
            sprintf(dst, "%04X  ", i);

            size_t j;
            char   tmp[9];

            for (j = 0; j < 16; j++)
            {
                if ((i + j) == len)
                {
                    break;
                }
                sprintf(tmp, "%02X ", (unsigned char)buf[i + j]);
                strcat(dst, tmp);
            }

            for (; j < 16; j++)
                strcat(dst, "   ");

            strcat(dst, " ");

            for (j = 0; j < 16; j++)
            {
                if ((i + j) == len)
                {
                    break;
                }
                sprintf(tmp, "%c", isascii(buf[i + j]) ? buf[i + j] : '.');
                strcat(dst, tmp);
            }
            i += 16;

            logData("%s\n", dst);
        }
        free(dst);
    }
}

static void sendstuff(CDevice& device)
{
    DWORD  rc;
    HANDLE hDev;

    logData("  about to send some bytes\n");

    if ((hDev = CreateFile(device.path,
                           0xC0000000,
                           0,
                           NULL,
                           OPEN_EXISTING,
                           FILE_FLAG_OVERLAPPED | FILE_ATTRIBUTE_NORMAL,
                           NULL)) == INVALID_HANDLE_VALUE)
    {
        logData("  error opening: %08X\n", GetLastError());
    }
    else
    {
        HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

        if (hEvent)
        {
            OVERLAPPED ovrlpd;
            DWORD      nBytes;
            char       buf[512];

            memset(&ovrlpd, 0, sizeof (OVERLAPPED));
            ovrlpd.hEvent = hEvent;

            buf[0] = 0x1B;
            buf[1] = 0x00;
            buf[2] = 0x0C;
            buf[3] = 0xD0;
            buf[4] = 0x00;
            buf[5] = 0x01;
            buf[6] = 0x04;

            logData("  about to send data:\n");
            dumpData(buf, 7);

            rc = WriteFile(hDev,
                           buf,
                           7,
                           &nBytes,
                           &ovrlpd);

            if (rc)
            {
                if (GetLastError() == ERROR_IO_PENDING)
                {
                    printf ("waiting for 5 seconds to complete (write)\n");
                    logData("  waiting for 5 seconds to complete (write)\n");

                    rc = WaitForSingleObject(hEvent, 5000);
                }
            }
            if (rc)
            {
                logData("  error sending data: %08X\n", GetLastError());
            }
            else
            {
                logData("  about to read response:\n");
                SetEvent(hEvent);

                rc = ReadFile(hDev,
                              buf,
                              sizeof(buf),
                              &nBytes,
                              &ovrlpd);
                if (rc)
                {
                    if (GetLastError() == ERROR_IO_PENDING)
                    {
                        printf ("waiting for 5 seconds to complete (read)\n");
                        logData("  waiting for 5 seconds to complete (read)\n");

                        rc = WaitForSingleObject(hEvent, 5000);
                    }
                }
                if (rc)
                {
                    logData("  error getting response: %08X\n", GetLastError());
                }
                else
                {
                    dumpData(buf, nBytes);
                }
            }
            CloseHandle(hEvent);
        }
        CloseHandle(hDev);
    }
}

int main()
{
    CDevice *aDevices;

    char *pch = getenv("LOG_DKU-2");
    if (pch && stricmp(pch, "yes"))
        fNeedLog = true;

    logStart();
    logData("Start logging\n");

    scanForDevices(&aDevices);

    if (aDevices)
    {
        for (CDevice *p = aDevices; p; p = p->pNext)
        {
            logData("  BEFORE DeviceIoControl\n");
            sendstuff(*p);

            processDevice(*p);

            logData("  AFTER DeviceIoControl\n");
            sendstuff(*p);
        }

        for (CDevice *p = aDevices; p;)
        {
            if (p->h != INVALID_HANDLE_VALUE)
                CloseHandle(p->h);

            CDevice *pTmp = p->pNext;
            free(p);
            p = pTmp;
        }
    }

    logData("End logging\n");

    return 0;
}


Сообщение отредактировал ahalaj - 23.10.2014, 23:19
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
borune
  опции профиля:
сообщение 24.10.2014, 7:28
Сообщение #120


Участник
**

Группа: Участник
Сообщений: 152
Регистрация: 1.1.2011
Пользователь №: 2314

Спасибо сказали: 0 раз(а)




Репутация:   0  


ahalaj, спасибо большое, но мне хотелось бы все же через QSerialPort сделать. В такие дебри лезть неохота, если честно, но за помощь спасибо тебе.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

14 страниц V  « < 10 11 12 13 14 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 25.11.2024, 13:14