#include "Detector.h" #include "ENESMBusController.h" #include "ENESMBusInterface_SpectrixS40G_Windows.h" #include "LogManager.h" #include "RGBController.h" #include "RGBController_ENESMBus.h" #include #include #include #define DEVBUFSIZE (128 * 1024) #include #include /*----------------------------------------------------------------------*\ | Windows defines "interface" for some reason. Work around this | \*----------------------------------------------------------------------*/ #ifdef interface #undef interface #endif /******************************************************************************************\ * * * Search * * * * Search for an NVMe device matching "XPG SPECTRIX S40G" * * * \******************************************************************************************/ int Search(wchar_t *dev_name) { wchar_t buff[DEVBUFSIZE] = L""; int wchar_count; wchar_count = QueryDosDeviceW(NULL, buff, DEVBUFSIZE); if(wchar_count == 0) { return 0; } for(int i = 0; i < wchar_count; i++) { if(wcsstr(buff + i, L"SCSI#Disk&Ven_NVMe&Prod_XPG_SPECTRIX_S40#")) { wcsncpy(dev_name, buff + i, MAX_PATH); (dev_name)[MAX_PATH - 1] = '\0'; return 1; } i += wcslen(buff + i); } return 0; } /******************************************************************************************\ * * * OpenDevice * * * * Open a handle to the given device path * * * \******************************************************************************************/ HANDLE OpenDevice(wchar_t buff[MAX_PATH]) { wchar_t path[MAX_PATH]; wcscpy(path, L"\\\\?\\"); wcsncat(path, buff, MAX_PATH - 4); for(size_t i = 0; i < MAX_PATH && path[i] != '\0'; i++) { path[i] = tolower(path[i]); } wprintf(L"%s\n", path); HANDLE hDevice = CreateFileW(path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, (LPSECURITY_ATTRIBUTES)0x0, OPEN_EXISTING, 0x0, (HANDLE)0x0); return(hDevice); } /******************************************************************************************\ * * * DetectSpectrixS40GControllers * * * * Detects ENE SMBus controllers on XPG Spectrix S40G NVMe devices * * * * Tests for the existance of a file descriptor matching * * SCSI#Disk&Ven_NVMe&Prod_XPG_SPECTRIX_S40# on Windows machines * * * \******************************************************************************************/ void DetectSpectrixS40GControllers(std::vector& rgb_controllers) { /*-------------------------------------------------------------------------------------------------*\ | https://docs.microsoft.com/en-us/windows-hardware/drivers/install/identifiers-for-scsi-devices | \*-------------------------------------------------------------------------------------------------*/ wchar_t dev_name[MAX_PATH]; if(Search(dev_name)) { HANDLE nvme_fd = OpenDevice(dev_name); if(nvme_fd != INVALID_HANDLE_VALUE) { ENESMBusInterface_SpectrixS40G* interface = new ENESMBusInterface_SpectrixS40G(nvme_fd, dev_name); ENESMBusController* controller = new ENESMBusController(interface, 0x67); RGBController_ENESMBus* rgb_controller = new RGBController_ENESMBus(controller); rgb_controller->name = "XPG Spectrix S40G"; rgb_controller->type = DEVICE_TYPE_STORAGE; rgb_controller->vendor = "XPG"; rgb_controllers.push_back(rgb_controller); } } } /* DetectSpectrixS40GControllers() */ REGISTER_DETECTOR( "XPG Spectrix S40G", DetectSpectrixS40GControllers);