Created
November 2, 2025 10:09
-
-
Save citrus610/32e54da1e36ae71f81d6f08b64b7f40c to your computer and use it in GitHub Desktop.
SCP driver interface c++
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "vxbox.h" | |
| namespace Vxbox | |
| { | |
| Bus::Bus() | |
| { | |
| this->handle = this->get_handle(); | |
| }; | |
| HANDLE Bus::get_handle() | |
| { | |
| WCHAR path[MAX_PATH]; | |
| auto n = this->get_path(path); | |
| if (n < 1) { | |
| return INVALID_HANDLE_VALUE; | |
| } | |
| return CreateFile( | |
| path, | |
| GENERIC_READ | GENERIC_WRITE, | |
| FILE_SHARE_READ | FILE_SHARE_WRITE, | |
| nullptr, | |
| OPEN_EXISTING, | |
| FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, | |
| nullptr | |
| ); | |
| }; | |
| int Bus::get_path(WCHAR* path) | |
| { | |
| GUID guid = { | |
| 0xf679f562, | |
| 0x3164, | |
| 0x42ce, | |
| { 0xa4, 0xdb, 0xe7, 0xdd, 0xbe, 0x72, 0x39, 0x9 } | |
| }; | |
| SP_DEVICE_INTERFACE_DATA device_interface_data = {}; | |
| device_interface_data.cbSize = sizeof(device_interface_data); | |
| auto device_info_set = SetupDiGetClassDevs(&guid, nullptr, nullptr, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); | |
| if (!SetupDiEnumDeviceInterfaces(device_info_set, nullptr, &guid, 0, &device_interface_data)) { | |
| return -1; | |
| } | |
| DWORD size = 0; | |
| SetupDiGetDeviceInterfaceDetail(device_info_set, &device_interface_data, nullptr, 0, &size, nullptr); | |
| auto detail_data_buffer = static_cast<PSP_DEVICE_INTERFACE_DETAIL_DATA>(malloc(size)); | |
| if (detail_data_buffer == NULL) { | |
| return -1; | |
| } | |
| detail_data_buffer->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); | |
| if (!SetupDiGetDeviceInterfaceDetail(device_info_set, &device_interface_data, detail_data_buffer, size, &size, nullptr)) | |
| { | |
| SetupDiDestroyDeviceInfoList(device_info_set); | |
| free(detail_data_buffer); | |
| return -1; | |
| } | |
| memcpy((void*)path, detail_data_buffer->DevicePath, size * sizeof(WCHAR)); | |
| SetupDiDestroyDeviceInfoList(device_info_set); | |
| free(detail_data_buffer); | |
| return size; | |
| }; | |
| Device::Device() | |
| { | |
| this->state = State(); | |
| }; | |
| Device::~Device() | |
| { | |
| if (this->id > -1) { | |
| this->plugout(); | |
| } | |
| }; | |
| bool Device::plugin(int id) | |
| { | |
| if (id < 1 || id > 4) { | |
| return false; | |
| } | |
| if (this->bus.handle == INVALID_HANDLE_VALUE) { | |
| return false; | |
| } | |
| DWORD trasfered = 0; | |
| UCHAR buffer[16] = { | |
| 0x10, 0, 0, 0, | |
| UCHAR((id >> 0) & 0xFF), | |
| UCHAR((id >> 8) & 0xFF), | |
| UCHAR((id >> 16) & 0xFF), | |
| UCHAR((id >> 24) & 0xFF), | |
| 0, 0, 0, 0, | |
| 0, 0, 0, 0 | |
| }; | |
| auto success = DeviceIoControl( | |
| this->bus.handle, | |
| 0x2A4000, | |
| buffer, | |
| _countof(buffer), | |
| nullptr, | |
| 0, | |
| &trasfered, | |
| nullptr | |
| ); | |
| if (success) { | |
| this->id = id; | |
| return true; | |
| } | |
| this->id = -1; | |
| return false; | |
| }; | |
| bool Device::plugout() | |
| { | |
| if (this->id < 1 || this->id > 4) { | |
| return false; | |
| } | |
| if (this->bus.handle == INVALID_HANDLE_VALUE) { | |
| return false; | |
| } | |
| DWORD trasfered = 0; | |
| UCHAR buffer[16] = { | |
| 0x10, 0, 0, 0, | |
| UCHAR((id >> 0) & 0xFF), | |
| UCHAR((id >> 8) & 0xFF), | |
| UCHAR((id >> 16) & 0xFF), | |
| UCHAR((id >> 24) & 0xFF), | |
| 0, 0, 0, 0, | |
| 0, 0, 0, 0 | |
| }; | |
| auto success = DeviceIoControl( | |
| this->bus.handle, | |
| 0x2A4004, | |
| buffer, | |
| _countof(buffer), | |
| nullptr, | |
| 0, | |
| &trasfered, | |
| nullptr | |
| ); | |
| if (success) { | |
| this->id = -1; | |
| return true; | |
| } | |
| return false; | |
| }; | |
| bool Device::send() | |
| { | |
| if (this->id < 1 || this->id > 4) { | |
| return false; | |
| } | |
| if (this->bus.handle == INVALID_HANDLE_VALUE) { | |
| return false; | |
| } | |
| auto to_uchar = [] (bool value[8]) -> UCHAR { | |
| UCHAR uchar = 0; | |
| for (int i = 0; i < 8; ++i) { | |
| uchar |= value[i] << i; | |
| } | |
| return uchar; | |
| }; | |
| bool btn_1[8] = { | |
| this->state.up, this->state.down, this->state.left, this->state.right, | |
| this->state.start, this->state.select, this->state.ls, this->state.rs | |
| }; | |
| bool btn_2[8] = { | |
| this->state.lb, this->state.rb, false, false, | |
| this->state.a, this->state.b, this->state.x, this->state.y | |
| }; | |
| DWORD trasfered = 0; | |
| UCHAR buffer[28] = { | |
| 0x1C, 0, 0, 0, | |
| UCHAR((id >> 0) & 0xFF), | |
| UCHAR((id >> 8) & 0xFF), | |
| UCHAR((id >> 16) & 0xFF), | |
| UCHAR((id >> 24) & 0xFF), | |
| 0x00, | |
| 0x14, | |
| to_uchar(btn_1), | |
| to_uchar(btn_2), | |
| 0, 0, 0, 0, | |
| 0, 0, 0, 0, | |
| 0, 0, 0, 0, | |
| 0, 0, 0, 0 | |
| }; | |
| return DeviceIoControl( | |
| this->bus.handle, | |
| 0x2A400C, | |
| buffer, | |
| _countof(buffer), | |
| nullptr, | |
| 0, | |
| &trasfered, | |
| nullptr | |
| ); | |
| }; | |
| void Device::clear() | |
| { | |
| this->state = State(); | |
| }; | |
| bool Device::is_plugged_in() | |
| { | |
| return this->id >= 1 && this->id <= 4; | |
| }; | |
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #pragma once | |
| #include <iostream> | |
| #include <windows.h> | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <assert.h> | |
| #include <crtdbg.h> | |
| #include <winioctl.h> | |
| #include <INITGUID.H> | |
| #include <Xinput.h> | |
| #include <SetupAPI.h> | |
| #pragma comment (lib, "SetupApi.lib") | |
| namespace Vxbox | |
| { | |
| class Bus | |
| { | |
| public: | |
| HANDLE handle; | |
| public: | |
| Bus(); | |
| public: | |
| HANDLE get_handle(); | |
| int get_path(WCHAR* path); | |
| }; | |
| struct State { | |
| bool up = false; | |
| bool down = false; | |
| bool left = false; | |
| bool right = false; | |
| bool a = false; | |
| bool b = false; | |
| bool x = false; | |
| bool y = false; | |
| bool start = false; | |
| bool select = false; | |
| bool ls = false; | |
| bool rs = false; | |
| bool lb = false; | |
| bool rb = false; | |
| }; | |
| class Device | |
| { | |
| public: | |
| Bus bus; | |
| int id; | |
| State state; | |
| public: | |
| Device(); | |
| ~Device(); | |
| public: | |
| bool plugin(int id); | |
| bool plugout(); | |
| bool send(); | |
| void clear(); | |
| bool is_plugged_in(); | |
| }; | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment