169 lines
4.2 KiB
C++
169 lines
4.2 KiB
C++
|
|
#include "DRI/Dri_Consumer.h"
|
|||
|
|
|
|||
|
|
namespace
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
bool Dri_Consumer_Func_BeginRead(Dri_Consumer_Struct_Port* p_Port, QString* p_TextStatus)
|
|||
|
|
{
|
|||
|
|
if (!p_Port->IsOpened || (p_Port->InputLength == 0))
|
|||
|
|
{
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (p_Port->IsReadPending)
|
|||
|
|
{
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ResetEvent(p_Port->HandleEvent);
|
|||
|
|
p_Port->ReadBuffer.fill(0, p_Port->InputLength);
|
|||
|
|
p_Port->OverlappedRead = {};
|
|||
|
|
p_Port->OverlappedRead.hEvent = p_Port->HandleEvent;
|
|||
|
|
|
|||
|
|
DWORD BytesRead = 0;
|
|||
|
|
if (ReadFile(
|
|||
|
|
p_Port->HandleRead,
|
|||
|
|
p_Port->ReadBuffer.data(),
|
|||
|
|
p_Port->InputLength,
|
|||
|
|
&BytesRead,
|
|||
|
|
&p_Port->OverlappedRead) ||
|
|||
|
|
(GetLastError() == ERROR_IO_PENDING))
|
|||
|
|
{
|
|||
|
|
p_Port->IsReadPending = true;
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (p_TextStatus != nullptr)
|
|||
|
|
{
|
|||
|
|
*p_TextStatus = QStringLiteral("Consumer 接口启动异步读取失败:%1").arg(GetLastError());
|
|||
|
|
}
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
} // namespace
|
|||
|
|
|
|||
|
|
void Dri_Consumer_Func_Close(Dri_Consumer_Struct_Port* p_Port)
|
|||
|
|
{
|
|||
|
|
if ((p_Port->HandleRead != INVALID_HANDLE_VALUE) && p_Port->IsReadPending)
|
|||
|
|
{
|
|||
|
|
CancelIoEx(p_Port->HandleRead, &p_Port->OverlappedRead);
|
|||
|
|
}
|
|||
|
|
if (p_Port->HandleRead != INVALID_HANDLE_VALUE)
|
|||
|
|
{
|
|||
|
|
CloseHandle(p_Port->HandleRead);
|
|||
|
|
}
|
|||
|
|
if (p_Port->HandleEvent != nullptr)
|
|||
|
|
{
|
|||
|
|
CloseHandle(p_Port->HandleEvent);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
*p_Port = Dri_Consumer_Struct_Port();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool Dri_Consumer_Func_Open(
|
|||
|
|
Dri_Consumer_Struct_Port* p_Port,
|
|||
|
|
const Mid_Struct_DeviceConfig& DeviceConfig,
|
|||
|
|
QString* p_TextStatus)
|
|||
|
|
{
|
|||
|
|
Dri_Consumer_Func_Close(p_Port);
|
|||
|
|
|
|||
|
|
QString DevicePath;
|
|||
|
|
quint16 InputLength = 0;
|
|||
|
|
if (!Mid_Func_FindHidInterface(
|
|||
|
|
Mid_Func_GetConsumerMatch(DeviceConfig),
|
|||
|
|
&DevicePath,
|
|||
|
|
&InputLength,
|
|||
|
|
nullptr))
|
|||
|
|
{
|
|||
|
|
if (p_TextStatus != nullptr)
|
|||
|
|
{
|
|||
|
|
*p_TextStatus = QStringLiteral("未找到 Consumer 接口:000C / 0001。");
|
|||
|
|
}
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
p_Port->HandleRead = CreateFileW(
|
|||
|
|
reinterpret_cast<LPCWSTR>(DevicePath.utf16()),
|
|||
|
|
GENERIC_READ,
|
|||
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|||
|
|
nullptr,
|
|||
|
|
OPEN_EXISTING,
|
|||
|
|
FILE_FLAG_OVERLAPPED,
|
|||
|
|
nullptr);
|
|||
|
|
if (p_Port->HandleRead == INVALID_HANDLE_VALUE)
|
|||
|
|
{
|
|||
|
|
if (p_TextStatus != nullptr)
|
|||
|
|
{
|
|||
|
|
*p_TextStatus = QStringLiteral("Consumer 接口打开失败:%1").arg(GetLastError());
|
|||
|
|
}
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
p_Port->HandleEvent = CreateEventW(nullptr, TRUE, FALSE, nullptr);
|
|||
|
|
if (p_Port->HandleEvent == nullptr)
|
|||
|
|
{
|
|||
|
|
if (p_TextStatus != nullptr)
|
|||
|
|
{
|
|||
|
|
*p_TextStatus = QStringLiteral("Consumer 接口创建事件失败:%1").arg(GetLastError());
|
|||
|
|
}
|
|||
|
|
Dri_Consumer_Func_Close(p_Port);
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
p_Port->InputLength = InputLength;
|
|||
|
|
p_Port->ReadBuffer = QByteArray(InputLength, 0);
|
|||
|
|
p_Port->OverlappedRead.hEvent = p_Port->HandleEvent;
|
|||
|
|
p_Port->IsOpened = true;
|
|||
|
|
|
|||
|
|
Dri_Consumer_Func_BeginRead(p_Port, p_TextStatus);
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool Dri_Consumer_Func_Read(
|
|||
|
|
Dri_Consumer_Struct_Port* p_Port,
|
|||
|
|
Mid_Struct_RawPacket* p_Packet,
|
|||
|
|
QString* p_TextStatus)
|
|||
|
|
{
|
|||
|
|
p_Packet->IsValid = false;
|
|||
|
|
p_Packet->ByteArray.clear();
|
|||
|
|
p_Packet->PortName = QStringLiteral("Consumer");
|
|||
|
|
|
|||
|
|
if (!p_Port->IsOpened)
|
|||
|
|
{
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!p_Port->IsReadPending)
|
|||
|
|
{
|
|||
|
|
Dri_Consumer_Func_BeginRead(p_Port, p_TextStatus);
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
DWORD BytesRead = 0;
|
|||
|
|
if (!GetOverlappedResult(p_Port->HandleRead, &p_Port->OverlappedRead, &BytesRead, FALSE))
|
|||
|
|
{
|
|||
|
|
const DWORD ErrorCode = GetLastError();
|
|||
|
|
if (ErrorCode == ERROR_IO_INCOMPLETE)
|
|||
|
|
{
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (p_TextStatus != nullptr)
|
|||
|
|
{
|
|||
|
|
*p_TextStatus = QStringLiteral("Consumer 接口读包失败:%1").arg(ErrorCode);
|
|||
|
|
}
|
|||
|
|
Dri_Consumer_Func_Close(p_Port);
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
p_Port->IsReadPending = false;
|
|||
|
|
if (BytesRead > 0)
|
|||
|
|
{
|
|||
|
|
p_Packet->IsValid = true;
|
|||
|
|
p_Packet->ByteArray = p_Port->ReadBuffer.left(static_cast<int>(BytesRead));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Dri_Consumer_Func_BeginRead(p_Port, p_TextStatus);
|
|||
|
|
return p_Packet->IsValid;
|
|||
|
|
}
|