📄 usbiopipe.cpp
字号:
/************************************************************************
*
* Module: UsbIoPipe.cpp
* Long name: CUsbIoPipe class
* Description: USB In/Out Pipe class implementation
*
* Runtime Env.: Win32, Part of UsbioLib
* Author(s): Guenter Hildebrandt, Udo Eberhardt
* Company: Thesycon GmbH, Ilmenau
************************************************************************/
// for shorter and faster windows.h
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif
// unicode is not supported by USBIOLIB
#ifdef UNICODE
#undef UNICODE
#endif
#include <windows.h>
#include "usbiopipe.h"
// standard constructor
CUsbIoPipe::CUsbIoPipe()
{
// empty
}
// destructor
CUsbIoPipe::~CUsbIoPipe()
{
// empty
}
DWORD CUsbIoPipe::Bind(
int DeviceNumber,
UCHAR EndpointAddress,
HDEVINFO DeviceList /*=NULL*/,
const GUID *InterfaceGuid /*=NULL*/
)
{
DWORD Status;
USBIO_BIND_PIPE BindPipe;
if ( !IsOpen() ) {
// open the device
Status = Open(DeviceNumber, DeviceList, InterfaceGuid);
if (Status != USBIO_ERR_SUCCESS) {
return Status;
}
}
// bind to an endpoint
// zero the struct if any fields are added...
ZeroMemory(&BindPipe,sizeof(USBIO_BIND_PIPE));
BindPipe.EndpointAddress = EndpointAddress;
Status = IoctlSync(
IOCTL_USBIO_BIND_PIPE,
&BindPipe,
sizeof(USBIO_BIND_PIPE),
NULL,
0,
NULL
);
return Status;
}
DWORD CUsbIoPipe::Unbind()
{
return IoctlSync(
IOCTL_USBIO_UNBIND_PIPE,
NULL,
0,
NULL,
0,
NULL
);
}
DWORD CUsbIoPipe::ResetPipe()
{
return IoctlSync(
IOCTL_USBIO_RESET_PIPE,
NULL,
0,
NULL,
0,
NULL
);
}
DWORD CUsbIoPipe::AbortPipe()
{
return IoctlSync(
IOCTL_USBIO_ABORT_PIPE,
NULL,
0,
NULL,
0,
NULL
);
}
DWORD CUsbIoPipe::GetPipeParameters(USBIO_PIPE_PARAMETERS* PipeParameters)
{
DWORD Status;
// zero the struct if any fields are added...
ZeroMemory(PipeParameters,sizeof(USBIO_PIPE_PARAMETERS));
Status = IoctlSync(
IOCTL_USBIO_GET_PIPE_PARAMETERS,
NULL,
0,
PipeParameters,
sizeof(USBIO_PIPE_PARAMETERS),
NULL
);
return Status;
}
DWORD CUsbIoPipe::SetPipeParameters(const USBIO_PIPE_PARAMETERS* PipeParameters)
{
DWORD Status;
Status = IoctlSync(
IOCTL_USBIO_SET_PIPE_PARAMETERS,
PipeParameters,
sizeof(USBIO_PIPE_PARAMETERS),
NULL,
0,
NULL
);
return Status;
}
DWORD CUsbIoPipe::PipeControlTransferIn(
void* Buffer,
DWORD& ByteCount,
const USBIO_PIPE_CONTROL_TRANSFER* ControlTransfer
)
{
DWORD Status;
Status = IoctlSync(
IOCTL_USBIO_PIPE_CONTROL_TRANSFER_IN,
ControlTransfer,
sizeof(USBIO_PIPE_CONTROL_TRANSFER),
Buffer,
ByteCount,
&ByteCount
);
return Status;
}
DWORD CUsbIoPipe::PipeControlTransferOut(
const void* Buffer,
DWORD& ByteCount,
const USBIO_PIPE_CONTROL_TRANSFER* ControlTransfer
)
{
DWORD Status;
Status = IoctlSync(
IOCTL_USBIO_PIPE_CONTROL_TRANSFER_OUT,
ControlTransfer,
sizeof(USBIO_PIPE_CONTROL_TRANSFER),
(void*)Buffer,
ByteCount,
&ByteCount
);
return Status;
}
DWORD CUsbIoPipe::SetupPipeStatistics(ULONG AveragingInterval)
{
USBIO_SETUP_PIPE_STATISTICS setup;
ZeroMemory(&setup,sizeof(setup));
setup.AveragingInterval = AveragingInterval;
return IoctlSync(
IOCTL_USBIO_SETUP_PIPE_STATISTICS,
&setup,
sizeof(setup),
NULL,
0,
NULL
);
}
DWORD CUsbIoPipe::QueryPipeStatistics(
USBIO_PIPE_STATISTICS* PipeStatistics,
ULONG Flags /*=0*/
)
{
USBIO_QUERY_PIPE_STATISTICS query;
ZeroMemory(&query,sizeof(query));
query.Flags = Flags;
return IoctlSync(
IOCTL_USBIO_QUERY_PIPE_STATISTICS,
&query,
sizeof(query),
PipeStatistics,
sizeof(USBIO_PIPE_STATISTICS),
NULL
);
}
DWORD CUsbIoPipe::ResetPipeStatistics()
{
USBIO_PIPE_STATISTICS stats;
return QueryPipeStatistics(
&stats,
USBIO_QPS_FLAG_RESET_ALL_COUNTERS
);
}
BOOL CUsbIoPipe::Read(CUsbIoBuf* Buf)
{
BOOL succ;
succ = ReadFile(
FileHandle, // handle of file to read
Buf->Buffer(), // pointer to buffer that receives data
Buf->NumberOfBytesToTransfer, // number of bytes to read
&Buf->BytesTransferred, // pointer to number of bytes read
&Buf->Overlapped // pointer to overlapped structure
);
if ( succ ) {
Buf->Status = USBIO_ERR_SUCCESS;
} else {
Buf->Status = GetLastError();
if ( Buf->Status == ERROR_IO_PENDING ) {
succ = TRUE;
}
}
return succ;
}
BOOL CUsbIoPipe::Write(CUsbIoBuf* Buf)
{
BOOL succ;
succ = WriteFile(
FileHandle, // handle of file to write
Buf->Buffer(), // pointer to buffer to send data
Buf->NumberOfBytesToTransfer, // number of bytes to write
&Buf->BytesTransferred, // pointer to number of bytes written
&Buf->Overlapped // pointer to overlapped structure
);
if ( succ ) {
// the operation was completed with success
Buf->Status = USBIO_ERR_SUCCESS;
} else {
Buf->Status = GetLastError();
if ( Buf->Status == ERROR_IO_PENDING ) {
// the operation is pending
succ = TRUE;
}
}
return succ;
}
DWORD CUsbIoPipe::WaitForCompletion(CUsbIoBuf* Buf, DWORD Timeout/*=INFINITE*/)
{
DWORD Status;
DWORD err;
BOOL succ;
if ( Buf->Status == USBIO_ERR_SUCCESS ) {
// the operation was already completed with success
Status = USBIO_ERR_SUCCESS;
} else {
if ( Buf->Status == ERROR_IO_PENDING ) {
// the operation is pending, wait for completion
err = WaitForSingleObject(Buf->Overlapped.hEvent,Timeout);
if ( err == WAIT_TIMEOUT ) {
// timeout on wait
Status = USBIO_ERR_TIMEOUT;
} else {
// operation was completed, get final status
succ = GetOverlappedResult(
FileHandle,
&Buf->Overlapped,
&Buf->BytesTransferred, // byte count
FALSE // wait flag
);
if ( succ ) {
// success
Buf->Status = USBIO_ERR_SUCCESS;
} else {
// error
Buf->Status = GetLastError();
}
Status = Buf->Status;
}
} else {
// the operation was already completed with an error
Status = Buf->Status;
}
}
return Status;
}
DWORD CUsbIoPipe::ReadSync(
void *Buffer,
DWORD &ByteCount,
DWORD Timeout /*=INFINITE*/
)
{
DWORD status;
// init buffer descriptor
CUsbIoBuf Buf(Buffer,ByteCount);
Buf.NumberOfBytesToTransfer = ByteCount;
// submit the buffer
Read(&Buf);
// wait for the transfer to complete
status = WaitForCompletion(&Buf,Timeout);
if ( status == USBIO_ERR_TIMEOUT ) {
// a timeout is occurred
// we must cancel the request because the
// Buf.OVERLAPPED struct is valid only in this function
CancelIo();
// now wait for the buffer to complete (infinite)
//status = WaitForCompletion(&Buf,INFINITE);
// in case of timeout the return status should be USBIO_ERR_TIMEOUT !
WaitForCompletion(&Buf,INFINITE);
}
// return the number of bytes transferred
ByteCount = Buf.BytesTransferred;
return status;
}
DWORD CUsbIoPipe::WriteSync(
void *Buffer,
DWORD &ByteCount,
DWORD Timeout /*=INFINITE*/
)
{
DWORD status;
// init buffer descriptor
CUsbIoBuf Buf(Buffer,ByteCount);
Buf.NumberOfBytesToTransfer = ByteCount;
// submit the buffer
Write(&Buf);
// wait for the transfer to complete
status = WaitForCompletion(&Buf,Timeout);
if ( status == USBIO_ERR_TIMEOUT ) {
// a timeout is occurred
// we must cancel the request because the
// Buf.OVERLAPPED struct is valid only in this function
CancelIo();
// now wait for the buffer to complete (infinite)
//status = WaitForCompletion(&Buf,INFINITE);
// in case of timeout the return status should be USBIO_ERR_TIMEOUT
WaitForCompletion(&Buf,INFINITE);
}
// return the number of bytes transferred
ByteCount = Buf.BytesTransferred;
return status;
}
/*************************** EOF **************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -