Projekte > Optische Laufwerke > Schublade

Sperren und Entsperren

Wenn der Gerätetreiber die Sperrfunktionn unterstützt, wird die elektrische Betätigung der Mechanik des Laufwerkes deaktiviert oder aktivert. Das bedeutet, dass bei deaktivierter Mechanik das Öffnen und Schliessen über den Knopf am Laufwerk und mittels Software nicht mehr möglich ist. Das mechanische Schliessen eines geöffneten Laufwerks ist jedoch möglich. Nach einem Systemneustart ist eine Sperre aufgehoben.

Für das Sperren bzw. Entsperren wird ab Windows XP die Funktion DeviceIoControl verwendet.

Als Controlcode konnte bei Erstellung dieses Kapitels IOCTL_CDROM_MEDIA_REMOVAL benutzt werden. Es wurde jedoch empfohlen das allgemeinere IOCTL_STORAGE_MEDIA_REMOVAL zu verwenden. Nun ist es überholt und veraltet.

BOOL DeviceIoControl(
  (HANDLE) hDevice,            // handle to device
  IOCTL_STORAGE_MEDIA_REMOVAL, // dwIoControlCode
  (LPVOID) lpInBuffer,         // input buffer
  (DWORD) nInBufferSize,       // size of input buffer
  NULL,                        // lpOutBuffer
  0,                           // nOutBufferSize
  (LPDWORD) lpBytesReturned,   // number of bytes returned
  (LPOVERLAPPED) lpOverlapped  // OVERLAPPED structure
);

Damit die Entsperrung funktioniert, muss der Gerätetreiber eine Sperrzählung vornehmen. Das bedeutet, bei jeder Sperrung wird der Zähler erhöht und bei jeder Entsperrung verringert. Ist der Zähler 0, ist das Laufwerk entsperrt.

Diesem Befehl wird eine PREVENT_MEDIA_REMOVAL Struktur mitgegeben, mit welchem mitgeteilt wird, ob das Laufwerk gesperrt oder entsperrt werden soll:

typedef struct _PREVENT_MEDIA_REMOVAL {
  BOOLEAN PreventMediaRemoval;
} PREVENT_MEDIA_REMOVAL;

Als dieses Kapitel und die Demo unter Windows 7 erstellt und PreventMediaRemoval als Boolean deklariert wurde, musste genauso oft entsperrt wie gesperrt werden. Deshalb erfolgte die Deklaration als Byte und es wurden die Werte 1 zum Sperren und 2 zum Entsperren verwendet. Unter Windows 10 funktioniert dies beim Entsperren nicht. Dort muss der Wert 0 verwendet werden. Auch bei der Deklaration als Boolean funktioniert das Entsperren unter Windows 10 nicht. Die richtige Deklaration ist Longbool oder ByteBool. Jedoch muss dabei genauso oft entspert werden wie vorher gesperrt wurde.

War die Ausführung der Funktion erfolgreich, ist das Ergebnis ungleich 0, das heisst True. In Delphi ist der Ergebnistyp Longbool.

Diese Struktur wird im folgenden Beispiel vereinfacht:

function TOptDrives.DriveLockUnlock(aValue: Boolean): Boolean;
{*******************************************************************************
*  Laufwerksschublade bzw Auswurf sperren und entsperren.
}
var
  hDevice               : THandle;
  nReturned             : Cardinal;
  PREVENT_MEDIA_REMOVAL : ByteBool;
begin
  {
  *  Init
  }
  Result    := False;
  nReturned := 0;
  {
  *  Das Handle auf das Laufwerk holen.
  }
  hDevice := DriveHandleRead;
  {
  *  Bei einem gültigen Handle Wert für Lock setzen und den Befehl senden
  *  und das Handle wieder schließen.
  }
  if hDevice <> INVALID_HANDLE_VALUE
  then begin
    PREVENT_MEDIA_REMOVAL := ByteBool(aValue);
    Result := DeviceIoControl(hDevice, IOCTL_STORAGE_MEDIA_REMOVAL,
                             @PREVENT_MEDIA_REMOVAL, SizeOf(PREVENT_MEDIA_REMOVAL),
                             nil, 0, nReturned, nil);
    CloseHandle(hDevice);
  end;
end;

Eine Alternative könnte der Controlcode IOCTL_STORAGE_EJECTION_CONTROL sein. Jedoch ist nicht angegeben, was übergeben werden soll. Auf der Seite unten steht zwar "See Also PREVENT_MEDIA_REMOVAL", aber das Ergebnis der Funktion bleibt False.

BOOL DeviceIoControl(
  (HANDLE) hDevice,                // handle to device
  IOCTL_STORAGE_EJECTION_CONTROL,  // dwIoControlCode
  (LPVOID) lpInBuffer,             // input buffer
  (DWORD) nInBufferSize,           // size of input buffer
  NULL,                            // lpOutBuffer
  0,                               // nOutBufferSize(LPDWORD)
  lpBytesReturned,                 // number of bytes returned
  (LPOVERLAPPED) lpOverlapped      // OVERLAPPED structure
);

Demo

Tray Lock (podTrayLock.7z - 211 kb) MD5 (1 kb). Stand: 1. September 2018

Änderungen an der Demo

01.09.2018Deklaration und Wertezuweisung von PREVENT_MEDIA_REMOVAL geändert.
28.04.2013Kleine Überarbeitung und neuer Name.
08.04.2013Überarbeitung.