Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 32 additions & 6 deletions src/parsec-vusb-api/parsec-vusb-api.cc
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#include "parsec-vusb-api.h"
#include <print>
#include <string>
#include <system_error>

#include <setupapi.h>
#include <windows.h>
Expand All @@ -13,6 +12,7 @@ constexpr DWORD IOCTL_VIRTUAL_USB_DEVICE_CREATE = 0x2ae804;
constexpr DWORD IOCTL_CONFIGURE_ENDPOINTS = 0x2aa808;
constexpr DWORD IOCTL_CONFIGURE_ENDPOINT_TYPES = 0x2aa81c;
constexpr DWORD IOCTL_PLUG_IN_DEVICE = 0x2aac04;
constexpr DWORD IOCTL_UNPLUG_DEVICE = 0x2aac08;
constexpr DWORD IOCTL_QUERY_MEDIA = 0x2af014;
constexpr DWORD IOCTL_SUBMIT_AUDIO = 0x2ab018;

Expand Down Expand Up @@ -84,8 +84,10 @@ static void vusb_ioctl_in_out(HANDLE handle, DWORD code,

if (!GetOverlappedResult(handle, &overlapped, &bytes_returned, TRUE)) {
DWORD error = GetLastError();
CloseHandle(overlapped.hEvent);
throw VUSBError("GetOverlappedResult failed.", error);
if (error != ERROR_NOT_READY) {
CloseHandle(overlapped.hEvent);
throw VUSBError("GetOverlappedResult failed.", error);
}
}

CloseHandle(overlapped.hEvent);
Expand Down Expand Up @@ -200,6 +202,8 @@ VirtualUSBDevice::VirtualUSBDevice(
vusb_ioctl_in_out(_hub_handle, IOCTL_VIRTUAL_USB_DEVICE_CREATE, buffer);

_device_id = *reinterpret_cast<uint32_t *>(buffer.data() + 4);
_device_handle = *reinterpret_cast<HANDLE *>(buffer.data() + 4);
_unknown_handle = *reinterpret_cast<HANDLE *>(buffer.data() + 12);

wchar_t event_name[MAX_PATH];
swprintf_s(event_name, MAX_PATH,
Expand Down Expand Up @@ -249,6 +253,25 @@ VirtualUSBDevice::operator=(VirtualUSBDevice &&other) noexcept {
return *this;
}

void VirtualUSBDevice::destroy_device() {
if (_device_handle == INVALID_HANDLE_VALUE || _device_id == 0) {
return;
}

std::vector<uint8_t> buffer(8);
write_to_buffer(buffer, 0, static_cast<uint32_t>(8));
write_to_buffer(buffer, 4, _device_id);

vusb_ioctl(_hub_handle, IOCTL_UNPLUG_DEVICE, buffer);

SetEvent(_device_handle);
CloseHandle(_device_handle);
CloseHandle(_unknown_handle);

_device_handle = INVALID_HANDLE_VALUE;
_device_id = 0;
}

void VirtualUSBDevice::close() {
if (_control_wait_event) {
CloseHandle(_control_wait_event);
Expand Down Expand Up @@ -456,9 +479,12 @@ bool VirtualUSBDevice::submit_audio_data(const std::vector<uint8_t> &data) {
}

if (!GetOverlappedResult(_hub_handle, &overlapped, &bytes_returned, TRUE)) {
CloseHandle(overlapped.hEvent);
throw VUSBError("Submit audio GetOverlappedResult failed.",
GetLastError());
DWORD error = GetLastError();
if (error != ERROR_NOT_READY) {
CloseHandle(overlapped.hEvent);
throw VUSBError("Submit audio GetOverlappedResult failed.",
GetLastError());
}
}
CloseHandle(overlapped.hEvent);

Expand Down
3 changes: 3 additions & 0 deletions src/parsec-vusb-api/parsec-vusb-api.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ class VirtualUSBDevice {
void configure_endpoint_types(const std::vector<int32_t> &endpointTypes);
void plug_in();
void unplug();
void destroy_device();
bool submit_audio_data(const std::vector<uint8_t> &data);
inline bool submit_audio_data(const std::vector<int16_t> &data) {
return submit_audio_data(std::vector<uint8_t>(
Expand All @@ -117,6 +118,8 @@ class VirtualUSBDevice {
void close();

HANDLE _hub_handle = INVALID_HANDLE_VALUE;
HANDLE _device_handle = INVALID_HANDLE_VALUE;
HANDLE _unknown_handle = INVALID_HANDLE_VALUE;
uint32_t _device_id = 0;
HANDLE _control_wait_event = nullptr;
HANDLE _cancelled_wait_event = nullptr;
Expand Down
Loading