Results 1 to 2 of 2

Thread: Eject JAZZ drive

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2000
    Location
    Texas
    Posts
    313

    Question

    Does anyone know how to eject a jazz drive? Or possable even lock it ect.

  2. #2
    Guru Yonatan's Avatar
    Join Date
    Apr 1999
    Location
    Israel
    Posts
    892
    There are a few Tape Backup API functions. Very few. Seems Microsoft forgot to put an eject somewhere in there.

    There's only one solution I can give you if you want to eject a drive (ANY drive, not necessarily tape). Use...
    Drum roll please...

    Assembly. (OH THE HORROR!)

    Alright, here's what MSDN says:
    Interrupt 21h Function 440Dh Minor Code 49h

    [Windows 95 only.]

    Ejects the specified media.

    mov ax, 440Dh ; generic IOCTL
    mov bx, DriveNum ; see below
    mov ch, 8 ; device category
    mov cl, 49h ; Eject Removable Media
    int 21h

    jc error

    Parameters
    DriveNum
    Drive to eject. This parameter can be 0 for default drive, 1 for A, 2 for B, and so on.
    Here's my code, only slightly modified:
    Code:
    mov ax, 440Dh
    mov bx, DriveNum
    mov ch, 8
    mov cl, 49h
    int 21h          ; Execute drive ejection
    mov ax, 4C00h    ; Code 4C:00 terminates the application
    int 21h          ; Terminate!
    Erm, yes, I bet that was very meaningful to you.

    Now create a new form with a DriveListBox (drvList) and a CommandButton (cmdEject).
    Use this code:
    Code:
    Option Explicit
    
    Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
    Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
    Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
    
    Private Const STANDARD_RIGHTS_REQUIRED = &HF0000
    Private Const SYNCHRONIZE = &H100000
    Private Const PROCESS_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED Or SYNCHRONIZE Or &HFFF
    Private Const INFINITE = &HFFFFFFFF
    
    Private Sub cmdEject_Click()
        Dim lProcessID As Long, hProcess As Long
        Dim bFile(1 To 17) As Byte, bFileNum As Byte, bDriveNum As Byte, sFileName As String
        ' 1 To 17 because the assembly code takes up 17 bytes of disk space.
        
        If Caption = "Busy..." Then Exit Sub
        Tag = Caption
        Caption = "Busy..."
        cmdEject.Enabled = False
        DoEvents ' Update caption
        
        ' First lets get the DriveNum.
        ' The upper case of the first word in drvList.Drive is A, or B, etc.
        ' ASCII codes: A = 65, B = 66, etc. Requested: A = 1, B = 2, etc.
        ' We just need to decrement 64 from the ASCII code.
        bDriveNum = Asc(UCase(Left(drvList.Drive, 1))) - 64
        
        ' mov ax, 440Dh
        ' "mov ax" = B8
        ' Then the source 440D in little-endian format: 0D 44
        ' "mov ax, 440Dh" = B8 0D 44
        bFile(1) = &HB8
        bFile(2) = &HD
        bFile(3) = &H44
        
        ' mov bx, DriveNum
        ' "mov bx" = BB
        ' Then the source DriveNum in little-endian format.
        ' Since DriveNum is a number between 1 and 26, its high byte will ALWAYS be zero.
        ' Since this is a little-endian system, first goes the low byte, then the high byte.
        ' So DriveNum can be expressed like this: [bDriveNum] 00
        ' "mov bx, DriveNum" = BB [bDriveNum] 00
        bFile(4) = &HBB
        bFile(5) = bDriveNum
        bFile(6) = &H0
        
        ' mov ch, 8
        ' "mov ch" = B5
        ' Then the source 8 is one byte... Just: 08
        ' "mov ch, 8" = B5 08
        bFile(7) = &HB5
        bFile(8) = &H8
        
        ' mov cl, 49h
        ' "mov cl" = B1
        ' Then the source 49 is again, one byte... Just: 49
        ' "mov cl, 49h" = B1 49
        bFile(9) = &HB1
        bFile(10) = &H49
        
        ' int 21h
        ' "int" = CD
        ' The interrupt 21h is just one byte: 21
        ' "int 21h" = CD 21
        bFile(11) = &HCD
        bFile(12) = &H21
        
        ' mov ax, 4C00h
        ' "mov ax" = B8
        ' Then the source 4C00 in little-endian format: 00 4C
        ' "mov ax, 4C00h" = B8 00 4C
        bFile(13) = &HB8
        bFile(14) = &H0
        bFile(15) = &H4C
        
        ' int 21h
        ' Didn't change since before: CD 21
        bFile(16) = &HCD
        bFile(17) = &H21
        
        ' Now that we are done with converting the source code to hex,
        ' we can save the data to a .com file and run it.
        sFileName = App.Path
        If Not Right(sFileName, 1) = "\" Then sFileName = sFileName & "\"
        sFileName = sFileName & "eject.com"
        
        bFileNum = FreeFile
        Open sFileName For Binary As bFileNum
            Put bFileNum, , bFile() ' Write Assembly data
        Close bFileNum
        
        lProcessID = Shell(sFileName, vbHide) ' Execute it, hidden from the user
        
        On Error Resume Next
        hProcess = OpenProcess(PROCESS_ALL_ACCESS, False, lProcessID) ' Open the process
        If hProcess = 0 Then ' Already ended. Happens
            Call Kill(sFileName)
            Exit Sub
        End If
        Call WaitForSingleObject(hProcess, INFINITE) ' Wait for it to end
        Call CloseHandle(hProcess) ' Close the process handle
        
        Call Kill(sFileName) ' Destroy the file
        
        cmdEject.Enabled = True
        Caption = Tag
    End Sub
    This will let you eject any drive. Even hard drives. NOT.

    If you don't understand a word of the code above, don't worry. It's assembly, and it's hard to understand as it is...

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width