mirror of
https://github.com/CalcProgrammer1/OpenRGB.git
synced 2026-01-26 07:58:16 -05:00
Initial commit of scsiapi for Windows
This commit is contained in:
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
/*-----------------------------------------*\
|
||||
| SeagateController.h |
|
||||
| |
|
||||
| Definitions for Seagate Firecuda |
|
||||
| External HDD RGB controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 6/15/2023 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <windows.h>
|
||||
#include <fileapi.h>
|
||||
#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
|
||||
);
|
||||
};
|
||||
@@ -1,130 +0,0 @@
|
||||
#include "Detector.h"
|
||||
#include "SeagateController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_Seagate.h"
|
||||
#include <vector>
|
||||
#include <fileapi.h>
|
||||
#include <ntddscsi.h>
|
||||
|
||||
#include "Detector.h"
|
||||
#include "ENESMBusController.h"
|
||||
#include "ENESMBusInterface_SpectrixS40G_Windows.h"
|
||||
#include "LogManager.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_ENESMBus.h"
|
||||
#include <vector>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define DEVBUFSIZE (128 * 1024)
|
||||
#include <windows.h>
|
||||
#include <fileapi.h>
|
||||
|
||||
/*----------------------------------------------------------------------*\
|
||||
| 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);
|
||||
17
OpenRGB.pro
17
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 \
|
||||
|
||||
|
||||
@@ -17,9 +17,10 @@
|
||||
| Platform-specific Includes |
|
||||
\*---------------------------------------------------------*/
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#include <fileapi.h>
|
||||
#include <ntddscsi.h>
|
||||
#include <windows.h>
|
||||
#include "WinIoCtl.h"
|
||||
#else
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
226
scsiapi/scsiapi_windows.c
Normal file
226
scsiapi/scsiapi_windows.c
Normal file
@@ -0,0 +1,226 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| scsiapi.c |
|
||||
| |
|
||||
| Cross-platform SCSI access library |
|
||||
| |
|
||||
| Adam Honse <calcprogrammer1@gmail.com> 7/28/2023 |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Includes |
|
||||
\*---------------------------------------------------------*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#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
|
||||
Reference in New Issue
Block a user