TL866/TL866_Updater/usb_win.cpp
2014-03-16 18:27:47 +02:00

130 lines
3.8 KiB
C++

/* Class USB, windows version
*
* This file is part of the TL866 updater project.
*
* Copyright (C) radioman 2013
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*/
#include "usb_win.h"
#include "tl866_global.h"
#include <QDebug>
#include <Windows.h>
#include <SetupAPI.h>
#define TL866_IOCTL_READ 0x222004
#define TL866_IOCTL_WRITE 0x222000
USB::USB()
{
hDriver=INVALID_HANDLE_VALUE;
}
USB::~USB()
{
if(hDriver !=INVALID_HANDLE_VALUE)
close_device();
}
const GUID MINIPRO_GUID={0x85980D83,0x32B9,0x4BA1,{0x8F,0xDF,0x12,0xA7,0x11,0xB9,0x9C,0xA2}};
int USB::get_devices_count()
{
DWORD idx = 0;
devices.clear();
HDEVINFO handle = SetupDiGetClassDevs(&MINIPRO_GUID, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (INVALID_HANDLE_VALUE == handle)
{
qDebug() << "SetupDi failed";
return 0;
}
while (1)
{
SP_DEVINFO_DATA deviceinfodata;
deviceinfodata.cbSize = sizeof(SP_DEVINFO_DATA);
if (SetupDiEnumDeviceInfo(handle, idx, &deviceinfodata))
{
SP_DEVICE_INTERFACE_DATA deviceinterfacedata;
deviceinterfacedata.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
if (SetupDiEnumDeviceInterfaces(handle, 0, &MINIPRO_GUID, idx, &deviceinterfacedata))
{
idx++;
DWORD size = 0;
SetupDiGetDeviceInterfaceDetail(handle, &deviceinterfacedata, NULL, 0, &size, NULL);
PSP_DEVICE_INTERFACE_DETAIL_DATA deviceinterfacedetaildata = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(size * sizeof(TCHAR));
deviceinterfacedetaildata->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
DWORD datasize = size;
if (SetupDiGetDeviceInterfaceDetail(handle, &deviceinterfacedata, deviceinterfacedetaildata, datasize , &size, NULL))
#ifdef UNICODE
devices.append(QString::fromWCharArray(deviceinterfacedetaildata->DevicePath));
#else
devices.append(deviceinterfacedetaildata->DevicePath);
#endif free(deviceinterfacedetaildata);
}
}
else
{
break;
}
}
return devices.count();
}
bool USB::open_device(int index)
{
hDriver = CreateFileA(devices.at(index).toAscii().data(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
return (hDriver != INVALID_HANDLE_VALUE);
}
void USB::close_device()
{
CloseHandle(hDriver);
hDriver=NULL;
}
bool USB::isOpen()
{
return (hDriver != INVALID_HANDLE_VALUE);
}
size_t USB::usb_read(unsigned char *data, size_t size)
{
DWORD bytes_read;
uchar buffer[4];
if (hDriver == INVALID_HANDLE_VALUE)
return 0;
bool ret = DeviceIoControl(hDriver, TL866_IOCTL_READ, buffer, sizeof(buffer), data, size, &bytes_read, NULL);
return (ret ? bytes_read : 0);
}
size_t USB::usb_write(unsigned char *data, size_t size)
{
DWORD bytes_written;
uchar buffer[4096];
if (hDriver == INVALID_HANDLE_VALUE)
return 0;
bool ret = DeviceIoControl(hDriver, TL866_IOCTL_WRITE, data, size, buffer, sizeof(buffer), &bytes_written, NULL);
return (ret ? bytes_written : 0);
}