• 締切済み

DeviceIoControlを使って、フロッピーをフォーマットするには?

初めて質問します。よろしくお願いします。 フロッピーをフォーマットするDLLを作っているのですが、DeviceIoControlを使ってフロッピーを 1.44M 512バイト/セクタにフォーマットするにはどうすればいいのでしょうか? 下記のようにコーディングしてみたのですがどうもうまくいきません。 DeviceIoControlは正常終了するのですが、フォーマットした(つもり)のフロッピーをエクスプローラで読もうとすると“このボリュームは認識可能なファイルシステムではありません。”と表示されてしまいます。 エクスプローラでフォーマットした時と比べ、DeviceIoControlが動作している時間が短いのでこの他に手順が必要なのかとも思ったのですが、それらしいのは見当たらず困っています。よろしくお願いします。 hFD = CreateFile( "\\\\.\\a:", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); FormatPara.MediaType = F3_1Pt44_512; FormatPara.StartCylinderNumber = 0; FormatPara.EndCylinderNumber = 79; FormatPara.StartHeadNumber = 0; FormatPara.EndHeadNumber = 1; bRet = DeviceIoControl( hFD, IOCTL_DISK_FORMAT_TRACKS, &FormatPara, sizeof(FormatPara), NULL, 0, &dwTempSize, NULL );

みんなの回答

noname#30727
noname#30727
回答No.2

No.1ですが、補足します。 プログラムのバグによって大変なことになりますから、 SHFormatDriveを呼び出しているプログラムを他人に配布する事は、自分を守る意味でも、『絶対』にやらないほうがいいですよ。

bow2001
質問者

お礼

回答頂き、ありがとうございます。 DeviceIoControlでのフロッピーのフォーマットは大変そうですね。 SHFormatDriveも含めて他の方法を検討してみますが、 “SHFormatDriveを呼び出しているプログラムを他人に配布する事は、~『絶対』にやらないほうがいいですよ。”とは、 “フォーマットするようなプログラムは気軽に配布すべきではない”ということでしょうか? 確かに、そうかもしれません。もうちょっといろいろ考えてみます。 ありがとうございました。 (御礼が遅くなり、申し訳ありませんでした。)

noname#30727
noname#30727
回答No.1

IOCTL_DISK_FORMAT_TRACKS では、物理フォーマットしかできないのが原因です。FAT12の論理フェーマットは自力でやる必要があります。 水をさす事になるので、書き込むのをためらっていたのですが、あえてフォーマットをするのでしたら、SHFormatDrive を呼び出すべきです。 VC++のMSDNだと、キーワードでは出てこないので、検索してみてください。

