[リストへもどる]   [VBレスキュー(花ちゃん)]
一括表示

投稿時間:2005/07/27(Wed) 11:13
投稿者名:はこ
Eメール:
URL :
タイトル:
フロッピーのフォーマット
プログラム中からフロッピーディスクのフォーマットを実行したいのですが。

SHFormatDrive関数を実行すると、ダイアログが表示され、開始ボタンを
押下しないとフォーマットされません。

Shell関数を使用して「format a:」を実行すると、コマンドプロンプトが
表示され、Enterキーの押下が求められてしまいます。

ダイアログなどを表示せずに、有無を言わさずプログラム中から
フォーマットを実行したいのですが、不可能でしょうか?

環境:WindowsXP SP2

投稿時間:2005/07/27(Wed) 11:43
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re: フロッピーのフォーマット
> ダイアログなどを表示せずに、有無を言わさずプログラム中から
> フォーマットを実行したいのですが、不可能でしょうか?

低レベルな方法でも良いなら、これかな。
hhttp://www.cisnet.or.jp/home/tsuneoka/win32tech/5.html

高レベルな方法だと、FMIFS.DLL の FormatEx API とか。(こちらは undocumented ですが)


# いずれにしても、手元にFDDのついたPCが無いので、サンプルは提示できそうにありませんが……。

投稿時間:2005/07/27(Wed) 15:30
投稿者名:はこ
Eメール:
URL :
タイトル:
Re^2: フロッピーのフォーマット
魔界の仮面弁士 様

いつもいつもどうもありがとうございます。

教えていただいたURLを参考にさせていただき、いろいろ探し回ってみたところ、
DeviceIoControl関数の引数で、IOCTL_DISK_SET_DRIVE_LAYOUTを指定すれば
実現できる(かもしれない)、というところまでこぎつけました。

ところが、肝心のIOCTL_DISK_SET_DRIVE_LAYOUT値が不明です。
(MSDNや他のサイト等でも散々探したつもりなのですが、、、)

もう少しお助けいただければ幸いです。
どうぞ宜しくお願いします。

投稿時間:2005/07/27(Wed) 21:28
投稿者名:のびた
Eメール:
URL :
タイトル:
Re^3: フロッピーのフォーマット
> 魔界の仮面弁士 様
>
> いつもいつもどうもありがとうございます。
>
> 教えていただいたURLを参考にさせていただき、いろいろ探し回ってみたところ、
> DeviceIoControl関数の引数で、IOCTL_DISK_SET_DRIVE_LAYOUTを指定すれば
> 実現できる(かもしれない)、というところまでこぎつけました。
>
> ところが、肝心のIOCTL_DISK_SET_DRIVE_LAYOUT値が不明です。
> (MSDNや他のサイト等でも散々探したつもりなのですが、、、)
>
> もう少しお助けいただければ幸いです。
> どうぞ宜しくお願いします。

Visual StudioがインストールされているならCのヘッダーファイルを検索すれば見つかりますよ。
ちなみにIOCTL_DISK_SET_DRIVE_LAYOUTはwinioctl.hに以下のように定義されていました。

#define IOCTL_DISK_SET_DRIVE_LAYOUT     CTL_CODE(IOCTL_DISK_BASE, 0x0004, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)

#define IOCTL_DISK_BASE                 FILE_DEVICE_DISK
#define FILE_DEVICE_DISK                0x00000007
#define METHOD_BUFFERED                 0
#define FILE_READ_ACCESS          ( 0x0001 )    // file & pipe
#define FILE_WRITE_ACCESS         ( 0x0002 )    // file & pipe

#define CTL_CODE( DeviceType, Function, Method, Access ) (                 \
    ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
)

投稿時間:2005/07/28(Thu) 10:58
投稿者名:はこ
Eメール:
URL :
タイトル:
Re^4: フロッピーのフォーマット
のびた 様

そうですよね!盲点でした。
どうもありがとうございました。

今はDeviceIoControl関数の3番目の引数に何を渡せばよいのか調査中です。
パーティションを作成しようとしているから、そのパーティション情報だとは
思うのですが、いまだ不明です。

投稿時間:2005/07/29(Fri) 01:51
投稿者名:Starfish
Eメール:
URL :
タイトル:
Re^2: フロッピーのフォーマット
>
> 高レベルな方法だと、FMIFS.DLL の FormatEx API とか。(こちらは undocumented ですが)
>
>
> # いずれにしても、手元にFDDのついたPCが無いので、サンプルは提示できそうにありませんが……。

 はこさんは、DeviceIoControlでやってるみたいですが、うまくいったら
サンプルでも公表してください。

 FMIFS.DLL の FormatEx API ですが、情報は少ないですが、なんとかフォーマットは
できるようになりました。

 参考にしたリンクは、
 hhttp://www.cisnet.or.jp/home/tsuneoka/win32tech/2.html

 ここに書かれている、Cのサンプルは、
 hhttp://www.sysinternals.com/SourceCode/fmifs.html

 これをVB.NETに移植しようとしている、(うまくいかなかった?)
 hhttp://www.error-bank.com/microsoft.public.dotnet.languages.vb.1/150835_Thread.aspx

 のあたりです。
                            つづく

