Code: Select all
; Define
#LOCK_TIMEOUT=10000; ms
#LOCK_RETRIES=20
#FSCTL_LOCK_VOLUME=$90018
#FSCTL_UNLOCK_VOLUME=$9001C
#FSCTL_DISMOUNT_VOLUME=$90020
#IOCTL_STORAGE_MEDIA_REMOVAL=$2D4804
#IOCTL_STORAGE_EJECT_MEDIA=$2D4808
Structure PREVENT_MEDIA_REMOVAL
PreventMediaRemoval.b
EndStructure
; EndDefine
Procedure.l OpenVolume(DriveLetter.s)
Protected AccessFlags.l
Protected Volume.l
DriveType.l=GetDriveType_(DriveLetter+":\")
Debug "Drivetyp: "+Str(DriveType)
Select DriveType
Case #DRIVE_REMOVABLE
AccessFlags = #GENERIC_READ|#GENERIC_WRITE
Case #DRIVE_CDROM
AccessFlags = #GENERIC_READ
Default
ProcedureReturn #INVALID_HANDLE_VALUE
EndSelect
ProcedureReturn CreateFile_("\\.\"+DriveLetter+":",AccessFlags,#FILE_SHARE_READ|#FILE_SHARE_WRITE,#Null,#OPEN_EXISTING,0,#Null)
EndProcedure
Procedure.b CloseVolume(Handle)
ProcedureReturn CloseHandle_(Handle)
EndProcedure
Procedure.b LockVolume(Handle.l)
Protected i.w=0
Protected Buffer.l
Debug "Lock..."
While i<#LOCK_RETRIES
i+1
If DeviceIoControl_(Handle,#FSCTL_LOCK_VOLUME,#Null,0,#Null,0,@Buffer,#Null)
Debug "...ed"
ProcedureReturn #True
EndIf
Sleep_(#LOCK_TIMEOUT / #LOCK_RETRIES)
Wend
Debug "...failed"
ProcedureReturn #False
EndProcedure
Procedure.b DismountVolume(Handle.l)
Protected Buffer.l
ProcedureReturn DeviceIoControl_(Handle,#FSCTL_DISMOUNT_VOLUME,#Null,0,#Null,0,@Buffer,#Null)
EndProcedure
Procedure.b PreventRemovalOfVolume(Handle.l,Flag.b)
Protected Buffer.l
Protected MediaBuffer.PREVENT_MEDIA_REMOVAL
MediaBuffer\PreventMediaRemoval = Flag
ProcedureReturn DeviceIoControl_(Handle,#IOCTL_STORAGE_MEDIA_REMOVAL,@MediaBuffer,SizeOf(PREVENT_MEDIA_REMOVAL),#Null,0,@Buffer,#Null)
EndProcedure
Procedure.b AutoEjectVolume(Handle)
Protected Buffer.l
ProcedureReturn DeviceIoControl_(Handle,#IOCTL_STORAGE_EJECT_MEDIA,#Null,0,#Null,0,@Buffer,#Null)
EndProcedure
Procedure EjectVolume(DriveLetter.s)
Protected Handle.l
Protected Success.l=0
; [ 1 ] Volume "\\.\X:" öffnen...
Handle=OpenVolume(DriveLetter)
If Handle=#INVALID_HANDLE_VALUE
ProcedureReturn #False
Else
; [ 2 ] Lock and Dismount...
If LockVolume(Handle)&DismountVolume(Handle)
Success=1
; [ 3 ] Check removal and Eject...
If PreventRemovalOfVolume(Handle,#False)&AutoEjectVolume(Handle)
Success=2
EndIf
EndIf
; [ 4 ] Close Volume...
If CloseVolume(Handle)
ProcedureReturn #False
EndIf
Debug "Ergebnis:"+Str(Success)
EndIf
EndProcedure
Debug EjectVolume("D");