関連するQ&A

  • フロッピーセクタアクセスに関して

    初めてお目にかかります。 今、PC98で書き込みを行ったフロッピーディスクを読み取るプログラムを作成しています。 インターネットにて調べて見ましたが、うまくいかない状態です。 問題点等あれば教えていただきたいと思います。 実行環境:Windows XP SP2 ドライブ:LOGITEC LFD-31U4 (USB:3モード) 開発言語:VC++(VS2005にて) BOOL Direct_Drive_Access(char *Drive){   HANDLE hHandle;   DISK_GEOMETRY disket;   DWORD dw1;   BOOL ret;   //ハンドルの取得   hHandle = CreateFile(Drive,GENERIC_READ , FILE_SHARE_READ,NULL,OPEN_EXISTING, NULL, NULL);   if ( hHandle != INVALID_HANDLE_VALUE ){     //FDの情報を取得     ret = DeviceIoControl(hHandle,IOCTL_DISK_GET_DRIVE_GEOMETRY,NULL,0,&disket,sizeof(disket),&dw1,NULL);     if (!ret) return FALSE;   } } 上記のソースにて取得したdisketの内容が、1.44MBのフロッピーでした。 (この情報だと、次のReadFile関数で"1785:フォーマットされていません"のエラーが返ります) 実際は、Cylinder - 77 Track - 2 Sector - 26 Byte - 256 でフォーマットしているフロッピーです。 BIOS経由のアクセスも調べましたが、32bitOSのため、使用できない様でした。 これから何を調べていいかも分からない状態なので、アドバイスをお願いします。

  • 実行時にエラーが出ます(;。;)

    hFile = CreateFile("1.txt",GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL, NULL); この文章で実行時エラーが出ます。初心者なのでよろしくお願いします。 C言語です。

  • CreateFileしてからtruncate

    ファイルデータを置換するプログラムを作っています。 短い文字に置換すると、ファイルサイズは小さくなります。 ところが、今のソースではファイルサイズ小さくなりません。 「abcdefg」のテスト中の「cde」を「H」に置換すると 「abHfgxx」になってしまいます。 ・hfile = CreateFile("test.txt", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); ・読む ・置換 ・上書き ・CloseHandle(hfile); というステップです。 ・読む の直後に、text.txtを0バイトにしたいんですが、 hfileを閉じないで、Perlのtruncateのようなことはできませんか?

  • 【C言語】引数にファイルパスを送りたい

    DLLで外部のファイルサイズを得る関数を作っています。 C言語は書きながら覚えていこうとしているのですが、 どうしても分からない点がありました。 ソースをここに正しく書ける自信がないので日本語を含めて大体で書きます。 いろいろなサイトのコピペです。 double __stdcall filesize(){ HANDLE hFile; DWORD size; hFile = CreateFile( _T(絶対パス, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); size = GetFileSize( hFile, NULL ); CloseHandle( hFile ); return(size); } このような感じで書いていて最後にretuenでファイルサイズを正しく得ることができました。 この絶対パスは環境によって変わるので引数にしようと考えました。 そしてfilesize()の中にどのように記述すればいいかで躓いています。 filesize(絶対パス){ char pass[] = "絶対パス"; hFile = CreateFile( _T(pass, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); こんな感じで書ければいいのですがC言語はポインタや文字列の扱いが難しいですね。 初歩的なことで申し訳ありませんがよろしくお願いします。

  • Visual C++で

    VisualC++を使って、ファイルにint型の二次元配列を書き込みたいのですが、WriteFile関数を使えばよいのかな?というところまではわかったのですが、二番目の引数を"int"型から"LPCVOID"型に変形できませんと言われてしまいます。 雰囲気的には下のような感じになるのかなぁー、と思いましたが、わかりません。教えてください。お願いします。 fp = CreateFile("test.dat", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); for(i = 0; i < 100; i++){ for(j = 0; j < 100; j++){ WriteFile(fp, array[i][j], sizeof(array), &dwRote, NULL); } }

  • 非同期のプロセス間通信(パイプ)で全データ受信する

    こんにちは。 非同期のプロセス間通信(パイプ)で詰まっています。 環境はWindowsで処理系はC++(Win32)です。 スレッドを用意して、 hPipe = ::CreateFile( L"\\\\.\\pipe\\pipename", GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL ) ; で作成し、OVERLAPPED構造体を // ZeroMemory( &so, sizeof( OVERLAPPED )) ; sOverlapped.hEvent = ::CreateEvent( NULL, FALSE, FALSE, NULL ) ; として、 const size_t bufsize = 16 ; BYTE     buffer[ uBufSize ] ; DWORD    dwNumberOfBytesRead ; bRet = ::ReadFile( hPipe, buffer, bufsize, &dwNumberOfBytesRead, &so ) ; で読み込みをしています。ReadFile関数はすぐ戻りbRetはFALSEで返ってくるため、GetLastErrorを調べて、 switch( ::GetLastError()) {   case ERROR_IO_PENDING :     bRet = ::GetOverlappedResult( hPipe, &so, &dwNumberOfBytesRead, FALSE ) ;     break ; } としてWaitForMultipleObjectsでsOverlapped.hEventがシグナル状態になったら取得したデータの処理をしています。 シグナル状態になるならないに関わらず、上記のReadFileとGetOverlappedResultはループでぐるぐる回しています。 上記の状態で短いデータならよかったのですが、上記のReadFileで読み込み最大サイズの16バイトを超えてしまとうと、 残りの部分のみしか取得できませんでした。 0123456789ABCDEFabcdefg というデータを受信しようとしたとき、後半のabcdefgだけしか取得できませんでした。 すべてのデータを正しく取得するにはどのようにしたらよいのでしょうか?

  • メモリに読み込んだ音源のPlaySoundによる再生

    HANDLE fh,fh2; DWORD dummy,dummy2; case WM_CREATE: fh=CreateFile(TEXT("F:\\shot.wav"),GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); /* ファイルオープン */ fh2=CreateFile(TEXT("F:\\ENDING.WAV"),GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); /* ファイルオープン */ /* バッファ確保 */ lpSound = GlobalAlloc(GPTR,GetFileSize(fh,NULL)); lpSound2 = GlobalAlloc(GPTR,GetFileSize(fh2,NULL)); ReadFile(fh ,lpSound ,GetFileSize(fh ,NULL),&dummy ,NULL); /* 読み込み */ ReadFile(fh2,lpSound2,GetFileSize(fh2,NULL),&dummy2,NULL); /* 読み込み */ CloseHandle(fh); CloseHandle(fh2); として音源をメモリに読み込み、その後イベント発生時にPlaySound関数で音源をならしているのですが、 PlaySound(lpSound,NULL,SND_ASYNC|SND_MEMORY); 一番最初のイベント発生時に音源読み込みに時間が掛かり即座に鳴りません。次のイベント発生時は同時に鳴るのですが.... 一番最初から同時に鳴らすにはどのようにしたら良いでしょうか? 根本的にPlaySound関数では良くないのでしょうか? 御指導の程よろしくお願いします。

  • Win32でシリアル通信

    現在.NET2003のWin32を使ってシリアル通信を行うプログラムを作成中なんですが、CreateFile()、WriteFile()といった関数を使っているのですがどうもうまくいきません。 どなたかWin32について詳しい方、ご教授頂けないでしょうか?また、こういった事が書いているHP等をご存知の方教えて頂けないでしょうか? ちなみに、ポートを開く部分は下記のようになっているのですが、何か間違いがあれば教えて下さい。 お願い致します。 /* シリアルポートを開く */ BOOL SerialOpenPort(int nPortNumber) { char szSerial[256]; if(g_ahSerial[nPortNumber - 1] != NULL) { return FALSE; } sprintf(szSerial, "COM%d", nPortNumber); g_ahSerial[nPortNumber - 1] = CreateFile( szSerial, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );   if(g_ahSerial[nPortNumber - 1] == INVALID_HANDLE_VALUE) { g_ahSerial[nPortNumber - 1] = NULL; return FALSE; } if(!InitDCB(nPortNumber)) { return FALSE; }  if(!InitCommTimeOuts(nPortNumber)) { return FALSE; }  return TRUE; }

  • SMART情報

    OS:Windows7 VS2008 SP1 http://www.usefullcode.net/2007/02/hdd.htmlをみて SMART情報を取得するプログラムを書いています http://www.usefullcode.net/2007/02/hdd.htmlの下の方からプロジェクトがDLできて 試しにビルドして(通りました) 実行してみたのですが、 //OSによってCreateFile処理を変える if(sVerInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) { hIoCtrl = ::CreateFile(_T("\\\\.\\SMARTVSD"), 0,0,0,CREATE_NEW, 0, 0); //Windows 9x } else { CAtlString strDevice; strDevice.Format(_T("\\\\.\\PhysicalDrive%d"),nDeviceNo); hIoCtrl = ::CreateFile(strDevice,GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL); int Error=0; Error=GetLastError(); char DebugStr[256]; wsprintf(DebugStr,"Error=%d",Error); MessageBox(NULL,DebugStr,"File Error",MB_OK); } if(hIoCtrl == INVALID_HANDLE_VALUE) { MessageBox(NULL,"hIoCtrl == INVALID_HANDLE_VALUE Error","hIoCtrl == INVALID_HANDLE_VALUE Error",MB_OK); return false;//********ここでfalseでreturnされてしまう。********* } ここでCreateFileエラーがでてしまい(GetLastError=2です。) falseでreturnされてしまい、うまくHDD情報が取得できません。 そもそもstrDevice.Format(_T("\\\\.\\PhysicalDrive%d"),nDeviceNo);の第一引数が_T("\\\\.\\PhysicalDrive%d")と指定されていますが、 ここには何を指定すべきなのでしょうか。これが分かればできそうな気がします。

  • CreateFileしてもうまくいきません・・。

    シリアルポートで通信するためのプログラミングを始めたばかりなのですが、COMポートのオープンが成功しません。 以下を実行しているのですが、何が間違いでしょうか? ちなみに、PCMCIAに挿入したPCカードから通信したいと考えています。単純に"COM1"というのであっているのかも分かりません・・。 よろしくお願いします。 void CMyDlg::OnReset() { HANDLE hCom; hCom = CreateFile( "COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED NULL ); if(hCom == INVALID_HANDLE_VALUE){ MessageBox("ポートオープン失敗"); } else{ MessageBox("ポートオープン成功"); } }

専門家に質問してみよう