投稿時間:2005/07/29(Fri) 02:10
投稿者名:Starfish
Eメール:
URL :
タイトル:
FMIFS.DLL の FormatEx API
 フォームに、コマンドボタンとラベルを貼り付けて

========== ここから、フォームモジュール ================
Private Sub Command1_Click()
Dim bytDrive()  As Byte
Dim bytFS()     As Byte
Dim bytLabel()  As Byte

    ' パラメータの文字列をバイト配列に
    bytDrive = "A:\" & Chr(0)           ' ドライブ
    bytFS = "FAT" & Chr(0)              ' ファイルシステムフォーマット
    bytLabel = "TEST" & Chr(0)          ' ラベル
    
    ' 表示をクリア
    Label1.Caption = ""

    Call FormatEx(bytDrive(0), _
                  FMIFS_FLOPPY, _
                  bytFS(0), _
                  bytLabel(0), _
                  API_FALSE, _
                  FMIFS_SizeDefault, _
                  AddressOf FormatexCallBack)
            
    If gbytResult = 1 Then
        MsgBox "フォーマットが完了しました。"
    Else
        MsgBox "フォーマットが失敗しました。"
    End If
    
End Sub


========== ここから、標準モジュール ================
Option Explicit

' ディスク/ディスケットのフォーマットを行う関数
Public Declare Function FormatEx Lib "FMIFS.DLL" _
                       (DriveRoot As Any, _
                        ByVal MediaFlag As Long, _
                        Format As Any, _
                        Label As Any, _
                        ByVal QuickFormat As Long, _
                        ByVal ClusterSize As Long, _
                        ByVal Callback As Long) As Long

' MediaFlag
Public Const FMIFS_HARDDISK = &HC
Public Const FMIFS_FLOPPY = &H8

' ClusterSize
Public Const FMIFS_SizeDefault = 0
Public Const FMIFS_Size512 = 512
Public Const FMIFS_Size1K = 1024
Public Const FMIFS_Size2K = 2048
Public Const FMIFS_Size4K = 4096
Public Const FMIFS_Size8K = 8192
Public Const FMIFS_Size16K = 16384
Public Const FMIFS_Size32K = 32768
Public Const FMIFS_Size64K = 65536
Public Const FMIFS_Size128K = 131072
Public Const FMIFS_Size256K = 262144

' Command
Public Const FMIFS_Progress = 0
Public Const FMIFS_DoneWithStructure = 1
Public Const FMIFS_InsufficientRights = 6
Public Const FMIFS_WriteProtected = 7
Public Const FMIFS_Done = 11
Public Const FMIFS_OutPut = 14
Public Const FMIFS_StructureProgress = 15

' メモリーコピー関数
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
                  (Destination As Any, _
                   Source As Any, _
                   ByVal Length As Long)

' C言語の、True/False
Public Const API_TRUE = 1               ' VBの True は、-1
Public Const API_FALSE = 0              ' VBの False は、0

' フォーマットの結果
Public gbytResult   As Byte

Public Function FormatexCallBack(ByVal lngCommand As Long, ByVal lngSubAction As Long, ByVal
ActionInfo As Long) As Long
Dim lngInfo         As Long
Dim bytMessage(256) As Byte

    ' Command により分岐
    Debug.Print lngCommand, lngSubAction, ActionInfo
    Select Case lngCommand                     ' 処理中
        Case FMIFS_Progress
            Call CopyMemory(lngInfo, ByVal ActionInfo, 4)
            Form1.Label1.Caption = CStr(lngInfo) & " パーセント終了しました。"
            Form1.Label1.Refresh
        Case FMIFS_DoneWithStructure        ' FAT初期化完了?
            Form1.Label1.Caption = "フォーマットは完了しました。"
            Form1.Label1.Refresh
        Case FMIFS_InsufficientRights
            ' ?
        Case FMIFS_WriteProtected           ' 書込み禁止
            Form1.Label1.Caption = "フォーマットできません。このボリュームは書込み禁止です。"
            Form1.Label1.Refresh
        Case FMIFS_Done                     ' 完了
            ' 終了
            Call CopyMemory(gbytResult, ByVal ActionInfo, 1)
        Case FMIFS_OutPut                   ' メッセージ出力
            ' ActionInfo にメッセージがセットされるようですが、発生しないのでとりあえずスキッ
プ。
        Case FMIFS_StructureProgress         ' FAT初期化中?
            Form1.Label1.Caption = "ファイル アロケーション テーブル(FAT)を初期化していま
す。"
            Form1.Label1.Refresh
    End Select
    
    FormatexCallBack = API_TRUE

End Function

投稿時間:2005/07/29(Fri) 13:35
投稿者名:はこ
Eメール:
URL :
タイトル:
Re: FMIFS.DLL の FormatEx API
Starfish 様

検証していただいた上にサンプルソースまで、どうもありがとうございます。
Starfishさんに検証していただいた方法は、魔界の仮面弁士さんにundocumentedって
言われた時点であきらめちゃってました。

こちらの状況はいまだ真っ暗闇です。
完成したら紹介させていただきますので、どうか気長にお待ちください。