Projekte > Optische Laufwerke > Typ

CD oder DVD Laufwerk?

Mit der Funktion DeviceIoControl, dem Kontrolcode IOCTL_STORAGE_GET_MEDIA_TYPES_EX und der Struktur GET_MEDIA_TYPES lässt sich ermitteln, ob es sich bei dem Laufwerk um ein CD- oder DVD-Laufwerk handelt. Eine weitere Unterscheidung ist in dieser Funktion offensichtlich nicht vorgesehen.

 

Deklarationen

const
  FILE_DEVICE_CD_ROM       = $00000002;
  FILE_DEVICE_MASS_STORAGE = $0000002d;
  FILE_DEVICE_DVD          = $00000033;
 
const
  IOCTL_STORAGE_BASE = FILE_DEVICE_MASS_STORAGE;
 
const
  METHOD_BUFFERED = 0;
 
const
  FILE_ANY_ACCESS = 0;
 
const
  IOCTL_STORAGE_GET_MEDIA_TYPES_EX = (IOCTL_STORAGE_BASE shl 16) or
                                     (FILE_ANY_ACCESS shl 14) or
                                     ($0301 shl 2) or
                                     METHOD_BUFFERED;
 
type
  TGET_MEDIA_TYPES = record
    DeviceType     : Cardinal;
//    MediaInfoCount : Cardinal;
//    MediaInfo      : Array[0..0] of TDEVICE_MEDIA_INFO;
  end;
  PGET_MEDIA_TYPES = ^TGET_MEDIA_TYPES;

Die Variablen MediaInfoCount und MediaInfo wurden auskommentiert da sie hier nicht benöigt werden.

 

Die Funktion

function TOptDrives.ReadDeviceType(aDevice: THandle): Boolean;
{********************************************************************************
*  Laufwerkstyp: CD, DVD, Unbekannt.
}
var
  GetMediaTypes : PGET_MEDIA_TYPES;
  lpOutBuffer   : array [0..2047] of AnsiChar;
  nReturned     : Cardinal;
begin
  Result := False;
  if hDevice <> INVALID_HANDLE_VALUE
  then begin
    nReturned := 0;
    Result := DeviceIoControl(hDevice, IOCTL_STORAGE_GET_MEDIA_TYPES_EX,
                              nil, 0, @lpOutBuffer, SizeOf(lpOutBuffer),
                              nReturned, nil);
    if Result
    then begin
      GetMediaTypes := @lpOutBuffer;
      case GetMediaTypes.DeviceType of
        FILE_DEVICE_CD_ROM : fDrive[fActive].DeviceType := 'CD-ROM';
        FILE_DEVICE_DVD    : fDrive[fActive].DeviceType := 'DVD';
        else                 fDrive[fActive].DeviceType := 'Unknown';
      end;
    end;
  end;
end;

Der Funktion wird das Handle auf das Laufwerk übergeben. Als Ergebnis gibt die Funktion zurück, ob Windows den Befehl erfolgreich ausführen konnte. Die Funktion wird in der Demo wiederum bei der Erstellung der Klasse ausgeführt.

constructor TOptDrives.Create;
{*******************************************************************************
*  Class erstellen.
}
var
  i       : Integer;
  hDevice : THandle;
begin
  {
  *  Laufwerksbuchstaben ermitteln.
  }
  if ReadDrives > 0
  then begin
    for i := 0 to Length(fDrive) - 1
    do begin
      fActive := i;
      hDevice := DriveHandle(fDrive[fActive].Letter);
      if hDevice <> INVALID_HANDLE_VALUE
      then begin
        ReadSCSIAddress(hDevice);
        ReadInquiry(hDevice);
        ReadDeviceType(hDevice);
        CloseHandle(hDevice);
      end;
    end;
  end;
end;

Die Demo sieht zum Beispiel so aus:

CD or DVD (podCDorDVD.7z - 231 kb) MD5 (1 kb). Stand: 28. April 2013

Änderungen an der Demo

28.04.2013Kleine Überarbeitung und neuer Name.
06.04.2013Überarbeitung.