#include "stdafx.h" #include #include #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; }