diff --git a/Controllers/ENESMBusController/XPGSpectrixS40GDetect_Windows.cpp b/Controllers/ENESMBusController/XPGSpectrixS40GDetect_Windows.cpp index 072d52a4f..f8972e641 100644 --- a/Controllers/ENESMBusController/XPGSpectrixS40GDetect_Windows.cpp +++ b/Controllers/ENESMBusController/XPGSpectrixS40GDetect_Windows.cpp @@ -27,7 +27,7 @@ * * \******************************************************************************************/ -int Search(wchar_t *dev_name) +static int Search(wchar_t *dev_name) { wchar_t buff[DEVBUFSIZE] = L""; int wchar_count; @@ -62,7 +62,7 @@ int Search(wchar_t *dev_name) * * \******************************************************************************************/ -HANDLE OpenDevice(wchar_t buff[MAX_PATH]) +static HANDLE OpenDevice(wchar_t buff[MAX_PATH]) { wchar_t path[MAX_PATH]; diff --git a/Controllers/SeagateController/RGBController_Seagate.cpp b/Controllers/SeagateController/RGBController_Seagate.cpp new file mode 100644 index 000000000..6040b9551 --- /dev/null +++ b/Controllers/SeagateController/RGBController_Seagate.cpp @@ -0,0 +1,94 @@ +/*-----------------------------------------*\ +| RGBController_Seagate.cpp | +| | +| Generic RGB Interface for Seagate | +| | +| Adam Honse (CalcProgrammer1) 11/8/2022 | +\*-----------------------------------------*/ + +#include "RGBController_Seagate.h" + +/**------------------------------------------------------------------*\ + @name Seagate + @category Storage + @type USB + @save :x: + @direct :x: + @effects :x: + @detectors DetectSeagateControllers + @comment +\*-------------------------------------------------------------------*/ + +RGBController_Seagate::RGBController_Seagate(SeagateController* controller_ptr) +{ + controller = controller_ptr; + + name = "Seagate"; + type = DEVICE_TYPE_STORAGE; + description = "Seagate Device"; + location = controller->GetLocation(); + + mode Direct; + Direct.name = "Direct"; + Direct.value = 0; + Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR; + Direct.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Direct); + + SetupZones(); +} + +RGBController_Seagate::~RGBController_Seagate() +{ + delete controller; +} + +void RGBController_Seagate::SetupZones() +{ + zone led_zone; + led_zone.name = "RGB Light"; + led_zone.type = ZONE_TYPE_SINGLE; + led_zone.leds_min = 1; + led_zone.leds_max = 1; + led_zone.leds_count = 1; + led_zone.matrix_map = NULL; + zones.push_back(led_zone); + + led new_led; + new_led.name = "RGB Light"; + + leds.push_back(new_led); + + SetupColors(); +} + +void RGBController_Seagate::ResizeZone(int /*zone*/, int /*new_size*/) +{ + /*---------------------------------------------------------*\ + | This device does not support resizing zones | + \*---------------------------------------------------------*/ +} + +void RGBController_Seagate::DeviceUpdateLEDs() +{ + unsigned char red = RGBGetRValue(colors[0]); + unsigned char grn = RGBGetGValue(colors[0]); + unsigned char blu = RGBGetBValue(colors[0]); + + //controller->SetRGB(red, grn, blu); +} + +void RGBController_Seagate::UpdateZoneLEDs(int /*zone*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_Seagate::UpdateSingleLED(int /*led*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_Seagate::DeviceUpdateMode() +{ + +} diff --git a/Controllers/SeagateController/RGBController_Seagate.h b/Controllers/SeagateController/RGBController_Seagate.h new file mode 100644 index 000000000..475ef1cda --- /dev/null +++ b/Controllers/SeagateController/RGBController_Seagate.h @@ -0,0 +1,31 @@ +/*-----------------------------------------*\ +| RGBController_Seagate.h | +| | +| Generic RGB Interface for Seagate | +| | +| Adam Honse (CalcProgrammer1) 11/8/2022 | +\*-----------------------------------------*/ + +#pragma once +#include "RGBController.h" +#include "SeagateController.h" + +class RGBController_Seagate : public RGBController +{ +public: + RGBController_Seagate(SeagateController* controller_ptr); + ~RGBController_Seagate(); + + void SetupZones(); + + void ResizeZone(int zone, int new_size); + + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void DeviceUpdateMode(); + +private: + SeagateController* controller; +}; diff --git a/Controllers/SeagateController/SeagateController.cpp b/Controllers/SeagateController/SeagateController.cpp new file mode 100644 index 000000000..5a368dbf3 --- /dev/null +++ b/Controllers/SeagateController/SeagateController.cpp @@ -0,0 +1,87 @@ +/*-----------------------------------------*\ +| SeagateController.cpp | +| | +| Code for Seagate Firecuda External HDD | +| RGB controller | +| | +| Adam Honse (CalcProgrammer1) 6/15/2023 | +\*-----------------------------------------*/ + +#include "SeagateController.h" + +#include "WinIoCtl.h" +#include "ntddscsi.h" + +SeagateController::SeagateController(HANDLE fd, wchar_t* path) +{ + this->nvme_fd = fd; + this->path = path; + + /*-----------------------------------------------------------------------------*\ + | Create buffer to hold STORAGE_PROTOCOL_COMMAND | + | Size must be enough for the STORAGE_PROTOCOL_COMMAND struct plus the command | + | data. Subtract sizeof(DWORD) as the Command field in the structure overlaps | + | the actual command data. | + \*-----------------------------------------------------------------------------*/ + unsigned char data[14] = {0}; + unsigned char buffer[80] = {0}; + + data[0] = 0x0E; + data[1] = 0x00; + data[2] = 0x01; + data[3] = 0x09; + data[4] = 0x01; + data[5] = 0x06; + data[6] = 0x00; + data[7] = 0x01; + data[8] = 0x03; + data[9] = 0x00; + data[10] = 0x15; + data[11] = 0xFF; + data[12] = 0x00; + data[13] = 0xFF; + + /*-----------------------------------------------------------------------------*\ + | Create STORAGE_PROTOCOL_COMMAND pointer and point it to the buffer | + \*-----------------------------------------------------------------------------*/ + PSCSI_PASS_THROUGH_DIRECT command = (PSCSI_PASS_THROUGH_DIRECT)buffer; + + command->Length = sizeof(SCSI_PASS_THROUGH_DIRECT); + command->ScsiStatus = 0x00; + command->PathId = 0x00; + command->TargetId = 0x00; + command->Lun = 0x00; + command->CdbLength = 0x0C; + command->SenseInfoLength = 0x20; + command->DataIn = SCSI_IOCTL_DATA_OUT; + command->DataTransferLength = 0x0000000E; + command->TimeOutValue = 0x00000014; + command->DataBuffer = &data; + command->SenseInfoOffset = 0x0000002E; + + command->Cdb[0] = 0xD2; + command->Cdb[1] = 0x53; + command->Cdb[2] = 0x65; + command->Cdb[3] = 0x74; + command->Cdb[4] = 0x4C; + command->Cdb[5] = 0x65; + command->Cdb[6] = 0x64; + command->Cdb[7] = 0x00; + command->Cdb[8] = 0x00; + command->Cdb[9] = 0x30; + command->Cdb[10] = 0x0E; + command->Cdb[11] = 0x00; + + DeviceIoControl(nvme_fd, IOCTL_SCSI_PASS_THROUGH_DIRECT, command, 80, command, 80, NULL, NULL); +} + +SeagateController::~SeagateController() +{ + +} + +std::string SeagateController::GetLocation() +{ + std::string str(path.begin(), path.end()); + return("SCSI: " + str); +} diff --git a/Controllers/SeagateController/SeagateController.h b/Controllers/SeagateController/SeagateController.h new file mode 100644 index 000000000..9d7d93a23 --- /dev/null +++ b/Controllers/SeagateController/SeagateController.h @@ -0,0 +1,29 @@ +/*-----------------------------------------*\ +| SeagateController.h | +| | +| Definitions for Seagate Firecuda | +| External HDD RGB controller | +| | +| Adam Honse (CalcProgrammer1) 6/15/2023 | +\*-----------------------------------------*/ + +#pragma once + +#include +#include +#include +#include "ntddscsi.h" + +class SeagateController +{ +public: + SeagateController(HANDLE fd, wchar_t* path); + ~SeagateController(); + + std::string GetLocation(); + +private: + HANDLE nvme_fd; + std::wstring path; + int a; +}; diff --git a/Controllers/SeagateController/SeagateControllerDetect.cpp b/Controllers/SeagateController/SeagateControllerDetect.cpp new file mode 100644 index 000000000..2d5d16163 --- /dev/null +++ b/Controllers/SeagateController/SeagateControllerDetect.cpp @@ -0,0 +1,130 @@ +#include "Detector.h" +#include "SeagateController.h" +#include "RGBController.h" +#include "RGBController_Seagate.h" +#include +#include +#include + +#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" * +* * +\******************************************************************************************/ + +static int Search(wchar_t *dev_name) +{ + wchar_t buff[DEVBUFSIZE] = L""; + int wchar_count; + + wchar_count = QueryDosDeviceW(NULL, buff, DEVBUFSIZE); + + for(int i = 0; i < wchar_count; i++) + { + buff[i] = towupper(buff[i]); + } + + if(wchar_count == 0) + { + return 0; + } + + for(int i = 0; i < wchar_count; i++) + { + wchar_t * buf_ptr = buff + i; + if(wcsstr(buf_ptr, L"SCSI#DISK&VEN_SEAGATE&PROD_FIRECUDA_HDD")) + { + 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 * +* * +\******************************************************************************************/ + +static 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); +} + +/******************************************************************************************\ +* * +* DetectSeagateControllers * +* * +* 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 DetectSeagateControllers(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 fd = OpenDevice(dev_name); + + if(fd != INVALID_HANDLE_VALUE) + { + SeagateController* controller = new SeagateController(fd, dev_name); + RGBController_Seagate* rgb_controller = new RGBController_Seagate(controller); + + rgb_controllers.push_back(rgb_controller); + } + } +} /* DetectSpectrixS40GControllers() */ + +REGISTER_DETECTOR( "Seagate Firecuda HDD", DetectSeagateControllers); diff --git a/OpenRGB.pro b/OpenRGB.pro index 03c27156e..cbbf4d598 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -206,6 +206,7 @@ INCLUDEPATH += Controllers/RedSquareKeyroxController/ \ Controllers/RoccatController/ \ Controllers/SapphireGPUController/ \ + Controllers/SeagateController/ \ Controllers/SinowealthController/ \ Controllers/SonyGamepadController/ \ Controllers/SRGBmodsController/ \ @@ -688,6 +689,8 @@ HEADERS += Controllers/SapphireGPUController/SapphireNitroGlowV3Controller.h \ Controllers/SapphireGPUController/RGBController_SapphireNitroGlowV1.h \ Controllers/SapphireGPUController/RGBController_SapphireNitroGlowV3.h \ + Controllers/SeagateController/SeagateController.h \ + Controllers/SeagateController/RGBController_Seagate.h \ Controllers/SinowealthController/SinowealthController.h \ Controllers/SinowealthController/SinowealthController1007.h \ Controllers/SinowealthController/SinowealthGMOWController.h \ @@ -1377,6 +1380,9 @@ SOURCES += Controllers/SapphireGPUController/SapphireGPUControllerDetect.cpp \ Controllers/SapphireGPUController/RGBController_SapphireNitroGlowV1.cpp \ Controllers/SapphireGPUController/RGBController_SapphireNitroGlowV3.cpp \ + Controllers/SeagateController/SeagateController.cpp \ + Controllers/SeagateController/SeagateControllerDetect.cpp \ + Controllers/SeagateController/RGBController_Seagate.cpp \ Controllers/SinowealthController/SinowealthController.cpp \ Controllers/SinowealthController/SinowealthController1007.cpp \ Controllers/SinowealthController/SinowealthGMOWController.cpp \