- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have tried to write a routine to eject floppies, Zip disks and CD-ROMs from drives, but it does not work. Can anybody please point me to an example of how to do it, or tell me where I am going wrong in the code below.
Alan
Alan
function EjectDisk(DriveLetter)
! Obtains authority and ejects disks from removable drives. Initial version is
! for single drive. Does not work - fails with System Error 5 Access is Denied.
use dfwinty, only : DRIVE_CDROM, DRIVE_REMOVABLE, FILE_ATTRIBUTE_NORMAL, &
INVALID_HANDLE_VALUE, IOCTL_STORAGE_EJECT_MEDIA, &
IOCTL_STORAGE_MEDIA_REMOVAL, NULL, OPEN_EXISTING, &
T_PREVENT_MEDIA_REMOVAL
use kernel32, only : CloseHandle, CreateFile, DeviceIoControl, GetDriveType, &
GetLastError
implicit none
character*1, intent(in) :: DriveLetter
logical*4 :: EjectDisk
integer*4 :: hDrive, i4, DriveType, j4, sizePMR
type (T_PREVENT_MEDIA_REMOVAL) pmr
!
! Get Drive Type
DriveType = GetDriveType(DriveLetter//':')
if (DriveType == DRIVE_REMOVABLE .OR. DriveType == DRIVE_CDROM) then
! If removable, get drive handle
hDrive = CreateFile(DriveLetter, 0, 0, NULL, OPEN_EXISTING, &
FILE_ATTRIBUTE_NORMAL, NULL)
if (hDrive /= INVALID_HANDLE_VALUE) then
! Allow media removal
pmr.PreventMediaRemoval = "F"
sizePMR = sizeof(pmr)
! Allow ejection - not that it works.
if (.NOT. DeviceIoControl(hDrive, IOCTL_STORAGE_MEDIA_REMOVAL, loc(pmr), &
sizePMR, NULL, 0, loc(j4), NULL)) then
! Display error Message: System Error 5 Access is denied.
i4 = DisplayErrorMessage('StorageMediaRemoval'C)
EjectDisk = .FALSE.
end if
! Eject - not that it works.
if (.NOT. DeviceIoControl(hDrive, IOCTL_STORAGE_EJECT_MEDIA, NULL, &
0, NULL, 0, loc(j4), NULL)) then
! Display error Message: System Error 5 Access is denied.
i4 = DisplayErrorMessage('StorageEjectMedia'C)
EjectDisk = .FALSE.
else
EjectDisk = .TRUE.
end if
end if
call CloseHandle(hDrive)
else
EjectDisk = .FALSE.
end if
end function EjectDisk
Link Copied
5 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I can spot two errors in the code. In line 1, string is not null-terminated; it should be:
DriveType = GetDriveType(DriveLetter//':'//CHAR(0))
or
DriveType = GetDriveType(DriveLetter//':'C)
Second, where did you find that "F" means .FALSE. in this context? Lemme see... BOOLEAN is a typedef for unsigned char in C; that's supposed to be a LOGICAL(1) in Fortran, however, I see it is translated as CHARACTER(UCHAR) in DFWINTY.f90 instead... it is not quite an appropriate translation. In any case, that means that CHAR(0) corresponds to FALSE and CHAR(255) (or anything else) to TRUE.
Jugoslav
DriveType = GetDriveType(DriveLetter//':'//CHAR(0))
or
DriveType = GetDriveType(DriveLetter//':'C)
Second, where did you find that "F" means .FALSE. in this context? Lemme see... BOOLEAN is a typedef for unsigned char in C; that's supposed to be a LOGICAL(1) in Fortran, however, I see it is translated as CHARACTER(UCHAR) in DFWINTY.f90 instead... it is not quite an appropriate translation. In any case, that means that CHAR(0) corresponds to FALSE and CHAR(255) (or anything else) to TRUE.
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Jugoslav,
Thanks for your help.
GetDriveType worked OK without the missing CHAR(0), but I have now put it in. Changing pmr.PreventMediaRemoval = ?F? to CHAR(0), CHAR(1) ?T?, ?F? or any other character(s) made no difference at all to the end result. I had hoped that the ghastly transformation of CHARACTER(UCHAR) to BOOLEAN involved it being intelligent enough to take ?F? as .FALSE. Silly me! But it does not seem to have any effect on calling DeviceIOControl. I must be misinterpreting the requirements for the arguments.
Thanks for the tip on Q165721 ? I will take some time to digest it and will see if it gives me the tools to hack it.
Alan
Thanks for your help.
GetDriveType worked OK without the missing CHAR(0), but I have now put it in. Changing pmr.PreventMediaRemoval = ?F? to CHAR(0), CHAR(1) ?T?, ?F? or any other character(s) made no difference at all to the end result. I had hoped that the ghastly transformation of CHARACTER(UCHAR) to BOOLEAN involved it being intelligent enough to take ?F? as .FALSE. Silly me! But it does not seem to have any effect on calling DeviceIOControl. I must be misinterpreting the requirements for the arguments.
Thanks for the tip on Q165721 ? I will take some time to digest it and will see if it gives me the tools to hack it.
Alan
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Aside from the general considerations in that article, your immediate problem is due to your CreateFile call, you need at least GENERIC_READ access (second parameter) when opening the drive.
James
James
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
James, Jugoslav,
Many thanks for your help - the article with its advice and sample C++ code did the trick, and the routine now ejects both Zip disks & CD-ROMs, and with floppies correctly tells me that it is an incorrect function. I now need to polish it up with appropriate messages & logic for when there is no disk to eject, etc and that will be another routine safely in the bank.
Alan
Many thanks for your help - the article with its advice and sample C++ code did the trick, and the routine now ejects both Zip disks & CD-ROMs, and with floppies correctly tells me that it is an incorrect function. I now need to polish it up with appropriate messages & logic for when there is no disk to eject, etc and that will be another routine safely in the bank.
Alan
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page