I have tried this code:
uses MMSystem;
mciSendString('Set cdaudio door open wait', nil, 0, handle);
mciSendString('Set cdaudio door closed wait', nil, 0, handle);
but there was no effect. I have heard that this does not work on all systems.
I'm trying to get a drive to eject on Windows XP, and would like to specify the drive via the drive letter (necessary for systems with multiple drives).
This is code using the DeviceIOControl() API function, works for me on Windows XP (compiled and tested using Delphi 5):
function DeviceIOControlHelper(ADeviceHandle: THandle;
ADeviceIOControlCode: DWORD): boolean;
var
BytesReturned: Cardinal;
begin
Result := DeviceIOControl(ADeviceHandle, ADeviceIOControlCode,
nil, 0, nil, 0, BytesReturned, nil);
end;
function SetDriveDoorOpen(ADriveLetter: char; AValue: boolean): boolean;
const
FILE_DEVICE_FILE_SYSTEM = 9;
FILE_ANY_ACCESS = 0;
FILE_READ_ACCESS = 1;
METHOD_BUFFERED = 0;
IOCTL_STORAGE_BASE = $2D;
(*
#define CTL_CODE( DeviceType, Function, Method, Access ) ( \
((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
*)
// FSCTL_LOCK_VOLUME = CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 6,
// METHOD_BUFFERED, FILE_ANY_ACCESS);
FSCTL_LOCK_VOLUME = (FILE_DEVICE_FILE_SYSTEM shl 16)
or (FILE_ANY_ACCESS shl 14)
or (6 shl 2) or METHOD_BUFFERED;
// FSCTL_DISMOUNT_VOLUME = CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 8,
// METHOD_BUFFERED, FILE_ANY_ACCESS);
FSCTL_DISMOUNT_VOLUME = (FILE_DEVICE_FILE_SYSTEM shl 16)
or (FILE_ANY_ACCESS shl 14)
or (8 shl 2) or METHOD_BUFFERED;
// IOCTL_STORAGE_EJECT_MEDIA = CTL_CODE(IOCTL_STORAGE_BASE, 0x0202,
// METHOD_BUFFERED, FILE_READ_ACCESS);
IOCTL_STORAGE_EJECT_MEDIA = (IOCTL_STORAGE_BASE shl 16)
or (FILE_READ_ACCESS shl 14)
or ($0202 shl 2) or METHOD_BUFFERED;
// IOCTL_STORAGE_LOAD_MEDIA = CTL_CODE(IOCTL_STORAGE_BASE, 0x0203,
// METHOD_BUFFERED, FILE_READ_ACCESS);
IOCTL_STORAGE_LOAD_MEDIA = (IOCTL_STORAGE_BASE shl 16)
or (FILE_READ_ACCESS shl 14)
or ($0203 shl 2) or METHOD_BUFFERED;
var
DriveCmdStr: string;
DriveHandle: THandle;
begin
Result := FALSE;
DriveCmdStr := Format('\\.\%s:', [ADriveLetter]);
DriveHandle := CreateFile(PChar(DriveCmdStr), GENERIC_READ, FILE_SHARE_WRITE,
nil, OPEN_EXISTING, 0, 0);
if DriveHandle <> INVALID_HANDLE_VALUE then begin
if AValue then begin
Result := DeviceIOControlHelper(DriveHandle, FSCTL_LOCK_VOLUME)
and DeviceIOControlHelper(DriveHandle, FSCTL_DISMOUNT_VOLUME)
and DeviceIOControlHelper(DriveHandle, IOCTL_STORAGE_EJECT_MEDIA);
end else
Result := DeviceIOControlHelper(DriveHandle, IOCTL_STORAGE_LOAD_MEDIA);
CloseHandle(DriveHandle);
end;
end;
Error handling omitted.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With