455 lines
10 KiB
C++
455 lines
10 KiB
C++
#include "stdafx.h"
|
|
#include <stdio.h>
|
|
#include <tchar.h>
|
|
#include "scn_usb.h"
|
|
#include "winioctl.h"
|
|
#include "PublicFunc.h"
|
|
#include "filetools.h"
|
|
|
|
//CUSBHotPlugged usb;
|
|
cscn_usb::cscn_usb(void)
|
|
{
|
|
m_h_dev = INVALID_HANDLE_VALUE;
|
|
m_usbscan_config = { 0 };
|
|
m_w_serial_no = 0;
|
|
}
|
|
|
|
cscn_usb::~cscn_usb(void)
|
|
{
|
|
close();
|
|
//FileTools::write_log("1.txt", "~cscn_usb");
|
|
}
|
|
|
|
void cscn_usb::init(WORD w_vid, WORD w_pid)
|
|
{
|
|
m_h_dev = INVALID_HANDLE_VALUE;
|
|
w_vid = w_vid;
|
|
w_pid = w_pid;
|
|
m_w_serial_no = 0;
|
|
}
|
|
|
|
HANDLE cscn_usb::open(WORD index)
|
|
{
|
|
BOOL b_ret = FALSE;
|
|
TCHAR szDevPath[MAX_PATH] = { 0 };
|
|
INT i = 0, j = 0;
|
|
DEVICE_DESCRIPTOR dev_desc;
|
|
DWORD cbRet = 0;
|
|
|
|
|
|
_stprintf(szDevPath, TEXT("\\\\.\\Usbscan%d"), index);
|
|
m_h_dev = CreateFile(szDevPath,
|
|
GENERIC_READ | GENERIC_WRITE,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
FILE_FLAG_OVERLAPPED,
|
|
NULL);
|
|
if (m_h_dev != INVALID_HANDLE_VALUE)
|
|
{
|
|
m_b_is_connected = TRUE;
|
|
b_ret = DeviceIoControl(m_h_dev, (DWORD)IOCTL_GET_DEVICE_DESCRIPTOR,
|
|
&dev_desc, sizeof(dev_desc), &dev_desc, sizeof(dev_desc),
|
|
&cbRet, NULL);
|
|
|
|
if (b_ret)
|
|
{
|
|
m_w_vid = dev_desc.usVendorId;
|
|
m_w_pid = dev_desc.usProductId;
|
|
m_w_serial_no = index;
|
|
b_ret = DeviceIoControl(m_h_dev, (DWORD)IOCTL_GET_PIPE_CONFIGURATION,
|
|
NULL, 0, &m_usbscan_config, sizeof(USBSCAN_PIPE_CONFIGURATION),
|
|
&cbRet, NULL);
|
|
if (b_ret && m_usbscan_config.NumberOfPipes > 0)
|
|
{
|
|
for (int by_i = 0x00; by_i < m_usbscan_config.NumberOfPipes; by_i++)
|
|
{
|
|
TCHAR szPipePath[MAX_PATH] = { 0 };
|
|
_stprintf(szPipePath, TEXT("\\\\.\\Usbscan%d\\%d"), index, by_i);
|
|
m_usb_pipes[by_i].pipe_info = m_usbscan_config.PipeInfo[by_i];
|
|
m_usb_pipes[by_i].h_pipe = CreateFile(szPipePath,
|
|
GENERIC_READ | GENERIC_WRITE,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
FILE_FLAG_OVERLAPPED,
|
|
NULL);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CloseHandle(m_h_dev);
|
|
m_h_dev = INVALID_HANDLE_VALUE;
|
|
}
|
|
}
|
|
|
|
return m_h_dev;
|
|
}
|
|
|
|
BOOL cscn_usb::close(void)
|
|
{
|
|
BOOL b_ret = FALSE;
|
|
BYTE by_i = 0x00;
|
|
|
|
if (m_h_dev != INVALID_HANDLE_VALUE)
|
|
{
|
|
|
|
BOOL bState = FALSE;
|
|
DWORD cbRet = 0;
|
|
OVERLAPPED overlapped;
|
|
PIPE_TYPE pipeType = ALL_PIPE;
|
|
|
|
memset(&overlapped, 0, sizeof(OVERLAPPED));
|
|
overlapped.hEvent =
|
|
CreateEvent(NULL, // pointer to security attributes
|
|
FALSE, // automatic reset
|
|
FALSE, // initialize to nosignaled
|
|
NULL); // pointer to the event-object name
|
|
bState =
|
|
DeviceIoControl(m_h_dev,
|
|
(DWORD)IOCTL_CANCEL_IO,
|
|
(LPVOID)&pipeType,
|
|
sizeof(PIPE_TYPE),
|
|
NULL,
|
|
0,
|
|
&cbRet,
|
|
&overlapped);
|
|
WaitForSingleObject(overlapped.hEvent, 1000);
|
|
CloseHandle(overlapped.hEvent);
|
|
|
|
for (by_i = 0x00; by_i < m_usbscan_config.NumberOfPipes; by_i++)
|
|
{
|
|
CancelIo(m_usb_pipes[by_i].h_pipe); //++@2012-06-08
|
|
CloseHandle(m_usb_pipes[by_i].h_pipe);
|
|
m_usb_pipes[by_i].h_pipe = INVALID_HANDLE_VALUE;
|
|
}
|
|
|
|
CancelIo(m_h_dev); //++@2012-06-08
|
|
b_ret = CloseHandle(m_h_dev);
|
|
if (b_ret)
|
|
{
|
|
m_h_dev = INVALID_HANDLE_VALUE;
|
|
b_ret = TRUE;
|
|
}
|
|
}
|
|
m_b_is_connected = FALSE;
|
|
return b_ret;
|
|
}
|
|
|
|
BOOL cscn_usb::control_in(BYTE by_pipe_addr, WORD w_value, WORD w_index, PVOID p_data, DWORD dw_size, PDWORD pdw_read, LPOVERLAPPED lp_overlap)
|
|
{
|
|
IO_BLOCK irp;
|
|
DWORD dw_ret;
|
|
HANDLE h_pipe = INVALID_HANDLE_VALUE;
|
|
|
|
if (m_h_dev == INVALID_HANDLE_VALUE)
|
|
return TRUE;
|
|
irp.uOffset = w_value;
|
|
irp.uLength = dw_size;
|
|
irp.uIndex = w_index;
|
|
irp.pbyData = (LPBYTE)p_data;
|
|
|
|
if (by_pipe_addr == 0x00)
|
|
h_pipe = m_h_dev;
|
|
else
|
|
{
|
|
BYTE by_i = 0x00;
|
|
for (by_i = 0x00; by_i < m_usbscan_config.NumberOfPipes; by_i++)
|
|
{
|
|
if (m_usb_pipes[by_i].pipe_info.EndpointAddress == by_pipe_addr)
|
|
h_pipe = m_usb_pipes[by_i].h_pipe;
|
|
}
|
|
}
|
|
return DeviceIoControl(h_pipe, IOCTL_READ_REGISTERS, &irp, sizeof(IO_BLOCK), p_data, 64, &dw_ret, lp_overlap);
|
|
}
|
|
|
|
BOOL cscn_usb::control_out(BYTE by_pipe_addr, WORD w_value, WORD w_index, PVOID p_data, DWORD dw_size, PDWORD pdw_write, LPOVERLAPPED lp_overlap)
|
|
{
|
|
BOOL b_ret = FALSE;
|
|
IO_BLOCK irp;
|
|
DWORD dw_ret;
|
|
HANDLE h_pipe = INVALID_HANDLE_VALUE;
|
|
|
|
if (m_h_dev == INVALID_HANDLE_VALUE)
|
|
return TRUE;
|
|
irp.uOffset = w_value;
|
|
irp.uLength = dw_size;
|
|
irp.uIndex = w_index;
|
|
irp.pbyData = (LPBYTE)p_data;
|
|
if (by_pipe_addr == 0x00)
|
|
h_pipe = m_h_dev;
|
|
else
|
|
{
|
|
BYTE by_i = 0x00;
|
|
for (by_i = 0x00; by_i < m_usbscan_config.NumberOfPipes; by_i++)
|
|
{
|
|
if (m_usb_pipes[by_i].pipe_info.EndpointAddress == by_pipe_addr)
|
|
h_pipe = m_usb_pipes[by_i].h_pipe;
|
|
}
|
|
}
|
|
b_ret = DeviceIoControl(h_pipe, IOCTL_WRITE_REGISTERS, &irp, sizeof(IO_BLOCK), NULL, 0L, &dw_ret, lp_overlap);
|
|
if (!b_ret)
|
|
{
|
|
if (ERROR_FILE_NOT_FOUND == GetLastError())
|
|
m_b_is_connected = FALSE;
|
|
}
|
|
return b_ret;
|
|
}
|
|
|
|
BOOL cscn_usb::interrupt_in(BYTE by_pipe_addr, PBYTE pby_data, BYTE by_len, PBYTE pby_read, LPOVERLAPPED lp_overlap)
|
|
{
|
|
BOOL b_ret = FALSE;
|
|
IO_BLOCK irp = { 0 };
|
|
DWORD dw_ret = 0L;
|
|
HANDLE h_pipe = INVALID_HANDLE_VALUE;
|
|
BYTE by_i = 0x00;
|
|
|
|
if (m_h_dev == INVALID_HANDLE_VALUE)
|
|
return FALSE;
|
|
|
|
for (by_i = 0x00; by_i < m_usbscan_config.NumberOfPipes; by_i++)
|
|
{
|
|
if (m_usb_pipes[by_i].pipe_info.EndpointAddress == by_pipe_addr)
|
|
h_pipe = m_usb_pipes[by_i].h_pipe;
|
|
}
|
|
b_ret = DeviceIoControl(h_pipe, (DWORD)IOCTL_WAIT_ON_DEVICE_EVENT,
|
|
NULL, 0, pby_data, by_len, &dw_ret, lp_overlap);
|
|
if (!b_ret)
|
|
{
|
|
if (ERROR_FILE_NOT_FOUND == GetLastError())
|
|
m_b_is_connected = FALSE;
|
|
}
|
|
if (lp_overlap != NULL)
|
|
{
|
|
DWORD dw_trans = 0x0L;
|
|
b_ret = WaitForSingleObject(lp_overlap->hEvent, 50) == WAIT_OBJECT_0;
|
|
if (b_ret)
|
|
{
|
|
b_ret = GetOverlappedResult(h_pipe, lp_overlap, &dw_trans, FALSE);
|
|
if (b_ret)
|
|
{
|
|
if (pby_read != NULL)
|
|
*pby_read = dw_trans & 0xff;
|
|
}
|
|
else
|
|
{
|
|
if (ERROR_FILE_NOT_FOUND == GetLastError())
|
|
m_b_is_connected = FALSE;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (pby_read != NULL)
|
|
*pby_read = dw_ret & 0xff;
|
|
}
|
|
|
|
return b_ret;
|
|
}
|
|
|
|
BOOL cscn_usb::bulk_in(BYTE by_pipe_addr, PVOID p_data, DWORD dw_size,DWORD timeout, PDWORD pdw_ret)
|
|
{
|
|
HANDLE h_pipe = INVALID_HANDLE_VALUE;
|
|
BOOL b_ret = FALSE;
|
|
|
|
OVERLAPPED oa;
|
|
memset(&oa, 0, sizeof(oa));
|
|
oa.hEvent = CreateEvent(0, TRUE, FALSE, NULL);
|
|
LPOVERLAPPED lp_overlap = &oa;
|
|
|
|
if (m_h_dev == INVALID_HANDLE_VALUE)
|
|
return TRUE;
|
|
if (by_pipe_addr == 0x00)
|
|
h_pipe = m_h_dev;
|
|
else
|
|
{
|
|
BYTE by_i = 0x00;
|
|
for (by_i = 0x00; by_i < m_usbscan_config.NumberOfPipes; by_i++)
|
|
{
|
|
if (m_usb_pipes[by_i].pipe_info.EndpointAddress == by_pipe_addr)
|
|
h_pipe = m_usb_pipes[by_i].h_pipe;
|
|
}
|
|
}
|
|
b_ret = ReadFile(h_pipe, p_data, dw_size, pdw_ret, lp_overlap);
|
|
if (lp_overlap != NULL)
|
|
{
|
|
DWORD dw_trans = 0x0L;;
|
|
b_ret = WaitForSingleObject(lp_overlap->hEvent, timeout) == WAIT_OBJECT_0;
|
|
if (b_ret)
|
|
{
|
|
b_ret = GetOverlappedResult(h_pipe, lp_overlap, &dw_trans, FALSE);
|
|
if (b_ret)
|
|
{
|
|
if (pdw_ret != NULL)
|
|
*pdw_ret = dw_trans;
|
|
}
|
|
else
|
|
{
|
|
if (ERROR_FILE_NOT_FOUND == GetLastError())
|
|
m_b_is_connected = FALSE;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
return b_ret;
|
|
CloseHandle(lp_overlap->hEvent);
|
|
return b_ret;
|
|
}
|
|
//overlap do not use current
|
|
BOOL cscn_usb::bulk_out(BYTE by_pipe_addr, PVOID p_data, DWORD dw_size, PDWORD pdw_ret)
|
|
{
|
|
BOOL b_ret = FALSE;
|
|
HANDLE h_pipe = INVALID_HANDLE_VALUE;
|
|
|
|
OVERLAPPED oa;
|
|
memset(&oa, 0, sizeof(oa));
|
|
oa.hEvent = CreateEvent(0, TRUE, FALSE, NULL);
|
|
LPOVERLAPPED lp_overlap = &oa;
|
|
|
|
if (m_h_dev == INVALID_HANDLE_VALUE)
|
|
return TRUE;
|
|
if (by_pipe_addr == 0x00)
|
|
h_pipe = m_h_dev;
|
|
else
|
|
{
|
|
BYTE by_i = 0x00;
|
|
for (by_i = 0x00; by_i < m_usbscan_config.NumberOfPipes; by_i++)
|
|
{
|
|
if (m_usb_pipes[by_i].pipe_info.EndpointAddress == by_pipe_addr)
|
|
h_pipe = m_usb_pipes[by_i].h_pipe;
|
|
}
|
|
}
|
|
|
|
b_ret = WriteFile(h_pipe, p_data, dw_size, pdw_ret, lp_overlap);
|
|
if (!b_ret)
|
|
{
|
|
DWORD dw_trans = 0x0L;
|
|
b_ret = WaitForSingleObject(lp_overlap->hEvent, 1000) == WAIT_OBJECT_0;
|
|
if (b_ret)
|
|
{
|
|
b_ret = GetOverlappedResult(h_pipe, lp_overlap, &dw_trans, FALSE);
|
|
if (b_ret)
|
|
{
|
|
if (pdw_ret != NULL)
|
|
*pdw_ret = dw_trans;
|
|
}
|
|
else
|
|
{
|
|
if (ERROR_FILE_NOT_FOUND == GetLastError())
|
|
m_b_is_connected = FALSE;
|
|
}
|
|
}
|
|
}
|
|
CloseHandle(lp_overlap->hEvent);
|
|
return b_ret;
|
|
|
|
}
|
|
|
|
BOOL cscn_usb::Read_Data(PVOID p_data, DWORD length, DWORD timeout, PDWORD pdw_ret)
|
|
{
|
|
//HANDLE h_pipe = INVALID_HANDLE_VALUE;
|
|
BOOL b_ret = FALSE;
|
|
OVERLAPPED oa;
|
|
memset(&oa, 0, sizeof(oa));
|
|
oa.hEvent = CreateEvent(0, TRUE, FALSE, NULL);
|
|
|
|
LPOVERLAPPED lp_overlap = &oa;
|
|
|
|
if (m_h_dev != NULL)
|
|
{
|
|
b_ret = ReadFile(m_h_dev, p_data, length, pdw_ret, lp_overlap);
|
|
DWORD dw_trans = 0x0L;
|
|
b_ret = WaitForSingleObject(lp_overlap->hEvent, timeout) == WAIT_OBJECT_0;
|
|
if (b_ret)
|
|
{
|
|
b_ret = GetOverlappedResult(m_h_dev, lp_overlap, &dw_trans, FALSE);
|
|
if (b_ret)
|
|
{
|
|
if (pdw_ret != NULL)
|
|
{
|
|
*pdw_ret = dw_trans;
|
|
}
|
|
CloseHandle(lp_overlap->hEvent);
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
CloseHandle(lp_overlap->hEvent);
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL cscn_usb::is_connected(void)
|
|
{
|
|
return m_b_is_connected;
|
|
}
|
|
|
|
usb_scan_dev Devices()
|
|
{
|
|
usb_scan_dev devs;
|
|
memset(&devs, 0, sizeof(devs));
|
|
BOOL b_ret = FALSE;
|
|
TCHAR szDevPath[MAX_PATH] = { 0 };
|
|
DEVICE_DESCRIPTOR dev_desc;
|
|
DWORD cbRet = 0;
|
|
HANDLE h_dev;
|
|
for (int i = 0; i < 1024; i++)
|
|
{
|
|
_stprintf(szDevPath, TEXT("\\\\.\\Usbscan%d"), i);
|
|
h_dev = CreateFile(szDevPath,
|
|
GENERIC_READ | GENERIC_WRITE,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
FILE_FLAG_OVERLAPPED,
|
|
NULL);
|
|
|
|
if (h_dev != INVALID_HANDLE_VALUE)
|
|
{
|
|
b_ret = DeviceIoControl(h_dev, (DWORD)IOCTL_GET_DEVICE_DESCRIPTOR,
|
|
&dev_desc, sizeof(dev_desc), &dev_desc, sizeof(dev_desc),
|
|
&cbRet, NULL);
|
|
if (b_ret)
|
|
{
|
|
devs.dev_infos[devs._NumberOfDevs].index = i;
|
|
devs.dev_infos[devs._NumberOfDevs].vid = dev_desc.usVendorId;
|
|
devs.dev_infos[devs._NumberOfDevs].pid = dev_desc.usProductId;
|
|
devs._NumberOfDevs++;
|
|
}
|
|
CloseHandle(h_dev);
|
|
h_dev = INVALID_HANDLE_VALUE;
|
|
}
|
|
}
|
|
|
|
return devs;
|
|
}
|
|
usb_scan_dev Devices(WORD w_vid)
|
|
{
|
|
usb_scan_dev all_dev = Devices();
|
|
usb_scan_dev devs;
|
|
memset(&devs, 0, sizeof(devs));
|
|
for (int i = 0; i < all_dev._NumberOfDevs; i++)
|
|
{
|
|
if (all_dev.dev_infos[i].vid == w_vid)
|
|
{
|
|
devs.dev_infos[devs._NumberOfDevs] = all_dev.dev_infos[i];
|
|
devs._NumberOfDevs++;
|
|
}
|
|
}
|
|
return devs;
|
|
}
|
|
usb_scan_dev Devices(WORD w_vid, WORD w_pid)
|
|
{
|
|
usb_scan_dev all_dev = Devices();
|
|
usb_scan_dev devs;
|
|
memset(&devs, 0, sizeof(devs));
|
|
for (int i = 0; i < all_dev._NumberOfDevs; i++)
|
|
{
|
|
if (all_dev.dev_infos[i].vid == w_vid && all_dev.dev_infos[i].pid == w_pid)
|
|
{
|
|
devs.dev_infos[devs._NumberOfDevs] = all_dev.dev_infos[i];
|
|
devs._NumberOfDevs++;
|
|
}
|
|
}
|
|
return devs;
|
|
} |