123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- #include <windows.h>
- #include <stddef.h> // for offsetof
- #include <winioctl.h>
- #include <strsafe.h>
- typedef struct {
- USHORT Length;
- UCHAR ScsiStatus;
- UCHAR PathId;
- UCHAR TargetId;
- UCHAR Lun;
- UCHAR CdbLength;
- UCHAR SenseInfoLength;
- UCHAR DataIn;
- ULONG DataTransferLength;
- ULONG TimeOutValue;
- PVOID DataBuffer;
- ULONG SenseInfoOffset;
- UCHAR Cdb[16];
- } SCSI_PASS_THROUGH_DIRECT, *PSCSI_PASS_THROUGH_DIRECT;
- typedef struct {
- SCSI_PASS_THROUGH_DIRECT spt;
- ULONG Filler;
- UCHAR ucSenseBuf[32];
- } SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, *PSCSI_PASS_THROUGH_DIRECT_WITH_BUFFER;
- #define IOCTL_SCSI_BASE 0x00000004
- /*
- * constants for DataIn member of SCSI_PASS_THROUGH* structures
- */
- #define SCSI_IOCTL_DATA_OUT 0
- #define SCSI_IOCTL_DATA_IN 1
- #define SCSI_IOCTL_DATA_UNSPECIFIED 2
- /*
- * Standard IOCTL define
- */
- #define CTL_CODE( DevType, Function, Method, Access ) ( \
- ((DevType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
- )
- #define IOCTL_SCSI_PASS_THROUGH CTL_CODE( IOCTL_SCSI_BASE, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS )
- #define IOCTL_SCSI_MINIPORT CTL_CODE( IOCTL_SCSI_BASE, 0x0402, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS )
- #define IOCTL_SCSI_GET_INQUIRY_DATA CTL_CODE( IOCTL_SCSI_BASE, 0x0403, METHOD_BUFFERED, FILE_ANY_ACCESS)
- #define IOCTL_SCSI_GET_CAPABILITIES CTL_CODE( IOCTL_SCSI_BASE, 0x0404, METHOD_BUFFERED, FILE_ANY_ACCESS)
- #define IOCTL_SCSI_PASS_THROUGH_DIRECT CTL_CODE( IOCTL_SCSI_BASE, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS )
- #define IOCTL_SCSI_GET_ADDRESS CTL_CODE( IOCTL_SCSI_BASE, 0x0406, METHOD_BUFFERED, FILE_ANY_ACCESS
- static bool scsi_inquiry(HANDLE deviceHandle, UCHAR page, UCHAR *inqbuf, size_t &buf_len)
- {
- char buf[2048] = {0};
- BOOL status;
- PSCSI_PASS_THROUGH_DIRECT_WITH_BUFFER pswb;
-
- DWORD length=0, returned=0;
- /*
- * Get the drive inquiry data
- */
- ZeroMemory( &buf, 2048 );
- ZeroMemory( inqbuf, buf_len );
- pswb = (PSCSI_PASS_THROUGH_DIRECT_WITH_BUFFER)buf;
- pswb->spt.Length = sizeof(SCSI_PASS_THROUGH_DIRECT);
- pswb->spt.CdbLength = 6;
- pswb->spt.SenseInfoLength = 32;
- pswb->spt.DataIn = SCSI_IOCTL_DATA_IN;
- pswb->spt.DataTransferLength = buf_len;
- pswb->spt.TimeOutValue = 2;
- pswb->spt.DataBuffer = inqbuf;
- pswb->spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER,ucSenseBuf);
- pswb->spt.Cdb[0] = 0x12;
- pswb->spt.Cdb[1] = 0x1;
- pswb->spt.Cdb[2] = page;
- pswb->spt.Cdb[4] = (UCHAR)buf_len;
- length = sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER);
- status = DeviceIoControl( deviceHandle,
- IOCTL_SCSI_PASS_THROUGH_DIRECT,
- pswb,
- length,
- pswb,
- length,
- &returned,
- NULL );
-
- if (status && returned >3)
- {
- buf_len=returned;
- return true;
- }
- else
- {
- buf_len=0;
- return false;
- }
- }
- static bool AddPagetoXML(HANDLE dev, char *&dest, size_t &destlen, UCHAR page)
- {
- UCHAR buf[256] = {0};
- size_t buflen=255;
- if (scsi_inquiry(dev, page, buf, buflen))
- {
- size_t len = buf[3];
- StringCchCopyNExA(dest, destlen, (char *)buf+4, len, &dest, &destlen, 0);
- return true;
- }
- return false;
- }
- static bool BuildXML(HANDLE dev, char *xml, size_t xmllen)
- {
- *xml=0;
- UCHAR pages[255] = {0};
- size_t pageslen=255;
- if (scsi_inquiry(dev, 0xc0, pages, pageslen) && pageslen>3)
- {
- unsigned char numPages=pages[3];
- if (numPages+4 <= 255)
- {
- for (int i=0;i<numPages;i++)
- {
- if (!AddPagetoXML(dev, xml, xmllen, pages[i+4]))
- return false;
- }
- }
- }
- return true;
- }
- bool ParseSysInfoXML(wchar_t drive_letter, char * xml, int xmllen)
- {
- wchar_t fn[MAX_PATH] = {0};
- StringCchPrintf(fn, MAX_PATH, L"\\\\.\\%c:", drive_letter);
- HANDLE hfile = CreateFileW(fn, GENERIC_WRITE|GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
- if (hfile != INVALID_HANDLE_VALUE)
- {
- bool ret = BuildXML(hfile, xml, xmllen);
- CloseHandle(hfile);
- return ret;
- }
- return false;
- }
|