scsi_id.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #include <windows.h>
  2. #include <winioctl.h>
  3. //functions to get the SCSI ID from a drive letter
  4. //thanks to Microsoft for making this a nightmare...
  5. // begin ntddscsi.h definitions
  6. #define IOCTL_SCSI_BASE \
  7. FILE_DEVICE_CONTROLLER
  8. #define IOCTL_SCSI_GET_ADDRESS CTL_CODE \
  9. ( \
  10. IOCTL_SCSI_BASE, \
  11. 0x0406, \
  12. METHOD_BUFFERED, \
  13. FILE_ANY_ACCESS \
  14. )
  15. #define IOCTL_SCSI_GET_INQUIRY_DATA \
  16. CTL_CODE( \
  17. IOCTL_SCSI_BASE, \
  18. 0x0403, \
  19. METHOD_BUFFERED, \
  20. FILE_ANY_ACCESS \
  21. )
  22. typedef struct _SCSI_ADDRESS {
  23. ULONG Length;
  24. UCHAR PortNumber;
  25. UCHAR PathId;
  26. UCHAR TargetId;
  27. UCHAR Lun;
  28. }SCSI_ADDRESS, *PSCSI_ADDRESS;
  29. //
  30. // Define SCSI information.
  31. // Used with the IOCTL_SCSI_GET_INQUIRY_DATA IOCTL.
  32. //
  33. typedef struct _SCSI_BUS_DATA {
  34. UCHAR NumberOfLogicalUnits;
  35. UCHAR InitiatorBusId;
  36. ULONG InquiryDataOffset;
  37. }SCSI_BUS_DATA, *PSCSI_BUS_DATA;
  38. //
  39. // Define SCSI adapter bus information structure..
  40. // Used with the IOCTL_SCSI_GET_INQUIRY_DATA IOCTL.
  41. //
  42. typedef struct _SCSI_ADAPTER_BUS_INFO {
  43. UCHAR NumberOfBuses;
  44. SCSI_BUS_DATA BusData[1];
  45. } SCSI_ADAPTER_BUS_INFO, *PSCSI_ADAPTER_BUS_INFO;
  46. //
  47. // Define SCSI adapter bus information.
  48. // Used with the IOCTL_SCSI_GET_INQUIRY_DATA IOCTL.
  49. //
  50. typedef struct _SCSI_INQUIRY_DATA {
  51. UCHAR PathId;
  52. UCHAR TargetId;
  53. UCHAR Lun;
  54. BOOLEAN DeviceClaimed;
  55. ULONG InquiryDataLength;
  56. ULONG NextInquiryDataOffset;
  57. UCHAR InquiryData[1];
  58. }SCSI_INQUIRY_DATA, *PSCSI_INQUIRY_DATA;
  59. // end ntddscsi.h definitions
  60. int getSCSIIDFromDrive(char driveletter, int *host, int *id, int *lun)
  61. {
  62. //FUCKO: only works on NT :(
  63. SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
  64. wchar_t tmp[128] = {0};
  65. wsprintf(tmp,L"\\\\.\\%c:",driveletter);
  66. HANDLE device = CreateFile(
  67. tmp,
  68. 0, // no particular access necessary
  69. // for the IO control we're using
  70. FILE_SHARE_READ
  71. | FILE_SHARE_WRITE
  72. | FILE_SHARE_DELETE,
  73. 0, // no security attrs - ignored anyway
  74. OPEN_EXISTING,
  75. 0, // no attributes or flags
  76. 0 // no template
  77. );
  78. if( device == INVALID_HANDLE_VALUE ) return 0;
  79. SCSI_ADDRESS sa;
  80. ULONG bytes;
  81. BOOL status = DeviceIoControl(
  82. device,
  83. IOCTL_SCSI_GET_ADDRESS,
  84. 0, 0, // no input buffer
  85. &sa, sizeof(sa), // output args
  86. &bytes, // bytes returned
  87. 0 // ignored
  88. );
  89. if (!status && 50 == GetLastError())
  90. {
  91. *host = ((driveletter > 'a') ? (driveletter - 'a') : (driveletter - 'A'));
  92. *id = 0;
  93. *lun = 0;
  94. CloseHandle(device);
  95. return 1;
  96. }
  97. CloseHandle(device);
  98. if( !status ) return 0;
  99. *host=sa.PortNumber;
  100. *id=sa.TargetId;
  101. *lun=sa.Lun;
  102. return 1;
  103. }