指定デバイスに直接制御コードを送る          <TOP>


指定したデバイスドライバに直接制御コードを送ります。例では取り出し可能なドライブ名を入力し実行ボタンによりEJECTしています。

GetVersion オペレーティングシステムの種類やバージョンに関する情報を取得

CreateFile 指定したファイルをオープンし、デバイスハンドルを返す

DeviceIoControl 指定したデバイスドライバに直接制御コードを送る

CloseHandle オープンされているオブジェクトハンドルをクローズ

 

Windows98/MeとWindows2000/XPでは方法が異なるのでOSバージョンを取得し振り分けています。
GetVersion >= 0 : Windows2000
GetVersion < 0  : Windows9x

 

 

'================================================================
'= 指定デバイスに直接制御コードを送る
'=    (DeviceIoControl.bas)
'================================================================
#include "Windows.bi"

Type DIOC_REGISTERS
    reg_EBX   As Long
    reg_EDX   As Long
    reg_ECX   As Long
    reg_EAX   As Long
    reg_EDI   As Long
    reg_ESI   As Long
    reg_Flags As Long
End Type

' オペレーティングシステムの種類やバージョンに関する情報を取得
Declare Function Api_GetVersion& Lib "kernel32" Alias "GetVersion" ()

' 指定したファイルをオープンし、デバイスハンドルを返す
Declare Function Api_CreateFile& Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName$, ByVal dwDesiredAccess&, ByVal dwShareMode&, lpSecurityAttributes As Any, ByVal dwCreationDisposition&, ByVal dwFlagsAndAttributes&, ByVal hTemplateFile&)

' 指定したデバイスドライバに直接制御コードを送る
Declare Function Api_DeviceIoControl& Lib "kernel32" Alias "DeviceIoControl" (ByVal hDevice&, ByVal dwIoControlCode&, lpInBuffer As Any, ByVal nInBufferSize&, lpOutBuffer As Any, ByVal nOutBufferSize&, lpBytesReturned&, lpOverlapped As Any)

' オープンされているオブジェクトハンドルをクローズ
Declare Function Api_CloseHandle& Lib "kernel32" Alias "CloseHandle" (ByVal hObject&)

#define INVALID_HANDLE_VALUE -1
#define OPEN_EXISTING 3
#define FILE_FLAG_DELETE_ON_CLOSE &H4000000 '67108864
#define GENERIC_READ -2147483648            '&H80000000
#define GENERIC_WRITE &H40000000
#define IOCTL_STORAGE_EJECT_MEDIA 2967560   'SCSIデバイスからメディアをイジェクトする
#define VWIN32_DIOC_DOS_IOCTL 1

Var Shared Edit1 As Object
Edit1.Attach getDlgItem("Edit1")

'================================================================
'=
'================================================================
Declare Sub Button1_on edecl ()
Sub Button1_on()
    Var Drive As Long
    Var Dummy As Long
    Var EjectDrive As String
    Var DriveLetter As String
    Var RawStuff As DIOC_REGISTERS
    Var Ret As Long

    EjectDrive = GetDlgItemText("Edit1")

    If Len(EjectDrive) Then

        '/ 小文字なら大文字に変換し":"を付加
        DriveLetter = ucase$(Left$(EjectDrive & ":", 2))
        If Api_GetVersion >= 0 Then 

            '/ Windows NT・2000・XP
            Drive = Api_CreateFile("\\.\" & DriveLetter, GENERIC_READ Or GENERIC_WRITE, 0, ByVal 0, OPEN_EXISTING, 0, 0)
            If Drive <> INVALID_HANDLE_VALUE Then

                '/ メディアイジェクト
                Ret = Api_DeviceIoControl(Drive, IOCTL_STORAGE_EJECT_MEDIA, 0, 0, 0, 0, Dummy, ByVal 0)
                Ret = APi_CloseHandle(Drive)
            End If
        Else

            '/ Win9x・Me
            Drive = Api_CreateFile("\\.\VWIN32", 0, 0, ByVal 0, 0, FILE_FLAG_DELETE_ON_CLOSE, 0)
            If Drive <> INVALID_HANDLE_VALUE Then

                '/ 仮想デバイスドライバを通してInt21h Function 440Dh Minor Code 49hを実行
                RawStuff.reg_EAX = &H440D
                RawStuff.reg_EBX = asc(DriveLetter) - Asc("A") + 1
                RawStuff.reg_ECX = &H49 Or &H800

                '/ メディアイジェクト
                Ret = Api_DeviceIoControl(Drive, VWIN32_DIOC_DOS_IOCTL, RawStuff, Len(RawStuff), RawStuff, Len(RawStuff), Dummy, ByVal 0)
                Ret = Api_CloseHandle(Drive)
            End If
        End If
    End If
End Sub

'================================================================
'=
'================================================================
While 1
    WaitEvent
Wend
Stop
End