125 lines
3.1 KiB
C++
125 lines
3.1 KiB
C++
#include <windows.h>
|
|
#include <winioctl.h>
|
|
|
|
//functions to get the SCSI ID from a drive letter
|
|
//thanks to Microsoft for making this a nightmare...
|
|
|
|
// begin ntddscsi.h definitions
|
|
|
|
#define IOCTL_SCSI_BASE \
|
|
FILE_DEVICE_CONTROLLER
|
|
|
|
#define IOCTL_SCSI_GET_ADDRESS CTL_CODE \
|
|
( \
|
|
IOCTL_SCSI_BASE, \
|
|
0x0406, \
|
|
METHOD_BUFFERED, \
|
|
FILE_ANY_ACCESS \
|
|
)
|
|
|
|
#define IOCTL_SCSI_GET_INQUIRY_DATA \
|
|
CTL_CODE( \
|
|
IOCTL_SCSI_BASE, \
|
|
0x0403, \
|
|
METHOD_BUFFERED, \
|
|
FILE_ANY_ACCESS \
|
|
)
|
|
|
|
typedef struct _SCSI_ADDRESS {
|
|
ULONG Length;
|
|
UCHAR PortNumber;
|
|
UCHAR PathId;
|
|
UCHAR TargetId;
|
|
UCHAR Lun;
|
|
}SCSI_ADDRESS, *PSCSI_ADDRESS;
|
|
|
|
//
|
|
// Define SCSI information.
|
|
// Used with the IOCTL_SCSI_GET_INQUIRY_DATA IOCTL.
|
|
//
|
|
|
|
typedef struct _SCSI_BUS_DATA {
|
|
UCHAR NumberOfLogicalUnits;
|
|
UCHAR InitiatorBusId;
|
|
ULONG InquiryDataOffset;
|
|
}SCSI_BUS_DATA, *PSCSI_BUS_DATA;
|
|
|
|
//
|
|
// Define SCSI adapter bus information structure..
|
|
// Used with the IOCTL_SCSI_GET_INQUIRY_DATA IOCTL.
|
|
//
|
|
|
|
typedef struct _SCSI_ADAPTER_BUS_INFO {
|
|
UCHAR NumberOfBuses;
|
|
SCSI_BUS_DATA BusData[1];
|
|
} SCSI_ADAPTER_BUS_INFO, *PSCSI_ADAPTER_BUS_INFO;
|
|
|
|
//
|
|
// Define SCSI adapter bus information.
|
|
// Used with the IOCTL_SCSI_GET_INQUIRY_DATA IOCTL.
|
|
//
|
|
|
|
typedef struct _SCSI_INQUIRY_DATA {
|
|
UCHAR PathId;
|
|
UCHAR TargetId;
|
|
UCHAR Lun;
|
|
BOOLEAN DeviceClaimed;
|
|
ULONG InquiryDataLength;
|
|
ULONG NextInquiryDataOffset;
|
|
UCHAR InquiryData[1];
|
|
}SCSI_INQUIRY_DATA, *PSCSI_INQUIRY_DATA;
|
|
|
|
// end ntddscsi.h definitions
|
|
|
|
int getSCSIIDFromDrive(char driveletter, int *host, int *id, int *lun)
|
|
{
|
|
//FUCKO: only works on NT :(
|
|
|
|
SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
|
|
wchar_t tmp[128] = {0};
|
|
wsprintf(tmp,L"\\\\.\\%c:",driveletter);
|
|
HANDLE device = CreateFile(
|
|
tmp,
|
|
0, // no particular access necessary
|
|
// for the IO control we're using
|
|
FILE_SHARE_READ
|
|
| FILE_SHARE_WRITE
|
|
| FILE_SHARE_DELETE,
|
|
0, // no security attrs - ignored anyway
|
|
OPEN_EXISTING,
|
|
0, // no attributes or flags
|
|
0 // no template
|
|
);
|
|
|
|
if( device == INVALID_HANDLE_VALUE ) return 0;
|
|
|
|
SCSI_ADDRESS sa;
|
|
ULONG bytes;
|
|
|
|
BOOL status = DeviceIoControl(
|
|
device,
|
|
IOCTL_SCSI_GET_ADDRESS,
|
|
0, 0, // no input buffer
|
|
&sa, sizeof(sa), // output args
|
|
&bytes, // bytes returned
|
|
0 // ignored
|
|
);
|
|
|
|
if (!status && 50 == GetLastError())
|
|
{
|
|
*host = ((driveletter > 'a') ? (driveletter - 'a') : (driveletter - 'A'));
|
|
*id = 0;
|
|
*lun = 0;
|
|
CloseHandle(device);
|
|
return 1;
|
|
}
|
|
CloseHandle(device);
|
|
|
|
if( !status ) return 0;
|
|
|
|
*host=sa.PortNumber;
|
|
*id=sa.TargetId;
|
|
*lun=sa.Lun;
|
|
return 1;
|
|
}
|