In "Mit Laufwerksbuchstaben SCSI-Adressen ermitteln und Bezeichnung aus der Registry holen" und "Mit Zähler SCSI-Adressen ermitteln und Bezeichnung aus der Registry holen" wurden die SCSI-Adressen mit Hilfe des SCSI Pass Through Interface ermittelt. Da bietet es sich an, die Bezeichnung der Laufwerke ebenfalls darüber zu ermitteln. In Hinblick auf Windows 7 ist dies sinnvoller als wie in den vorigen Beispielen über die Registry.
Unter Windows 2000 und Windows XP müssten Brennrechte erforderlich sein.
Das sieht beispielsweise so aus:
...
var
nBufferLength : Integer;
pDriveBuffer : PAnsiChar;
pDrive : PAnsiChar;
hDevice : THandle;
bSCSIBuffer : array[0..1023] of AnsiChar;
bInqueryData : array[0..99] of AnsiChar;
pSCSIAddr : PSCSI_ADDRESS;
pSCSIBuffer : PSCSI_PASS_THROUGH_DIRECT_WITH_BUFFER;
nPort : Integer;
nTargetId : Integer;
nLUnId : Integer;
nReturned : Cardinal;
pInquery : PAnsiChar;
sVendor : AnsiString;
sProductId : AnsiString;
sRevision : AnsiString;
sVendorSpec : AnsiString;
begin
...
{
******************************************************************************
* Liste der optischen Laufwerke erstellen.
}
if Win32Platform = VER_PLATFORM_WIN32_NT
then begin
{
* Init
}
lvwDrives.Clear;
pDriveBuffer := nil;
pDrive := nil;
{
* Vorhandene Laufwerksbuchstaben einlesen und Pointer übergeben.
}
nBufferLength := GetLogicalDriveStringsA(0, nil);
if nBufferLength > 0
then try
GetMem(pDriveBuffer, nBufferLength * SizeOf(AnsiChar));
if GetLogicalDriveStringsA(nBufferLength, pDriveBuffer) > 0
then begin
{
* Am Anfang Buffers steht das erste Laufwerk. Deshalb wird der
* Pointer des Buffers als Startpointer übergeben.
}
pDrive := pDriveBuffer;
{
* Solange es einen Laufwerkseintrag gibt ...
}
while Length(pDrive) > 0
do begin
{
* den Typ des Laufwerks auf CD-ROM prüfen und ggfs eintragen.
}
if GetDriveTypeA(pDrive) = DRIVE_CDROM
then begin
lvwDrives.Items.Add.Caption := pDrive;
{
* Nun wird das Handle auf das Laufwerk geholt.
}
hDevice := CreateFile(PAnsiChar(Format('\\.\%s:', [pDrive[0]])),
GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE,
nil, OPEN_EXISTING, 0, 0 );
if hDevice <> INVALID_HANDLE_VALUE
then begin
{
* Die SCSI Adresse für das Laufwerk ermitteln und eintragen.
}
ZeroMemory(@bSCSIBuffer, 1024);
pscsiAddr := PSCSI_ADDRESS(@bSCSIBuffer);
pscsiAddr^.Length := SizeOf(TSCSI_ADDRESS);
if DeviceIoControl(hDevice, IOCTL_SCSI_GET_ADDRESS, nil, 0,
pscsiAddr, SizeOf(TSCSI_ADDRESS), nReturned, nil)
then begin
nPort := pscsiAddr^.PortNumber;
nTargetId := pscsiAddr^.TargetId;
nLUnId := pscsiAddr^.Lun;
lvwDrives.Items.Item[lvwDrives.Items.Count - 1].SubItems.Add(
Format('[%d:%d:%d]', [nPort, nTargetId, nLUnId]));
end;
{
* Laufwerksbezeichnung ermitteln und eintragen.
}
ZeroMemory(@bSCSIBuffer, 1024);
ZeroMemory(@bInqueryData, 100);
pSCSIBuffer := PSCSI_PASS_THROUGH_DIRECT_WITH_BUFFER(@bSCSIBuffer);
with pSCSIBuffer^.sptd
do begin
Length := SizeOf(SCSI_PASS_THROUGH_DIRECT);
CdbLength := 6;
SenseInfoLength := 24;
DataIn := SCSI_IOCTL_DATA_IN;
DataTransferLength := Length(bInqueryData);
TimeOutValue := 2;
DataBuffer := @bInqueryData;
SenseInfoOffset := SizeOf(pSCSIBuffer^.sptd) +
SizeOf(pSCSIBuffer^.Filler);
Cdb[0] := $12;
Cdb[4] := Length(bInqueryData);
end;
if DeviceIoControl(hDevice, IOCTL_SCSI_PASS_THROUGH_DIRECT,
pSCSIBuffer, SizeOf(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER),
pSCSIBuffer, SizeOf(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER),
nReturned, nil)
then begin
pInquery := @bInqueryData[0];
Inc(pInquery, 8);
sVendor := Trim(Copy(pInquery, 1, 8));
sProductId := Trim(Copy(pInquery, 8 + 1, 16));
sRevision := Trim(Copy(pInquery, 24 + 1, 4));
sVendorSpec := Trim(Copy(pInquery, 28 + 1, 20));
lvwDrives.Items.Item[lvwDrives.Items.Count - 1].SubItems.Add(
Trim(Format('%s %s %s %s',
[sVendor, sProductId, sRevision, sVendorSpec])));
end;
end;
CloseHandle(hDevice);
end;
{
* Da die Laufwerkstrings mit einer #0 getrennt hintereinander stehen,
* wird der Pointer um die Länge des Strings und des Trennzeichens
* erhöht.
}
inc(pDrive, lStrLenA(pDrive) + 1);
end;
end;
finally
{
* Reservierten Speicher wieder freigeben.
}
FreeMem(pDriveBuffer);
pDriveBuffer := nil;
pDrive := nil;
end;
end;
...
end;
Das Ergebnis des Beispiels sieht so aus:

Get Drives 5 (podGetDrives05.7z - 224 kb) MD5 (1 kb). Stand: 2. Januar 2012
Fr_An - Letzte Änderung: 30. Dezember 2011
seit 28. Juli 2010