twain2/scn_usb.cpp

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;
}