タイトル DiskをEjectする
対象言語 VB4.0, Access95以降
動作確認OS Windows95,98,NT4.0
使用関数 CreateFile,CloseHandle,DeviceIoControl
改築日 1999/05/16(1998/03/20)
Source Download

CDやMO等、SoftwareEject出来るドライブの
Diskを取り出します。


Win95,98 と NTとでは方法が違います。
Win95,98の場合、仮想デバイスドライバを通して
Int21h Function 440Dh Minor Code 49hを実行します。
NTの場合、IOCTL_STORAGE_EJECT_MEDIAコントロールコードを実行します。

Ejectする前にデバイスが開放されていないと Eject出来ません。

1. フォームを作成しコマンドボタン(Command1)ドライブリストボックス(Drive1)を貼り付けてください。

Option Explicit

Private Sub Command1_Click()

   Dim Drv As String

   Drv = Drive1.Drive
   Call Y_EjectDisk(Drv)

End Sub



2.モジュールウインドウを作成し、下のソースを入力してください。


Option Explicit

'ファイル(各種デバイス)を開く
Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, _
ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, lpSecurityAttributes As SECURITY_ATTRIBUTES, _
ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long

Type SECURITY_ATTRIBUTES
   nLength As Long
   lpSecurityDescriptor As Long
   bInheritHandle As Boolean
End Type

Public Const GENERIC_READ = &H80000000
Public Const FILE_SHARE_READ = &H1
Public Const OPEN_EXISTING = 3


'デバイス間I/O制御
Declare Function DeviceIoControl Lib "kernel32" (ByVal hDevice As Long, ByVal dwIoControlCode As Long, _
lpInBuffer As Any, ByVal nInBufferSize As Long, lpOutBuffer As Any, ByVal nOutBufferSize As Long, _
lpBytesReturned As Long, lpOverlapped As OVERLAPPED) As Long

Type OVERLAPPED
   Internal As Long
   InternalHigh As Long
   offset As Long
   OffsetHigh As Long
   hEvent As Long
End Type

Type DevIoCtrlRegs
   EBX As Long
   EDX As Long
   ECX As Long
   EAX As Long
   EDI As Long
   ESI As Long
   flg As Long
End Type

'ハンドルを閉じる
Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

'Windowsバージョンを取得する
Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" (lpVersionInformation As OSVERSIONINFO) As Long

Type OSVERSIONINFO
   dwOSVersionInfoSize As Long 'この構造体のバイト数
   dwMajorVersion As Long 'バージョン番号
   dwMinorVersion As Long 'マイナーリビジョン番号
   dwBuildNumber As Long 'ビルド番号
   dwPlatformId As Long 'プラットホーム
   szCSDVersion As String * 128 'OSに関する説明
End Type

'dwPlatformId の戻り値
Public Const VER_PLATFORM_WIN32_NT = 2 'WinNT

Public Const FILE_DEVICE_MASS_STORAGE As Long = &H2D
Public Const IOCTL_STORAGE_BASE As Long = FILE_DEVICE_MASS_STORAGE
Public Const METHOD_BUFFERED As Long = 0
Public Const FILE_READ_ACCESS As Long = &H1
Public Const INVALID_HANDLE_VALUE = -1


Public Sub Y_EjectDisk(ByVal Drv As String)
'***********************************************************
'機能: 指定したドライブをイジェクトする
'引数: Drv = ドライブ名
'備考: 指定したドライブが自動イジェクト機構を持っていなければ
'   作動しません。
'   デバイスがロックされている時も作動しません。
'***********************************************************

   Dim Over As OVERLAPPED
   Dim DevIoCtrlReg As DevIoCtrlRegs
   Dim Security As SECURITY_ATTRIBUTES
   Dim IOCTL_STORAGE_EJECT_MEDIA As Long
   Dim hDevice As Long
   Dim BytesReturned As Long
   Dim drvNo As Long
   Dim DrvName As String
   Dim NTFlg As Boolean
   Dim longret As Long

   Drv = StrConv(Left$(Drv, 1), vbUpperCase)
   drvNo = Asc(Drv) - 64

   If drvNo >= 1 And drvNo <= 26 Then
     NTFlg = Y_IsNT()

     If NTFlg Then
       DrvName = "\\.\" & Drv & ":"
     Else
       DrvName = "\\.\vwin32"

     End If
   'デバイスオープン
     hDevice = CreateFile(DrvName, GENERIC_READ, FILE_SHARE_READ, Security, OPEN_EXISTING, 0, 0)

     If hDevice <> INVALID_HANDLE_VALUE Then
   'メディアイジェクト
       If NTFlg Then 'NT
         IOCTL_STORAGE_EJECT_MEDIA = CTL_CODE(IOCTL_STORAGE_BASE, &H202, _
        METHOD_BUFFERED, FILE_READ_ACCESS)
         longret = DeviceIoControl(hDevice, IOCTL_STORAGE_EJECT_MEDIA, vbNullString, _
        0, vbNullString, 0, BytesReturned, Over)
       Else 'Win95,98
   '仮想デバイスドライバを通して Int21h Function 440Dh Minor Code 49hを実行
         With DevIoCtrlReg
           .EAX = &H440D
           .EBX = drvNo
           .ECX = &H849
           .EDX = 0
         End With
         longret = DeviceIoControl(hDevice, 1, DevIoCtrlReg, Len(DevIoCtrlReg), DevIoCtrlReg, _
        Len(DevIoCtrlReg), BytesReturned, Over)
       End If

     'デバイスを閉じる
       longret = CloseHandle(hDevice)
     End If
   End If

End Sub


Public Function CTL_CODE(DeviceType As Long, Func As Long, Method As Long, Access As Long) As Long
'***********************************************************
'機能 : winioctl.h の CTL_CODE マクロ
'***********************************************************

   CTL_CODE = (DeviceType * 2 ^ 16) Or (Access * 2 ^ 14) Or (Func * 2 ^ 2) Or Method

End Function


Public Function Y_IsNT() As Boolean
'***********************************************************
'機能 : WindowsNTかを判断する
'戻り値: True = NT False = その他
'***********************************************************

   Dim longret As Long
   Dim info As OSVERSIONINFO

   info.dwOSVersionInfoSize = Len(info)

   longret = GetVersionEx(info)
   Y_IsNT = (info.dwPlatformId = VER_PLATFORM_WIN32_NT)

End Function





Copyright (C)1997-2001 空耳工房 MY2Project All rights reserved.