разобрался... сначала надо получить его адрес. вот вроде бы работающий код:
| Код | {$ALIGN ON} type TScsiBusData = record // warning! dword alignment NumberOfLogicalUnits : Byte; InitiatorBusId : Byte; InquiryDataOffset : ULONG; end; SCSI_BUS_DATA = TScsiBusData; PScsiBusData = ^TScsiBusData;
// Define SCSI adapter bus information structure.. TScsiAdapterBusInfo = record // warning! dword alignment NumberOfBuses : Byte; BusData : Array[0..0] of SCSI_BUS_DATA; end; SCSI_ADAPTER_BUS_INFO = TScsiAdapterBusInfo; PScsiAdapterBusInfo = ^TScsiAdapterBusInfo;
TScsiInquiryData = record // warning! dword alignment PathId : Byte; TargetId : Byte; Lun : Byte; DeviceClaimed : Boolean; InquiryDataLength : ULONG; NextInquiryDataOffset : ULONG; InquiryData : Array[0..0] of Byte; end; PScsiInquiryData = ^TScsiInquiryData;
_SCSI_ADDRESS = record Length: ULONG; PortNumber: UCHAR; PathId: UCHAR; TargetId: UCHAR; Lun: UCHAR; end; PScsiAddress = ^TScsiAddress; TScsiAddress = _SCSI_ADDRESS; {$ALIGN OFF} const FILE_DEVICE_CONTROLLER = $00000004; IOCTL_SCSI_BASE = FILE_DEVICE_CONTROLLER; IOCTL_SCSI_GET_INQUIRY_DATA = (IOCTL_SCSI_BASE shl 16) or ($0403 shl 2); IOCTL_SCSI_GET_ADDRESS = (IOCTL_SCSI_BASE shl 16) or ($0406 shl 2);
function GetDeviceName( ADriveLetter: Char; var AName: string ): Boolean; const C_BufSize = 2048; var hDevice : THandle; lScsiAddress: TScsiAddress;
i: Integer; lAdaptBusInfo: PScsiAdapterBusInfo; lInqData: PScsiInquiryData; lSz: DWORD; lBuff: array[0..C_BufSize-1] of Byte; lSrc: Pointer; begin Result := False; AName := ''; hDevice := CreateFile( PChar( '\\.\'+ADriveLetter+':'), GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 ); if hDevice <> INVALID_HANDLE_VALUE then begin try lSz := SizeOf( TScsiAddress ); ZeroMemory( @lScsiAddress, SizeOf( TScsiAddress ) ); lScsiAddress.Length := lSz;
Result := DeviceIoControl( hDevice, IOCTL_SCSI_GET_ADDRESS, nil, 0, @lScsiAddress, lSz, lSz, nil ); if not Result then Exit;
lSz := C_BufSize; ZeroMemory( @lBuff, C_BufSize ); Result := DeviceIoControl( hDevice, IOCTL_SCSI_GET_INQUIRY_DATA, nil, 0, @lBuff, lSz, lSz, nil ); if not Result then Exit; lAdaptBusInfo := @lBuff; Result := lAdaptBusInfo^.NumberOfBuses > 0; if not Result then Exit; lInqData := nil;
Result := False; repeat if lInqData = nil then lInqData := PScsiInquiryData( Integer(lAdaptBusInfo) + lAdaptBusInfo^.BusData[0].InquiryDataOffset ) else lInqData := Pointer(Integer(lAdaptBusInfo) + lInqData^.NextInquiryDataOffset); lSz := lInqData^.InquiryDataLength - 8; if (lInqData^.PathId = lScsiAddress.PathId) and (lInqData^.TargetId = lScsiAddress.TargetId ) and (lInqData^.Lun = lScsiAddress.Lun) and (lSz > 0) then begin SetLength( AName, lSz); lSrc := PChar(@lInqData^.InquiryData[0]) + 8; Move( lSrc^, AName[1], lSz ); Result := True; Break; end; until lInqData^.NextInquiryDataOffset = 0; finally CloseHandle( hDevice ); end; end; end;
|
|