Merge pull request #6410 from leoetlino/timing-groundwork
IOS: Change devices to always return IPCCommandResult
This commit is contained in:
commit
f2891418da
|
@ -161,16 +161,16 @@ void Device::DoStateShared(PointerWrap& p)
|
|||
p.Do(m_is_active);
|
||||
}
|
||||
|
||||
ReturnCode Device::Open(const OpenRequest& request)
|
||||
IPCCommandResult Device::Open(const OpenRequest& request)
|
||||
{
|
||||
m_is_active = true;
|
||||
return IPC_SUCCESS;
|
||||
return GetDefaultReply(IPC_SUCCESS);
|
||||
}
|
||||
|
||||
ReturnCode Device::Close(u32 fd)
|
||||
IPCCommandResult Device::Close(u32 fd)
|
||||
{
|
||||
m_is_active = false;
|
||||
return IPC_SUCCESS;
|
||||
return GetDefaultReply(IPC_SUCCESS);
|
||||
}
|
||||
|
||||
IPCCommandResult Device::Unsupported(const Request& request)
|
||||
|
|
|
@ -188,8 +188,8 @@ public:
|
|||
const std::string& GetDeviceName() const { return m_name; }
|
||||
// Replies to Open and Close requests are sent by the IPC request handler (HandleCommand),
|
||||
// not by the devices themselves.
|
||||
virtual ReturnCode Open(const OpenRequest& request);
|
||||
virtual ReturnCode Close(u32 fd);
|
||||
virtual IPCCommandResult Open(const OpenRequest& request);
|
||||
virtual IPCCommandResult Close(u32 fd);
|
||||
virtual IPCCommandResult Seek(const SeekRequest& seek) { return Unsupported(seek); }
|
||||
virtual IPCCommandResult Read(const ReadWriteRequest& read) { return Unsupported(read); }
|
||||
virtual IPCCommandResult Write(const ReadWriteRequest& write) { return Unsupported(write); }
|
||||
|
|
|
@ -12,11 +12,11 @@ namespace HLE
|
|||
{
|
||||
namespace Device
|
||||
{
|
||||
ReturnCode Stub::Open(const OpenRequest& request)
|
||||
IPCCommandResult Stub::Open(const OpenRequest& request)
|
||||
{
|
||||
WARN_LOG(IOS, "%s faking Open()", m_name.c_str());
|
||||
m_is_active = true;
|
||||
return IPC_SUCCESS;
|
||||
return GetDefaultReply(IPC_SUCCESS);
|
||||
}
|
||||
|
||||
IPCCommandResult Stub::IOCtl(const IOCtlRequest& request)
|
||||
|
|
|
@ -21,7 +21,7 @@ class Stub final : public Device
|
|||
public:
|
||||
// Inherit the constructor from the Device class, since we don't need to do anything special.
|
||||
using Device::Device;
|
||||
ReturnCode Open(const OpenRequest& request) override;
|
||||
IPCCommandResult Open(const OpenRequest& request) override;
|
||||
IPCCommandResult IOCtl(const IOCtlRequest& request) override;
|
||||
IPCCommandResult IOCtlV(const IOCtlVRequest& request) override;
|
||||
};
|
||||
|
|
|
@ -372,11 +372,11 @@ ES::ContextArray::iterator ES::FindInactiveContext()
|
|||
[](const auto& context) { return !context.active; });
|
||||
}
|
||||
|
||||
ReturnCode ES::Open(const OpenRequest& request)
|
||||
IPCCommandResult ES::Open(const OpenRequest& request)
|
||||
{
|
||||
auto context = FindInactiveContext();
|
||||
if (context == m_contexts.end())
|
||||
return ES_FD_EXHAUSTED;
|
||||
return GetDefaultReply(ES_FD_EXHAUSTED);
|
||||
|
||||
context->active = true;
|
||||
context->uid = request.uid;
|
||||
|
@ -385,18 +385,18 @@ ReturnCode ES::Open(const OpenRequest& request)
|
|||
return Device::Open(request);
|
||||
}
|
||||
|
||||
ReturnCode ES::Close(u32 fd)
|
||||
IPCCommandResult ES::Close(u32 fd)
|
||||
{
|
||||
auto context = FindActiveContext(fd);
|
||||
if (context == m_contexts.end())
|
||||
return ES_EINVAL;
|
||||
return GetDefaultReply(ES_EINVAL);
|
||||
|
||||
context->active = false;
|
||||
context->ipc_fd = -1;
|
||||
|
||||
INFO_LOG(IOS_ES, "ES: Close");
|
||||
m_is_active = false;
|
||||
return IPC_SUCCESS;
|
||||
return GetDefaultReply(IPC_SUCCESS);
|
||||
}
|
||||
|
||||
IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request)
|
||||
|
|
|
@ -46,8 +46,8 @@ public:
|
|||
|
||||
void DoState(PointerWrap& p) override;
|
||||
|
||||
ReturnCode Open(const OpenRequest& request) override;
|
||||
ReturnCode Close(u32 fd) override;
|
||||
IPCCommandResult Open(const OpenRequest& request) override;
|
||||
IPCCommandResult Close(u32 fd) override;
|
||||
IPCCommandResult IOCtlV(const IOCtlVRequest& request) override;
|
||||
|
||||
struct TitleImportExportContext
|
||||
|
|
|
@ -138,12 +138,6 @@ void FS::DoState(PointerWrap& p)
|
|||
}
|
||||
}
|
||||
|
||||
ReturnCode FS::Open(const OpenRequest& request)
|
||||
{
|
||||
m_is_active = true;
|
||||
return IPC_SUCCESS;
|
||||
}
|
||||
|
||||
// Get total filesize of contents of a directory (recursive)
|
||||
// Only used for ES_GetUsage atm, could be useful elsewhere?
|
||||
static u64 ComputeTotalFileSize(const File::FSTEntry& parentEntry)
|
||||
|
|
|
@ -36,7 +36,6 @@ public:
|
|||
|
||||
void DoState(PointerWrap& p) override;
|
||||
|
||||
ReturnCode Open(const OpenRequest& request) override;
|
||||
IPCCommandResult IOCtl(const IOCtlRequest& request) override;
|
||||
IPCCommandResult IOCtlV(const IOCtlVRequest& request) override;
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ FileIO::FileIO(Kernel& ios, const std::string& device_name)
|
|||
{
|
||||
}
|
||||
|
||||
ReturnCode FileIO::Close(u32 fd)
|
||||
IPCCommandResult FileIO::Close(u32 fd)
|
||||
{
|
||||
INFO_LOG(IOS_FILEIO, "FileIO: Close %s", m_name.c_str());
|
||||
m_Mode = 0;
|
||||
|
@ -89,10 +89,10 @@ ReturnCode FileIO::Close(u32 fd)
|
|||
m_file.reset();
|
||||
|
||||
m_is_active = false;
|
||||
return IPC_SUCCESS;
|
||||
return GetDefaultReply(IPC_SUCCESS);
|
||||
}
|
||||
|
||||
ReturnCode FileIO::Open(const OpenRequest& request)
|
||||
IPCCommandResult FileIO::Open(const OpenRequest& request)
|
||||
{
|
||||
m_Mode = request.flags;
|
||||
|
||||
|
@ -106,14 +106,14 @@ ReturnCode FileIO::Open(const OpenRequest& request)
|
|||
{
|
||||
WARN_LOG(IOS_FILEIO, "FileIO: Open (%s) failed - File doesn't exist %s", Modes[m_Mode],
|
||||
m_filepath.c_str());
|
||||
return FS_ENOENT;
|
||||
return GetDefaultReply(FS_ENOENT);
|
||||
}
|
||||
|
||||
INFO_LOG(IOS_FILEIO, "FileIO: Open %s (%s == %08X)", m_name.c_str(), Modes[m_Mode], m_Mode);
|
||||
OpenFile();
|
||||
|
||||
m_is_active = true;
|
||||
return IPC_SUCCESS;
|
||||
return GetDefaultReply(IPC_SUCCESS);
|
||||
}
|
||||
|
||||
// This isn't theadsafe, but it's only called from the CPU thread.
|
||||
|
|
|
@ -32,8 +32,8 @@ class FileIO : public Device
|
|||
public:
|
||||
FileIO(Kernel& ios, const std::string& device_name);
|
||||
|
||||
ReturnCode Close(u32 fd) override;
|
||||
ReturnCode Open(const OpenRequest& request) override;
|
||||
IPCCommandResult Close(u32 fd) override;
|
||||
IPCCommandResult Open(const OpenRequest& request) override;
|
||||
IPCCommandResult Seek(const SeekRequest& request) override;
|
||||
IPCCommandResult Read(const ReadWriteRequest& request) override;
|
||||
IPCCommandResult Write(const ReadWriteRequest& request) override;
|
||||
|
|
|
@ -468,14 +468,14 @@ std::shared_ptr<Device::Device> EmulationKernel::GetDeviceByName(const std::stri
|
|||
}
|
||||
|
||||
// Returns the FD for the newly opened device (on success) or an error code.
|
||||
s32 Kernel::OpenDevice(OpenRequest& request)
|
||||
IPCCommandResult Kernel::OpenDevice(OpenRequest& request)
|
||||
{
|
||||
const s32 new_fd = GetFreeDeviceID();
|
||||
INFO_LOG(IOS, "Opening %s (mode %d, fd %d)", request.path.c_str(), request.flags, new_fd);
|
||||
if (new_fd < 0 || new_fd >= IPC_MAX_FDS)
|
||||
{
|
||||
ERROR_LOG(IOS, "Couldn't get a free fd, too many open files");
|
||||
return FS_EFDEXHAUSTED;
|
||||
return Device::Device::GetDefaultReply(FS_EFDEXHAUSTED);
|
||||
}
|
||||
request.fd = new_fd;
|
||||
|
||||
|
@ -497,14 +497,13 @@ s32 Kernel::OpenDevice(OpenRequest& request)
|
|||
if (!device)
|
||||
{
|
||||
ERROR_LOG(IOS, "Unknown device: %s", request.path.c_str());
|
||||
return IPC_ENOENT;
|
||||
return Device::Device::GetDefaultReply(IPC_ENOENT);
|
||||
}
|
||||
|
||||
const ReturnCode code = device->Open(request);
|
||||
if (code < IPC_SUCCESS)
|
||||
return code;
|
||||
m_fdmap[new_fd] = device;
|
||||
return new_fd;
|
||||
const IPCCommandResult result = device->Open(request);
|
||||
if (result.return_value >= IPC_SUCCESS)
|
||||
m_fdmap[new_fd] = device;
|
||||
return result;
|
||||
}
|
||||
|
||||
IPCCommandResult Kernel::HandleIPCCommand(const Request& request)
|
||||
|
@ -512,8 +511,7 @@ IPCCommandResult Kernel::HandleIPCCommand(const Request& request)
|
|||
if (request.command == IPC_CMD_OPEN)
|
||||
{
|
||||
OpenRequest open_request{request.address};
|
||||
const s32 new_fd = OpenDevice(open_request);
|
||||
return Device::Device::GetDefaultReply(new_fd);
|
||||
return OpenDevice(open_request);
|
||||
}
|
||||
|
||||
const auto device = (request.fd < IPC_MAX_FDS) ? m_fdmap[request.fd] : nullptr;
|
||||
|
@ -527,7 +525,7 @@ IPCCommandResult Kernel::HandleIPCCommand(const Request& request)
|
|||
{
|
||||
case IPC_CMD_CLOSE:
|
||||
m_fdmap[request.fd].reset();
|
||||
ret = Device::Device::GetDefaultReply(device->Close(request.fd));
|
||||
ret = device->Close(request.fd);
|
||||
break;
|
||||
case IPC_CMD_READ:
|
||||
ret = device->Read(ReadWriteRequest{request.address});
|
||||
|
|
|
@ -126,7 +126,7 @@ protected:
|
|||
void AddStaticDevices();
|
||||
std::shared_ptr<Device::Device> GetDeviceByName(const std::string& device_name);
|
||||
s32 GetFreeDeviceID();
|
||||
s32 OpenDevice(OpenRequest& request);
|
||||
IPCCommandResult OpenDevice(OpenRequest& request);
|
||||
|
||||
bool m_is_responsible_for_nand_root = false;
|
||||
u64 m_title_id = 0;
|
||||
|
|
|
@ -80,17 +80,17 @@ void SDIOSlot0::OpenInternal()
|
|||
}
|
||||
}
|
||||
|
||||
ReturnCode SDIOSlot0::Open(const OpenRequest& request)
|
||||
IPCCommandResult SDIOSlot0::Open(const OpenRequest& request)
|
||||
{
|
||||
OpenInternal();
|
||||
m_registers.fill(0);
|
||||
|
||||
m_is_active = true;
|
||||
|
||||
return IPC_SUCCESS;
|
||||
return GetDefaultReply(IPC_SUCCESS);
|
||||
}
|
||||
|
||||
ReturnCode SDIOSlot0::Close(u32 fd)
|
||||
IPCCommandResult SDIOSlot0::Close(u32 fd)
|
||||
{
|
||||
m_card.Close();
|
||||
m_block_length = 0;
|
||||
|
|
|
@ -30,8 +30,8 @@ public:
|
|||
|
||||
void DoState(PointerWrap& p) override;
|
||||
|
||||
ReturnCode Open(const OpenRequest& request) override;
|
||||
ReturnCode Close(u32 fd) override;
|
||||
IPCCommandResult Open(const OpenRequest& request) override;
|
||||
IPCCommandResult Close(u32 fd) override;
|
||||
IPCCommandResult IOCtl(const IOCtlRequest& request) override;
|
||||
IPCCommandResult IOCtlV(const IOCtlVRequest& request) override;
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ IPCCommandResult STMImmediate::IOCtl(const IOCtlRequest& request)
|
|||
return GetDefaultReply(return_value);
|
||||
}
|
||||
|
||||
ReturnCode STMEventHook::Close(u32 fd)
|
||||
IPCCommandResult STMEventHook::Close(u32 fd)
|
||||
{
|
||||
s_event_hook_request.reset();
|
||||
return Device::Close(fd);
|
||||
|
|
|
@ -55,7 +55,7 @@ class STMEventHook final : public Device
|
|||
{
|
||||
public:
|
||||
using Device::Device;
|
||||
ReturnCode Close(u32 fd) override;
|
||||
IPCCommandResult Close(u32 fd) override;
|
||||
IPCCommandResult IOCtl(const IOCtlRequest& request) override;
|
||||
void DoState(PointerWrap& p) override;
|
||||
|
||||
|
|
|
@ -133,7 +133,7 @@ bool BluetoothEmu::RemoteDisconnect(u16 _connectionHandle)
|
|||
return SendEventDisconnect(_connectionHandle, 0x13);
|
||||
}
|
||||
|
||||
ReturnCode BluetoothEmu::Close(u32 fd)
|
||||
IPCCommandResult BluetoothEmu::Close(u32 fd)
|
||||
{
|
||||
// Clean up state
|
||||
m_ScanEnable = 0;
|
||||
|
|
|
@ -49,7 +49,7 @@ public:
|
|||
|
||||
virtual ~BluetoothEmu();
|
||||
|
||||
ReturnCode Close(u32 fd) override;
|
||||
IPCCommandResult Close(u32 fd) override;
|
||||
IPCCommandResult IOCtlV(const IOCtlVRequest& request) override;
|
||||
|
||||
void Update() override;
|
||||
|
|
|
@ -86,10 +86,10 @@ BluetoothReal::~BluetoothReal()
|
|||
SaveLinkKeys();
|
||||
}
|
||||
|
||||
ReturnCode BluetoothReal::Open(const OpenRequest& request)
|
||||
IPCCommandResult BluetoothReal::Open(const OpenRequest& request)
|
||||
{
|
||||
if (!m_libusb_context)
|
||||
return IPC_EACCES;
|
||||
return GetDefaultReply(IPC_EACCES);
|
||||
|
||||
libusb_device** list;
|
||||
const ssize_t cnt = libusb_get_device_list(m_libusb_context, &list);
|
||||
|
@ -97,7 +97,7 @@ ReturnCode BluetoothReal::Open(const OpenRequest& request)
|
|||
{
|
||||
ERROR_LOG(IOS_WIIMOTE, "Couldn't get device list: %s",
|
||||
libusb_error_name(static_cast<int>(cnt)));
|
||||
return IPC_ENOENT;
|
||||
return GetDefaultReply(IPC_ENOENT);
|
||||
}
|
||||
|
||||
for (ssize_t i = 0; i < cnt; ++i)
|
||||
|
@ -142,16 +142,15 @@ ReturnCode BluetoothReal::Open(const OpenRequest& request)
|
|||
PanicAlertT("Bluetooth passthrough mode is enabled, "
|
||||
"but no usable Bluetooth USB device was found. Aborting.");
|
||||
Core::QueueHostJob(Core::Stop);
|
||||
return IPC_ENOENT;
|
||||
return GetDefaultReply(IPC_ENOENT);
|
||||
}
|
||||
|
||||
StartTransferThread();
|
||||
|
||||
m_is_active = true;
|
||||
return IPC_SUCCESS;
|
||||
return Device::Open(request);
|
||||
}
|
||||
|
||||
ReturnCode BluetoothReal::Close(u32 fd)
|
||||
IPCCommandResult BluetoothReal::Close(u32 fd)
|
||||
{
|
||||
if (m_handle)
|
||||
{
|
||||
|
|
|
@ -51,8 +51,8 @@ public:
|
|||
BluetoothReal(Kernel& ios, const std::string& device_name);
|
||||
~BluetoothReal() override;
|
||||
|
||||
ReturnCode Open(const OpenRequest& request) override;
|
||||
ReturnCode Close(u32 fd) override;
|
||||
IPCCommandResult Open(const OpenRequest& request) override;
|
||||
IPCCommandResult Close(u32 fd) override;
|
||||
IPCCommandResult IOCtlV(const IOCtlVRequest& request) override;
|
||||
|
||||
void DoState(PointerWrap& p) override;
|
||||
|
|
|
@ -14,11 +14,11 @@ namespace HLE
|
|||
{
|
||||
namespace Device
|
||||
{
|
||||
ReturnCode BluetoothStub::Open(const OpenRequest& request)
|
||||
IPCCommandResult BluetoothStub::Open(const OpenRequest& request)
|
||||
{
|
||||
PanicAlertT("Bluetooth passthrough mode is enabled, but Dolphin was built without libusb."
|
||||
" Passthrough mode cannot be used.");
|
||||
return IPC_ENOENT;
|
||||
return GetDefaultReply(IPC_ENOENT);
|
||||
}
|
||||
|
||||
void BluetoothStub::DoState(PointerWrap& p)
|
||||
|
|
|
@ -22,7 +22,7 @@ class BluetoothStub final : public BluetoothBase
|
|||
{
|
||||
public:
|
||||
using BluetoothBase::BluetoothBase;
|
||||
ReturnCode Open(const OpenRequest& request) override;
|
||||
IPCCommandResult Open(const OpenRequest& request) override;
|
||||
void DoState(PointerWrap& p) override;
|
||||
};
|
||||
} // namespace Device
|
||||
|
|
|
@ -47,7 +47,7 @@ USBHost::~USBHost()
|
|||
#endif
|
||||
}
|
||||
|
||||
ReturnCode USBHost::Open(const OpenRequest& request)
|
||||
IPCCommandResult USBHost::Open(const OpenRequest& request)
|
||||
{
|
||||
// Force a device scan to complete, because some games (including Your Shape) only care
|
||||
// about the initial device list (in the first GETDEVICECHANGE reply).
|
||||
|
@ -55,7 +55,7 @@ ReturnCode USBHost::Open(const OpenRequest& request)
|
|||
{
|
||||
}
|
||||
StartThreads();
|
||||
return IPC_SUCCESS;
|
||||
return GetDefaultReply(IPC_SUCCESS);
|
||||
}
|
||||
|
||||
void USBHost::UpdateWantDeterminism(const bool new_want_determinism)
|
||||
|
|
|
@ -36,7 +36,7 @@ public:
|
|||
USBHost(Kernel& ios, const std::string& device_name);
|
||||
virtual ~USBHost();
|
||||
|
||||
ReturnCode Open(const OpenRequest& request) override;
|
||||
IPCCommandResult Open(const OpenRequest& request) override;
|
||||
|
||||
void UpdateWantDeterminism(bool new_want_determinism) override;
|
||||
void DoState(PointerWrap& p) override;
|
||||
|
|
|
@ -35,10 +35,10 @@ OH0::~OH0()
|
|||
StopThreads();
|
||||
}
|
||||
|
||||
ReturnCode OH0::Open(const OpenRequest& request)
|
||||
IPCCommandResult OH0::Open(const OpenRequest& request)
|
||||
{
|
||||
if (HasFeature(m_ios.GetVersion(), Feature::NewUSB))
|
||||
return IPC_EACCES;
|
||||
return GetDefaultReply(IPC_EACCES);
|
||||
return USBHost::Open(request);
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ public:
|
|||
OH0(Kernel& ios, const std::string& device_name);
|
||||
~OH0() override;
|
||||
|
||||
ReturnCode Open(const OpenRequest& request) override;
|
||||
IPCCommandResult Open(const OpenRequest& request) override;
|
||||
IPCCommandResult IOCtl(const IOCtlRequest& request) override;
|
||||
IPCCommandResult IOCtlV(const IOCtlVRequest& request) override;
|
||||
|
||||
|
|
|
@ -55,19 +55,19 @@ void OH0Device::DoState(PointerWrap& p)
|
|||
p.Do(m_device_id);
|
||||
}
|
||||
|
||||
ReturnCode OH0Device::Open(const OpenRequest& request)
|
||||
IPCCommandResult OH0Device::Open(const OpenRequest& request)
|
||||
{
|
||||
if (m_vid == 0 && m_pid == 0)
|
||||
return IPC_ENOENT;
|
||||
return GetDefaultReply(IPC_ENOENT);
|
||||
|
||||
m_oh0 = std::static_pointer_cast<OH0>(GetIOS()->GetDeviceByName("/dev/usb/oh0"));
|
||||
|
||||
ReturnCode return_code;
|
||||
std::tie(return_code, m_device_id) = m_oh0->DeviceOpen(m_vid, m_pid);
|
||||
return return_code;
|
||||
return GetDefaultReply(return_code);
|
||||
}
|
||||
|
||||
ReturnCode OH0Device::Close(u32 fd)
|
||||
IPCCommandResult OH0Device::Close(u32 fd)
|
||||
{
|
||||
m_oh0->DeviceClose(m_device_id);
|
||||
return Device::Close(fd);
|
||||
|
|
|
@ -24,8 +24,8 @@ class OH0Device final : public Device
|
|||
public:
|
||||
OH0Device(Kernel& ios, const std::string& device_name);
|
||||
|
||||
ReturnCode Open(const OpenRequest& request) override;
|
||||
ReturnCode Close(u32 fd) override;
|
||||
IPCCommandResult Open(const OpenRequest& request) override;
|
||||
IPCCommandResult Close(u32 fd) override;
|
||||
IPCCommandResult IOCtl(const IOCtlRequest& request) override;
|
||||
IPCCommandResult IOCtlV(const IOCtlVRequest& request) override;
|
||||
void DoState(PointerWrap& p) override;
|
||||
|
|
|
@ -45,7 +45,7 @@ USB_KBD::USB_KBD(Kernel& ios, const std::string& device_name) : Device(ios, devi
|
|||
{
|
||||
}
|
||||
|
||||
ReturnCode USB_KBD::Open(const OpenRequest& request)
|
||||
IPCCommandResult USB_KBD::Open(const OpenRequest& request)
|
||||
{
|
||||
INFO_LOG(IOS, "USB_KBD: Open");
|
||||
IniFile ini;
|
||||
|
@ -61,8 +61,7 @@ ReturnCode USB_KBD::Open(const OpenRequest& request)
|
|||
m_OldModifiers = 0x00;
|
||||
|
||||
// m_MessageQueue.push(SMessageData(MSG_KBD_CONNECT, 0, nullptr));
|
||||
m_is_active = true;
|
||||
return IPC_SUCCESS;
|
||||
return Device::Open(request);
|
||||
}
|
||||
|
||||
IPCCommandResult USB_KBD::Write(const ReadWriteRequest& request)
|
||||
|
|
|
@ -22,7 +22,7 @@ class USB_KBD : public Device
|
|||
public:
|
||||
USB_KBD(Kernel& ios, const std::string& device_name);
|
||||
|
||||
ReturnCode Open(const OpenRequest& request) override;
|
||||
IPCCommandResult Open(const OpenRequest& request) override;
|
||||
IPCCommandResult Write(const ReadWriteRequest& request) override;
|
||||
IPCCommandResult IOCtl(const IOCtlRequest& request) override;
|
||||
void Update() override;
|
||||
|
|
Loading…
Reference in New Issue