From afb08f736cd0e5fb35d63af6b46a1a24552b4824 Mon Sep 17 00:00:00 2001 From: Adam Honse Date: Sat, 29 Jul 2023 03:25:37 -0500 Subject: [PATCH] Initial commit of scsiapi for Windows --- .../SeagateController.cpp | 130 +++++----- .../SeagateController.h | 0 .../SeagateControllerDetect.cpp | 9 +- .../SeagateController.cpp | 121 ---------- .../SeagateController.h | 43 ---- .../SeagateControllerDetect.cpp | 130 ---------- OpenRGB.pro | 17 +- scsiapi/scsiapi.h | 3 +- scsiapi/scsiapi_windows.c | 226 ++++++++++++++++++ 9 files changed, 305 insertions(+), 374 deletions(-) rename Controllers/SeagateController/{SeagateControllerLinux => }/SeagateController.cpp (97%) rename Controllers/SeagateController/{SeagateControllerLinux => }/SeagateController.h (100%) rename Controllers/SeagateController/{SeagateControllerLinux => }/SeagateControllerDetect.cpp (73%) delete mode 100644 Controllers/SeagateController/SeagateControllerWindows/SeagateController.cpp delete mode 100644 Controllers/SeagateController/SeagateControllerWindows/SeagateController.h delete mode 100644 Controllers/SeagateController/SeagateControllerWindows/SeagateControllerDetect.cpp create mode 100644 scsiapi/scsiapi_windows.c diff --git a/Controllers/SeagateController/SeagateControllerLinux/SeagateController.cpp b/Controllers/SeagateController/SeagateController.cpp similarity index 97% rename from Controllers/SeagateController/SeagateControllerLinux/SeagateController.cpp rename to Controllers/SeagateController/SeagateController.cpp index 96c9ff68d..4a3acb3e6 100644 --- a/Controllers/SeagateController/SeagateControllerLinux/SeagateController.cpp +++ b/Controllers/SeagateController/SeagateController.cpp @@ -1,65 +1,65 @@ -/*-----------------------------------------*\ -| SeagateController.cpp | -| | -| Code for Seagate Firecuda External HDD | -| RGB controller | -| | -| Adam Honse (CalcProgrammer1) 6/15/2023 | -\*-----------------------------------------*/ - -#include "SeagateController.h" - -SeagateController::SeagateController(scsi_device* dev_handle, char* path) -{ - this->dev = dev_handle; - this->path = path; -} - -SeagateController::~SeagateController() -{ - scsi_close(dev); -} - -std::string SeagateController::GetLocation() -{ - std::string str(path.begin(), path.end()); - return("SCSI: " + str); -} - -void SeagateController::SetLED - ( - unsigned char led_id, - unsigned char r, - unsigned char g, - unsigned char b, - bool save - ) -{ - /*-----------------------------------------------------------------------------*\ - | Create buffer to hold RGB control data | - \*-----------------------------------------------------------------------------*/ - unsigned char data[14] = {0}; - data[0] = 0x0E; // size of data packet - data[1] = 0x00; - data[2] = 0x01; - data[3] = 0x09; - data[4] = 0x01; - data[5] = 0x06; - data[6] = led_id; - data[7] = 0x01; - if(save) - { - data[8] = 0x03; // 0x00 for no save, 0x03 for save - } - else - { - data[8] = 0x00; - } - data[9] = r; - data[10] = g; - data[11] = b; - data[12] = 0xFF; - data[13] = 0xFF; - - scsi_write(dev, data, 14); -} +/*-----------------------------------------*\ +| SeagateController.cpp | +| | +| Code for Seagate Firecuda External HDD | +| RGB controller | +| | +| Adam Honse (CalcProgrammer1) 6/15/2023 | +\*-----------------------------------------*/ + +#include "SeagateController.h" + +SeagateController::SeagateController(scsi_device* dev_handle, char* path) +{ + this->dev = dev_handle; + this->path = path; +} + +SeagateController::~SeagateController() +{ + scsi_close(dev); +} + +std::string SeagateController::GetLocation() +{ + std::string str(path.begin(), path.end()); + return("SCSI: " + str); +} + +void SeagateController::SetLED + ( + unsigned char led_id, + unsigned char r, + unsigned char g, + unsigned char b, + bool save + ) +{ + /*-----------------------------------------------------------------------------*\ + | Create buffer to hold RGB control data | + \*-----------------------------------------------------------------------------*/ + unsigned char data[14] = {0}; + data[0] = 0x0E; // size of data packet + data[1] = 0x00; + data[2] = 0x01; + data[3] = 0x09; + data[4] = 0x01; + data[5] = 0x06; + data[6] = led_id; + data[7] = 0x01; + if(save) + { + data[8] = 0x03; // 0x00 for no save, 0x03 for save + } + else + { + data[8] = 0x00; + } + data[9] = r; + data[10] = g; + data[11] = b; + data[12] = 0xFF; + data[13] = 0xFF; + + scsi_write(dev, data, 14); +} diff --git a/Controllers/SeagateController/SeagateControllerLinux/SeagateController.h b/Controllers/SeagateController/SeagateController.h similarity index 100% rename from Controllers/SeagateController/SeagateControllerLinux/SeagateController.h rename to Controllers/SeagateController/SeagateController.h diff --git a/Controllers/SeagateController/SeagateControllerLinux/SeagateControllerDetect.cpp b/Controllers/SeagateController/SeagateControllerDetect.cpp similarity index 73% rename from Controllers/SeagateController/SeagateControllerLinux/SeagateControllerDetect.cpp rename to Controllers/SeagateController/SeagateControllerDetect.cpp index 08337485d..38f98fe73 100644 --- a/Controllers/SeagateController/SeagateControllerLinux/SeagateControllerDetect.cpp +++ b/Controllers/SeagateController/SeagateControllerDetect.cpp @@ -11,10 +11,7 @@ * * * 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 * +* Detects Seagate FireCuda HDD devices * * * \******************************************************************************************/ @@ -38,6 +35,6 @@ void DetectSeagateControllers() scsi_free_enumeration(info); -} /* DetectSpectrixS40GControllers() */ +} /* DetectSeagateControllers() */ -REGISTER_DETECTOR( "Seagate Firecuda HDD", DetectSeagateControllers); +REGISTER_DETECTOR("Seagate Firecuda HDD", DetectSeagateControllers); diff --git a/Controllers/SeagateController/SeagateControllerWindows/SeagateController.cpp b/Controllers/SeagateController/SeagateControllerWindows/SeagateController.cpp deleted file mode 100644 index 7bfa2471c..000000000 --- a/Controllers/SeagateController/SeagateControllerWindows/SeagateController.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/*-----------------------------------------*\ -| 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->fd = fd; - this->path = path; -} - -SeagateController::~SeagateController() -{ - -} - -std::string SeagateController::GetLocation() -{ - std::string str(path.begin(), path.end()); - return("SCSI: " + str); -} - -void SeagateController::SetLED - ( - unsigned char led_id, - unsigned char r, - unsigned char g, - unsigned char b, - bool save - ) -{ - /*-----------------------------------------------------------------------------*\ - | Create buffer to hold RGB control data | - \*-----------------------------------------------------------------------------*/ - unsigned char data[14] = {0}; - data[0] = 0x0E; // size of data packet - data[1] = 0x00; - data[2] = 0x01; - data[3] = 0x09; - data[4] = 0x01; - data[5] = 0x06; - data[6] = led_id; - data[7] = 0x01; - if(save) - { - data[8] = 0x03; // 0x00 for no save, 0x03 for save - } - else - { - data[8] = 0x00; - } - data[9] = r; - data[10] = g; - data[11] = b; - data[12] = 0xFF; - data[13] = 0xFF; - - SendPacket(data, 14); -} - -void SeagateController::SendPacket - ( - void * packet, - unsigned char packet_sz - ) -{ - /*-----------------------------------------------------------------------------*\ - | Create buffer to hold SCSI_PASS_THROUGH_DIRECT | - | Size must be enough for the SCSI_PASS_THROUGH_DIRECT struct plus the sense | - | data. Size of 80 bytes taken from captured data | - \*-----------------------------------------------------------------------------*/ - unsigned char buffer[sizeof(SCSI_PASS_THROUGH_DIRECT) + 32] = {0}; - - /*-----------------------------------------------------------------------------*\ - | Create PSCSI_PASS_THROUGH_DIRECT pointer and point it to the buffer | - \*-----------------------------------------------------------------------------*/ - PSCSI_PASS_THROUGH_DIRECT command = (PSCSI_PASS_THROUGH_DIRECT)buffer; - - /*-----------------------------------------------------------------------------*\ - | Set up pass through command | - \*-----------------------------------------------------------------------------*/ - 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 = packet_sz; - command->TimeOutValue = 0x00000014; - command->DataBuffer = packet; - command->SenseInfoOffset = sizeof(SCSI_PASS_THROUGH_DIRECT); - - 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] = packet_sz; - command->Cdb[11] = 0x00; - - /*-----------------------------------------------------------------------------*\ - | Send pass through command | - \*-----------------------------------------------------------------------------*/ - DeviceIoControl(fd, IOCTL_SCSI_PASS_THROUGH_DIRECT, command, sizeof(buffer), command, sizeof(buffer), NULL, NULL); -} diff --git a/Controllers/SeagateController/SeagateControllerWindows/SeagateController.h b/Controllers/SeagateController/SeagateControllerWindows/SeagateController.h deleted file mode 100644 index 1753b329b..000000000 --- a/Controllers/SeagateController/SeagateControllerWindows/SeagateController.h +++ /dev/null @@ -1,43 +0,0 @@ -/*-----------------------------------------*\ -| 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(); - - void SetLED - ( - unsigned char led_id, - unsigned char r, - unsigned char g, - unsigned char b, - bool save - ); - -private: - HANDLE fd; - std::wstring path; - - void SeagateController::SendPacket - ( - void * packet, - unsigned char packet_sz - ); -}; diff --git a/Controllers/SeagateController/SeagateControllerWindows/SeagateControllerDetect.cpp b/Controllers/SeagateController/SeagateControllerWindows/SeagateControllerDetect.cpp deleted file mode 100644 index 62d2d8f57..000000000 --- a/Controllers/SeagateController/SeagateControllerWindows/SeagateControllerDetect.cpp +++ /dev/null @@ -1,130 +0,0 @@ -#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() -{ - /*-------------------------------------------------------------------------------------------------*\ - | 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); - - ResourceManager::get()->RegisterRGBController(rgb_controller); - } - } -} /* DetectSpectrixS40GControllers() */ - -REGISTER_DETECTOR( "Seagate Firecuda HDD", DetectSeagateControllers); diff --git a/OpenRGB.pro b/OpenRGB.pro index 14f2248bc..20668f2f8 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -1567,7 +1567,7 @@ win32:INCLUDEPATH += Controllers/AsusTUFLaptopController \ Controllers/NVIDIAIlluminationController \ Controllers/SeagateController/ \ - Controllers/SeagateController/SeagateControllerWindows \ + scsiapi/ \ win32:SOURCES += \ # dependencies/hidapi/hidapi.c \ @@ -1676,9 +1676,10 @@ win32:SOURCES += Controllers/NVIDIAIlluminationController/RGBController_NVIDIAIllumination.cpp \ Controllers/OpenRazerController/OpenRazerWindowsDetect.cpp \ Controllers/OpenRazerController/RGBController_OpenRazerWindows.cpp \ - Controllers/SeagateController/SeagateControllerWindows/SeagateController.cpp \ - Controllers/SeagateController/SeagateControllerWindows/SeagateControllerDetect.cpp \ + Controllers/SeagateController/SeagateController.cpp \ + Controllers/SeagateController/SeagateControllerDetect.cpp \ Controllers/SeagateController/RGBController_Seagate.cpp \ + scsiapi/scsiapi_windows.c \ win32:HEADERS += \ dependencies/display-library/include/adl_defines.h \ @@ -1699,8 +1700,9 @@ win32:HEADERS += Controllers/NVIDIAIlluminationController/NVIDIAIlluminationV1Controller.h \ Controllers/NVIDIAIlluminationController/RGBController_NVIDIAIllumination.h \ Controllers/OpenRazerController/RGBController_OpenRazerWindows.h \ - Controllers/SeagateController/SeagateControllerWindows/SeagateController.h \ + Controllers/SeagateController/SeagateController.h \ Controllers/SeagateController/RGBController_Seagate.h \ + scsiapi\scsiapi.h \ win32:contains(QMAKE_TARGET.arch, x86_64) { LIBS += \ @@ -1790,7 +1792,6 @@ contains(QMAKE_PLATFORM, linux) { Controllers/FaustusController \ Controllers/LinuxLEDController \ Controllers/SeagateController/ \ - Controllers/SeagateController/SeagateControllerLinux/ \ scsiapi/ \ HEADERS += \ @@ -1803,7 +1804,7 @@ contains(QMAKE_PLATFORM, linux) { Controllers/LinuxLEDController/LinuxLEDController.h \ Controllers/LinuxLEDController/RGBController_LinuxLED.h \ Controllers/OpenRazerController/RGBController_OpenRazer.h \ - Controllers/SeagateController/SeagateControllerLinux/SeagateController.h \ + Controllers/SeagateController/SeagateController.h \ Controllers/SeagateController/RGBController_Seagate.h \ scsiapi/scsiapi.h \ @@ -1860,8 +1861,8 @@ contains(QMAKE_PLATFORM, linux) { Controllers/LinuxLEDController/RGBController_LinuxLED.cpp \ Controllers/OpenRazerController/OpenRazerDetect.cpp \ Controllers/OpenRazerController/RGBController_OpenRazer.cpp \ - Controllers/SeagateController/SeagateControllerLinux/SeagateController.cpp \ - Controllers/SeagateController/SeagateControllerLinux/SeagateControllerDetect.cpp \ + Controllers/SeagateController/SeagateController.cpp \ + Controllers/SeagateController/SeagateControllerDetect.cpp \ Controllers/SeagateController/RGBController_Seagate.cpp \ scsiapi/scsiapi.c \ diff --git a/scsiapi/scsiapi.h b/scsiapi/scsiapi.h index da0748557..7542c4c19 100644 --- a/scsiapi/scsiapi.h +++ b/scsiapi/scsiapi.h @@ -17,9 +17,10 @@ | Platform-specific Includes | \*---------------------------------------------------------*/ #ifdef WIN32 +#include #include #include -#include +#include "WinIoCtl.h" #else #include #include diff --git a/scsiapi/scsiapi_windows.c b/scsiapi/scsiapi_windows.c new file mode 100644 index 000000000..e22e4bbce --- /dev/null +++ b/scsiapi/scsiapi_windows.c @@ -0,0 +1,226 @@ +/*---------------------------------------------------------*\ +| scsiapi.c | +| | +| Cross-platform SCSI access library | +| | +| Adam Honse 7/28/2023 | +\*---------------------------------------------------------*/ + +#pragma once + +/*---------------------------------------------------------*\ +| Includes | +\*---------------------------------------------------------*/ +#include +#include +#include + +#include "scsiapi.h" + +#define DEVBUFSIZE (128 * 1024) + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------*\ +| Functions | +\*---------------------------------------------------------*/ + +void scsi_close(struct scsi_device * dev) +{ + +} + +struct scsi_device_info * scsi_enumerate(const char * vendor, const char * product) +{ + struct scsi_device_info * ret_ptr = NULL; + struct scsi_device_info * last_ptr = NULL; + + char buff[DEVBUFSIZE] = ""; + int char_count; + + /*-----------------------------------------------------*\ + | Query all devices and look for SCSI devices | + \*-----------------------------------------------------*/ + char_count = QueryDosDevice(NULL, buff, DEVBUFSIZE); + + if(char_count == 0) + { + return 0; + } + + for(int i = 0; i < char_count; i++) + { + char * buf_ptr = buff + i; + + if(strstr(buf_ptr, "SCSI")) + { + /*---------------------------------------------*\ + | Extract vendor and product from SCSI path | + | Format: SCSI#Disk&Ven_VENDOR&Prod_PRODUCT#... | + \*---------------------------------------------*/ + char c_vendor[512]; + char c_product[512]; + char c_path[MAX_PATH]; + + sscanf(buf_ptr, "SCSI#Disk&Ven_%[^&]&Prod_%[^#]#", c_vendor, c_product); + + strcpy(c_path, "\\\\?\\"); + strncat(c_path, buf_ptr, MAX_PATH - 4); + + /*---------------------------------------------*\ + | Windows converts spaces to underscores so | + | undo that | + | There may be a better way to do this... | + \*---------------------------------------------*/ + for(int pos = 0; pos < strlen(c_vendor); pos++) + { + if(c_vendor[pos] == '_') + { + c_vendor[pos] = ' '; + } + } + + for(int pos = 0; pos < strlen(c_product); pos++) + { + if(c_product[pos] == '_') + { + c_product[pos] = ' '; + } + } + + /*---------------------------------------------*\ + | Check if this SCSI device should be added to | + | the list | + \*---------------------------------------------*/ + int add_to_list = 0; + + if(vendor == NULL || product == NULL) + { + add_to_list = 1; + } + else if(strncmp(c_product, product, strlen(product)) == 0) + { + if(strncmp(c_vendor, vendor, strlen(vendor)) == 0) + { + add_to_list = 1; + } + } + + /*---------------------------------------------*\ + | Create new scsi_device_info if adding to list | + \*---------------------------------------------*/ + if(add_to_list == 1) + { + struct scsi_device_info * info = malloc(sizeof(struct scsi_device_info)); + + info->path = malloc(strlen(c_path) + 1); + strcpy(info->path, c_path); + + info->vendor = malloc(strlen(c_vendor) + 1); + strcpy(info->vendor, c_vendor); + + info->product = malloc(strlen(c_product) + 1); + strcpy(info->product, c_product); + + info->next = NULL; + + if(ret_ptr == NULL) + { + ret_ptr = info; + } + else + { + last_ptr->next = info; + } + + last_ptr = info; + } + } + + i += strlen(buff + i); + } + + return(ret_ptr); +} + +void scsi_free_enumeration(struct scsi_device_info * devs) +{ + struct scsi_device_info * dev = devs; + + while(dev) + { + struct scsi_device_info * next = dev->next; + + free(dev->path); + free(dev->vendor); + free(dev->product); + free(dev); + + dev = next; + } +} + +struct scsi_device * scsi_open_path(const char *path) +{ + struct scsi_device * device = malloc(sizeof(struct scsi_device)); + + device->fd = CreateFile(path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, (LPSECURITY_ATTRIBUTES)0x0, OPEN_EXISTING, 0x0, (HANDLE)0x0); + + return(device); +} + +int scsi_write(struct scsi_device * dev, const unsigned char * data, size_t length) +{ + /*-----------------------------------------------------*\ + | Create buffer to hold SCSI_PASS_THROUGH_DIRECT | + | Size must be enough for the SCSI_PASS_THROUGH_DIRECT | + | struct plus the sense data. Size of 80 bytes taken | + | from captured data | + \*-----------------------------------------------------*/ + unsigned char buffer[sizeof(SCSI_PASS_THROUGH_DIRECT) + 32] = {0}; + + /*-----------------------------------------------------*\ + | Create PSCSI_PASS_THROUGH_DIRECT pointer and point it | + | to the buffer | + \*-----------------------------------------------------*/ + PSCSI_PASS_THROUGH_DIRECT command = (PSCSI_PASS_THROUGH_DIRECT)buffer; + + /*-----------------------------------------------------*\ + | Set up pass through command | + \*-----------------------------------------------------*/ + 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 = length; + command->TimeOutValue = 0x00000014; + command->DataBuffer = data; + command->SenseInfoOffset = sizeof(SCSI_PASS_THROUGH_DIRECT); + + 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] = length; + command->Cdb[11] = 0x00; + + /*-----------------------------------------------------*\ + | Send pass through command | + \*-----------------------------------------------------*/ + DeviceIoControl(dev->fd, IOCTL_SCSI_PASS_THROUGH_DIRECT, command, sizeof(buffer), command, sizeof(buffer), NULL, NULL); +} +#ifdef __cplusplus +} +#endif