Platform: Windows: Avoid windows.h
This way Windows.h doesn't pollute everything with random definesv0.3.0-dev
parent
caf5cca42f
commit
453d3366af
|
|
@ -1,19 +1,7 @@
|
||||||
#ifndef __DYNAMICLIB_WINDOWS_H_
|
#ifndef __DYNAMICLIB_WINDOWS_H_
|
||||||
#define __DYNAMICLIB_WINDOWS_H_
|
#define __DYNAMICLIB_WINDOWS_H_
|
||||||
|
|
||||||
#define NOMINMAX
|
#include "icsneo/platform/windows/windows.h"
|
||||||
#ifndef WIN32_LEAN_AND_MEAN
|
|
||||||
#define LAM_DEFINED
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
|
||||||
#endif
|
|
||||||
#include <Windows.h>
|
|
||||||
#ifdef LAM_DEFINED
|
|
||||||
#undef LAM_DEFINED
|
|
||||||
#undef WIN32_LEAN_AND_MEAN
|
|
||||||
#endif
|
|
||||||
#undef NOMINMAX
|
|
||||||
#undef near
|
|
||||||
#undef far
|
|
||||||
|
|
||||||
#ifdef ICSNEOC_MAKEDLL
|
#ifdef ICSNEOC_MAKEDLL
|
||||||
#define DLLExport __declspec(dllexport)
|
#define DLLExport __declspec(dllexport)
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,7 @@
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
#include <Windows.h>
|
#include "icsneo/platform/windows/windows.h"
|
||||||
#include <winsock2.h>
|
|
||||||
#include <pcap.h>
|
#include <pcap.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
#include <Windows.h>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
@ -20,17 +19,6 @@ public:
|
||||||
// Get DWORD value
|
// Get DWORD value
|
||||||
static bool Get(std::wstring path, std::wstring key, uint32_t& value);
|
static bool Get(std::wstring path, std::wstring key, uint32_t& value);
|
||||||
static bool Get(std::string path, std::string key, uint32_t& value);
|
static bool Get(std::string path, std::string key, uint32_t& value);
|
||||||
|
|
||||||
private:
|
|
||||||
class Key {
|
|
||||||
public:
|
|
||||||
Key(std::wstring path, bool readwrite = false);
|
|
||||||
~Key();
|
|
||||||
HKEY GetKey() { return key; }
|
|
||||||
bool IsOpen() { return key != nullptr; }
|
|
||||||
private:
|
|
||||||
HKEY key;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <Windows.h>
|
|
||||||
#include "icsneo/device/neodevice.h"
|
#include "icsneo/device/neodevice.h"
|
||||||
#include "icsneo/communication/driver.h"
|
#include "icsneo/communication/driver.h"
|
||||||
#include "icsneo/api/eventmanager.h"
|
#include "icsneo/api/eventmanager.h"
|
||||||
|
|
@ -22,25 +21,21 @@ public:
|
||||||
static bool IsHandleValid(neodevice_handle_t handle);
|
static bool IsHandleValid(neodevice_handle_t handle);
|
||||||
typedef void(*fn_boolCallback)(bool success);
|
typedef void(*fn_boolCallback)(bool success);
|
||||||
|
|
||||||
VCP(const device_eventhandler_t& err, neodevice_t& forDevice) : Driver(err), device(forDevice) {
|
VCP(const device_eventhandler_t& err, neodevice_t& forDevice);
|
||||||
overlappedRead.hEvent = INVALID_HANDLE_VALUE;
|
|
||||||
overlappedWrite.hEvent = INVALID_HANDLE_VALUE;
|
|
||||||
overlappedWait.hEvent = INVALID_HANDLE_VALUE;
|
|
||||||
}
|
|
||||||
~VCP() { close(); }
|
~VCP() { close(); }
|
||||||
bool open() { return open(false); }
|
bool open() { return open(false); }
|
||||||
void openAsync(fn_boolCallback callback);
|
void openAsync(fn_boolCallback callback);
|
||||||
bool close();
|
bool close();
|
||||||
bool isOpen() { return handle != INVALID_HANDLE_VALUE; }
|
bool isOpen();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool open(bool fromAsync);
|
bool open(bool fromAsync);
|
||||||
bool opening = false;
|
bool opening = false;
|
||||||
neodevice_t& device;
|
neodevice_t& device;
|
||||||
HANDLE handle = INVALID_HANDLE_VALUE;
|
|
||||||
OVERLAPPED overlappedRead = {};
|
struct Detail;
|
||||||
OVERLAPPED overlappedWrite = {};
|
std::shared_ptr<Detail> detail;
|
||||||
OVERLAPPED overlappedWait = {};
|
|
||||||
std::vector<std::shared_ptr<std::thread>> threads;
|
std::vector<std::shared_ptr<std::thread>> threads;
|
||||||
void readTask();
|
void readTask();
|
||||||
void writeTask();
|
void writeTask();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
// Include Windows.h with as few annoying defines as possible
|
||||||
|
|
||||||
|
#define NOMINMAX
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define LAM_DEFINED
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <Windows.h>
|
||||||
|
#ifdef LAM_DEFINED
|
||||||
|
#undef LAM_DEFINED
|
||||||
|
#undef WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#undef NOMINMAX
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
#include <windows.h>
|
||||||
|
#include <winsock2.h>
|
||||||
|
|
||||||
#include "icsneo/platform/windows/pcap.h"
|
#include "icsneo/platform/windows/pcap.h"
|
||||||
#include "icsneo/communication/network.h"
|
#include "icsneo/communication/network.h"
|
||||||
#include "icsneo/communication/communication.h"
|
#include "icsneo/communication/communication.h"
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#include "icsneo/platform/windows/registry.h"
|
#include "icsneo/platform/windows/registry.h"
|
||||||
|
#include "icsneo/platform/windows/windows.h"
|
||||||
#include <codecvt>
|
#include <codecvt>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <locale>
|
#include <locale>
|
||||||
|
|
@ -7,7 +8,17 @@ using namespace icsneo;
|
||||||
|
|
||||||
static std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
|
static std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
|
||||||
|
|
||||||
Registry::Key::Key(std::wstring path, bool readwrite) {
|
class Key {
|
||||||
|
public:
|
||||||
|
Key(std::wstring path, bool readwrite = false);
|
||||||
|
~Key();
|
||||||
|
HKEY GetKey() { return key; }
|
||||||
|
bool IsOpen() { return key != nullptr; }
|
||||||
|
private:
|
||||||
|
HKEY key;
|
||||||
|
};
|
||||||
|
|
||||||
|
Key::Key(std::wstring path, bool readwrite) {
|
||||||
DWORD dwDisposition;
|
DWORD dwDisposition;
|
||||||
if(readwrite)
|
if(readwrite)
|
||||||
RegCreateKeyExW(HKEY_LOCAL_MACHINE, path.c_str(), 0, nullptr, 0, KEY_QUERY_VALUE | KEY_WRITE, nullptr, &key, &dwDisposition);
|
RegCreateKeyExW(HKEY_LOCAL_MACHINE, path.c_str(), 0, nullptr, 0, KEY_QUERY_VALUE | KEY_WRITE, nullptr, &key, &dwDisposition);
|
||||||
|
|
@ -15,7 +26,7 @@ Registry::Key::Key(std::wstring path, bool readwrite) {
|
||||||
RegOpenKeyExW(HKEY_LOCAL_MACHINE, path.c_str(), 0, KEY_READ, &key);
|
RegOpenKeyExW(HKEY_LOCAL_MACHINE, path.c_str(), 0, KEY_READ, &key);
|
||||||
}
|
}
|
||||||
|
|
||||||
Registry::Key::~Key() {
|
Key::~Key() {
|
||||||
if(IsOpen())
|
if(IsOpen())
|
||||||
RegCloseKey(key);
|
RegCloseKey(key);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include "icsneo/platform/windows/ftdi.h"
|
#include "icsneo/platform/windows/ftdi.h"
|
||||||
#include "icsneo/platform/ftdi.h"
|
#include "icsneo/platform/ftdi.h"
|
||||||
#include "icsneo/platform/registry.h"
|
#include "icsneo/platform/registry.h"
|
||||||
|
#include <windows.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
@ -18,6 +19,19 @@ static const std::wstring ALL_ENUM_REG_KEY = L"SYSTEM\\CurrentControlSet\\Enum\\
|
||||||
static constexpr unsigned int RETRY_TIMES = 5;
|
static constexpr unsigned int RETRY_TIMES = 5;
|
||||||
static constexpr unsigned int RETRY_DELAY = 50;
|
static constexpr unsigned int RETRY_DELAY = 50;
|
||||||
|
|
||||||
|
struct VCP::Detail
|
||||||
|
{
|
||||||
|
Detail() {
|
||||||
|
overlappedRead.hEvent = INVALID_HANDLE_VALUE;
|
||||||
|
overlappedWrite.hEvent = INVALID_HANDLE_VALUE;
|
||||||
|
overlappedWait.hEvent = INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
HANDLE handle = INVALID_HANDLE_VALUE;
|
||||||
|
OVERLAPPED overlappedRead = {};
|
||||||
|
OVERLAPPED overlappedWrite = {};
|
||||||
|
OVERLAPPED overlappedWait = {};
|
||||||
|
};
|
||||||
|
|
||||||
std::vector<neodevice_t> VCP::FindByProduct(int product, std::vector<std::wstring> driverNames) {
|
std::vector<neodevice_t> VCP::FindByProduct(int product, std::vector<std::wstring> driverNames) {
|
||||||
std::vector<neodevice_t> found;
|
std::vector<neodevice_t> found;
|
||||||
|
|
||||||
|
|
@ -172,6 +186,10 @@ std::vector<neodevice_t> VCP::FindByProduct(int product, std::vector<std::wstrin
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VCP::VCP(const device_eventhandler_t& err, neodevice_t& forDevice) : Driver(err), device(forDevice) {
|
||||||
|
detail = std::make_shared<Detail>();
|
||||||
|
}
|
||||||
|
|
||||||
bool VCP::IsHandleValid(neodevice_handle_t handle) {
|
bool VCP::IsHandleValid(neodevice_handle_t handle) {
|
||||||
if(handle < 1)
|
if(handle < 1)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -200,7 +218,8 @@ bool VCP::open(bool fromAsync) {
|
||||||
|
|
||||||
// We're going to attempt to open 5 (RETRY_TIMES) times in a row
|
// We're going to attempt to open 5 (RETRY_TIMES) times in a row
|
||||||
for(int i = 0; !isOpen() && i < RETRY_TIMES; i++) {
|
for(int i = 0; !isOpen() && i < RETRY_TIMES; i++) {
|
||||||
handle = CreateFileW(comss.str().c_str(), GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, nullptr);
|
detail->handle = CreateFileW(comss.str().c_str(), GENERIC_READ | GENERIC_WRITE, 0, nullptr,
|
||||||
|
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, nullptr);
|
||||||
if(GetLastError() == ERROR_SUCCESS)
|
if(GetLastError() == ERROR_SUCCESS)
|
||||||
break; // We have the file handle
|
break; // We have the file handle
|
||||||
|
|
||||||
|
|
@ -216,7 +235,7 @@ bool VCP::open(bool fromAsync) {
|
||||||
|
|
||||||
// Set the timeouts
|
// Set the timeouts
|
||||||
COMMTIMEOUTS timeouts;
|
COMMTIMEOUTS timeouts;
|
||||||
if(!GetCommTimeouts(handle, &timeouts)) {
|
if(!GetCommTimeouts(detail->handle, &timeouts)) {
|
||||||
close();
|
close();
|
||||||
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
|
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -229,7 +248,7 @@ bool VCP::open(bool fromAsync) {
|
||||||
timeouts.WriteTotalTimeoutConstant = 10000;
|
timeouts.WriteTotalTimeoutConstant = 10000;
|
||||||
timeouts.WriteTotalTimeoutMultiplier = 0;
|
timeouts.WriteTotalTimeoutMultiplier = 0;
|
||||||
|
|
||||||
if(!SetCommTimeouts(handle, &timeouts)) {
|
if(!SetCommTimeouts(detail->handle, &timeouts)) {
|
||||||
close();
|
close();
|
||||||
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
|
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -237,7 +256,7 @@ bool VCP::open(bool fromAsync) {
|
||||||
|
|
||||||
// Set the COM state
|
// Set the COM state
|
||||||
DCB comstate;
|
DCB comstate;
|
||||||
if(!GetCommState(handle, &comstate)) {
|
if(!GetCommState(detail->handle, &comstate)) {
|
||||||
close();
|
close();
|
||||||
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
|
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -250,26 +269,26 @@ bool VCP::open(bool fromAsync) {
|
||||||
comstate.fDtrControl = DTR_CONTROL_ENABLE;
|
comstate.fDtrControl = DTR_CONTROL_ENABLE;
|
||||||
comstate.fRtsControl = RTS_CONTROL_ENABLE;
|
comstate.fRtsControl = RTS_CONTROL_ENABLE;
|
||||||
|
|
||||||
if(!SetCommState(handle, &comstate)) {
|
if(!SetCommState(detail->handle, &comstate)) {
|
||||||
close();
|
close();
|
||||||
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
|
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
PurgeComm(handle, PURGE_RXCLEAR);
|
PurgeComm(detail->handle, PURGE_RXCLEAR);
|
||||||
|
|
||||||
// Set up events so that overlapped IO can work with them
|
// Set up events so that overlapped IO can work with them
|
||||||
overlappedRead.hEvent = CreateEvent(nullptr, false, false, nullptr);
|
detail->overlappedRead.hEvent = CreateEvent(nullptr, false, false, nullptr);
|
||||||
overlappedWrite.hEvent = CreateEvent(nullptr, false, false, nullptr);
|
detail->overlappedWrite.hEvent = CreateEvent(nullptr, false, false, nullptr);
|
||||||
overlappedWait.hEvent = CreateEvent(nullptr, true, false, nullptr);
|
detail->overlappedWait.hEvent = CreateEvent(nullptr, true, false, nullptr);
|
||||||
if (overlappedRead.hEvent == nullptr || overlappedWrite.hEvent == nullptr || overlappedWait.hEvent == nullptr) {
|
if (detail->overlappedRead.hEvent == nullptr || detail->overlappedWrite.hEvent == nullptr || detail->overlappedWait.hEvent == nullptr) {
|
||||||
close();
|
close();
|
||||||
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
|
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up event so that we will satisfy overlappedWait when a character comes in
|
// Set up event so that we will satisfy overlappedWait when a character comes in
|
||||||
if(!SetCommMask(handle, EV_RXCHAR)) {
|
if(!SetCommMask(detail->handle, EV_RXCHAR)) {
|
||||||
close();
|
close();
|
||||||
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
|
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -303,28 +322,28 @@ bool VCP::close() {
|
||||||
writeThread.join();
|
writeThread.join();
|
||||||
closing = false;
|
closing = false;
|
||||||
|
|
||||||
if(!CloseHandle(handle)) {
|
if(!CloseHandle(detail->handle)) {
|
||||||
report(APIEvent::Type::DriverFailedToClose, APIEvent::Severity::Error);
|
report(APIEvent::Type::DriverFailedToClose, APIEvent::Severity::Error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
handle = INVALID_HANDLE_VALUE;
|
detail->handle = INVALID_HANDLE_VALUE;
|
||||||
|
|
||||||
bool ret = true; // If one of the events fails closing, we probably still want to try and close the others
|
bool ret = true; // If one of the events fails closing, we probably still want to try and close the others
|
||||||
if(overlappedRead.hEvent != INVALID_HANDLE_VALUE) {
|
if(detail->overlappedRead.hEvent != INVALID_HANDLE_VALUE) {
|
||||||
if(!CloseHandle(overlappedRead.hEvent))
|
if(!CloseHandle(detail->overlappedRead.hEvent))
|
||||||
ret = false;
|
ret = false;
|
||||||
overlappedRead.hEvent = INVALID_HANDLE_VALUE;
|
detail->overlappedRead.hEvent = INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
if(overlappedWrite.hEvent != INVALID_HANDLE_VALUE) {
|
if(detail->overlappedWrite.hEvent != INVALID_HANDLE_VALUE) {
|
||||||
if(!CloseHandle(overlappedWrite.hEvent))
|
if(!CloseHandle(detail->overlappedWrite.hEvent))
|
||||||
ret = false;
|
ret = false;
|
||||||
overlappedWrite.hEvent = INVALID_HANDLE_VALUE;
|
detail->overlappedWrite.hEvent = INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
if(overlappedWait.hEvent != INVALID_HANDLE_VALUE) {
|
if(detail->overlappedWait.hEvent != INVALID_HANDLE_VALUE) {
|
||||||
if(!CloseHandle(overlappedWait.hEvent))
|
if(!CloseHandle(detail->overlappedWait.hEvent))
|
||||||
ret = false;
|
ret = false;
|
||||||
overlappedWait.hEvent = INVALID_HANDLE_VALUE;
|
detail->overlappedWait.hEvent = INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t flush;
|
uint8_t flush;
|
||||||
|
|
@ -340,6 +359,10 @@ bool VCP::close() {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VCP::isOpen() {
|
||||||
|
return detail->handle != INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
void VCP::readTask() {
|
void VCP::readTask() {
|
||||||
constexpr size_t READ_BUFFER_SIZE = 10240;
|
constexpr size_t READ_BUFFER_SIZE = 10240;
|
||||||
uint8_t readbuf[READ_BUFFER_SIZE];
|
uint8_t readbuf[READ_BUFFER_SIZE];
|
||||||
|
|
@ -351,11 +374,11 @@ void VCP::readTask() {
|
||||||
case LAUNCH: {
|
case LAUNCH: {
|
||||||
COMSTAT comStatus;
|
COMSTAT comStatus;
|
||||||
unsigned long errorCodes;
|
unsigned long errorCodes;
|
||||||
ClearCommError(handle, &errorCodes, &comStatus);
|
ClearCommError(detail->handle, &errorCodes, &comStatus);
|
||||||
|
|
||||||
bytesRead = 0;
|
bytesRead = 0;
|
||||||
if(ReadFile(handle, readbuf, READ_BUFFER_SIZE, nullptr, &overlappedRead)) {
|
if(ReadFile(detail->handle, readbuf, READ_BUFFER_SIZE, nullptr, &detail->overlappedRead)) {
|
||||||
if(GetOverlappedResult(handle, &overlappedRead, &bytesRead, FALSE)) {
|
if(GetOverlappedResult(detail->handle, &detail->overlappedRead, &bytesRead, FALSE)) {
|
||||||
if(bytesRead)
|
if(bytesRead)
|
||||||
readQueue.enqueue_bulk(readbuf, bytesRead);
|
readQueue.enqueue_bulk(readbuf, bytesRead);
|
||||||
}
|
}
|
||||||
|
|
@ -377,9 +400,9 @@ void VCP::readTask() {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WAIT: {
|
case WAIT: {
|
||||||
auto ret = WaitForSingleObject(overlappedRead.hEvent, 100);
|
auto ret = WaitForSingleObject(detail->overlappedRead.hEvent, 100);
|
||||||
if(ret == WAIT_OBJECT_0) {
|
if(ret == WAIT_OBJECT_0) {
|
||||||
if(GetOverlappedResult(handle, &overlappedRead, &bytesRead, FALSE)) {
|
if(GetOverlappedResult(detail->handle, &detail->overlappedRead, &bytesRead, FALSE)) {
|
||||||
readQueue.enqueue_bulk(readbuf, bytesRead);
|
readQueue.enqueue_bulk(readbuf, bytesRead);
|
||||||
state = LAUNCH;
|
state = LAUNCH;
|
||||||
} else
|
} else
|
||||||
|
|
@ -406,7 +429,7 @@ void VCP::writeTask() {
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
bytesWritten = 0;
|
bytesWritten = 0;
|
||||||
if(WriteFile(handle, writeOp.bytes.data(), (DWORD)writeOp.bytes.size(), nullptr, &overlappedWrite))
|
if(WriteFile(detail->handle, writeOp.bytes.data(), (DWORD)writeOp.bytes.size(), nullptr, &detail->overlappedWrite))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto winerr = GetLastError();
|
auto winerr = GetLastError();
|
||||||
|
|
@ -423,9 +446,9 @@ void VCP::writeTask() {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WAIT: {
|
case WAIT: {
|
||||||
auto ret = WaitForSingleObject(overlappedWrite.hEvent, 50);
|
auto ret = WaitForSingleObject(detail->overlappedWrite.hEvent, 50);
|
||||||
if(ret == WAIT_OBJECT_0) {
|
if(ret == WAIT_OBJECT_0) {
|
||||||
if(!GetOverlappedResult(handle, &overlappedWrite, &bytesWritten, FALSE))
|
if(!GetOverlappedResult(detail->handle, &detail->overlappedWrite, &bytesWritten, FALSE))
|
||||||
report(APIEvent::Type::FailedToWrite, APIEvent::Severity::Error);
|
report(APIEvent::Type::FailedToWrite, APIEvent::Severity::Error);
|
||||||
state = LAUNCH;
|
state = LAUNCH;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue