#include "lusbk_private.h"
BOOL Ioctl_Async(__in HANDLE dev,
__in INT code,
__in_opt PVOID in,
__in DWORD in_size,
__inout_opt PVOID out,
__in DWORD out_size,
__in LPOVERLAPPED overlapped)
{
DWORD ret = ERROR_INVALID_PARAMETER;
if (overlapped)
return DeviceIoControl(dev, code, in, in_size, out, out_size, NULL, overlapped);
USBERR("overlapped cannot be null.");
return LusbwError(ret);
}
BOOL Ioctl_Sync(__in HANDLE dev,
__in INT code,
__in_opt PVOID in,
__in DWORD in_size,
__inout_opt PVOID out,
__in DWORD out_size,
__out_opt PUINT ret)
{
OVERLAPPED ol;
DWORD _ret;
memset(&ol, 0, sizeof(ol));
if (ret)
*ret = 0;
ol.hEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
if (!ol.hEvent)
return FALSE;
if (!DeviceIoControl(dev, code, in, in_size, out, out_size, NULL, &ol))
{
_ret = GetLastError();
if (_ret != ERROR_IO_PENDING)
{
CloseHandle(ol.hEvent);
SetLastError(_ret);
return FALSE;
}
}
if (!GetOverlappedResult(dev, &ol, &_ret, TRUE))
{
_ret = GetLastError();
CloseHandle(ol.hEvent);
SetLastError(_ret);
return FALSE;
}
if (ret)
*ret = _ret;
return CloseHandle(ol.hEvent);
}
BOOL Ioctl_SyncWithTimeout(__in HANDLE DeviceHandle,
__in INT code,
__in libusb_request* request,
__inout_opt PVOID out,
__in DWORD out_size,
__in INT timeout,
__in UCHAR PipeID,
__out_opt PUINT ret)
{
OVERLAPPED ol;
DWORD _ret;
BOOL bWait = FALSE;
memset(&ol, 0, sizeof(ol));
if (ret)
*ret = 0;
ol.hEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
if (!ol.hEvent)
return FALSE;
if (!DeviceIoControl(DeviceHandle, code, request, sizeof(*request), out, out_size, NULL, &ol))
{
_ret = GetLastError();
if (_ret != ERROR_IO_PENDING)
{
CloseHandle(ol.hEvent);
SetLastError(_ret);
return FALSE;
}
if (timeout)
{
if ((_ret = WaitForSingleObject(ol.hEvent, timeout)) != WAIT_OBJECT_0)
{
libusb_request abort_request;
Mem_Zero(&abort_request, sizeof(abort_request));
abort_request.endpoint.endpoint = PipeID;
if (!Ioctl_Sync(DeviceHandle,
LIBUSB_IOCTL_ABORT_ENDPOINT,
&abort_request, sizeof(abort_request),
NULL, 0,
NULL))
{
_ret = GetLastError();
USBERRN("A transfer time out occurred and it could not be aborted. Timeout=%u PipeID=%02Xh ErrorCode=%08Xh",
timeout, PipeID, _ret);
}
else
{
_ret = ERROR_SEM_TIMEOUT;
SetLastError(_ret);
}
WaitForSingleObject(ol.hEvent, 0);
CloseHandle(ol.hEvent);
return FALSE;
}
}
else
{
_ret = WaitForSingleObject(ol.hEvent, INFINITE);
}
}
else
{
bWait = TRUE;
}
if (!GetOverlappedResult(DeviceHandle, &ol, &_ret, bWait))
{
_ret = GetLastError();
CloseHandle(ol.hEvent);
SetLastError(_ret);
return FALSE;
}
if (ret)
*ret = _ret;
return CloseHandle(ol.hEvent);
}