CreateFile関数によるCD/DVDへの書込み方法

このQ&Aのポイント
  • VCプログラムで、操作履歴情報を出力先ドライブを選択してファイルに保存する機能を作成しています。(OS:Windows-XP)
  • CD-ROM(RW)ドライブを選択すると、以下のエラーになってしまうのですが、正しい引数または別の方法を教えて頂けませんでしょうか。ERROR_INVALID_FUNCTION(0x00000001)「ファンクションが間違っています。」
  • 以上、宜しくお願い致します!
回答を見る
  • ベストアンサー

CreateFile関数によるCD/DVDへの書込み方法を教えて下さい

VCプログラムで、操作履歴情報を出力先ドライブを選択してファイルに保存する機能を作成しています。(OS:Windows-XP) CD-ROM(RW)ドライブを選択すると、以下のエラーになってしまうのですが、 正しい引数または別の方法を教えて頂けませんでしょうか。 ◆エラー ERROR_INVALID_FUNCTION(0x00000001)「ファンクションが間違っています。」 ◆引数 handle = CreateFile( "\\\\.\\E:\\HISmmdd.TXT",// ファイル名 GENERIC_WRITE, // アクセスモード FILE_SHARE_WRITE, // 共有モード NULL, // セキュリティ記述子 CREATE_ALWAYS, // 作成方法 FILE_FLAG_WRITE_THROUGH,// ファイル属性 NULL // テンプレートファイルのハンドル ) ; 以上、宜しくお願い致します!

質問者が選んだベストアンサー

  • ベストアンサー
  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.1

CD/DVDは、通常のAPI関数では書き込み出来ません。 CD/DVDへの書き込みは「IMAPI(Windows Image Mastering API)」と言う、専用のAPIを使用する必要があります。 CreateFileなど、通常のAPI関数では、書き込む事は出来ません。 また、ネットワーク共有で共有された他のPCのCD/DVDドライブは、IMAPIを使用しても書き込む事は出来ません。IMAPIで書き込み出来るのは「自分自身のCD/DVDドライブだけ」です。 どうやら、質問者さんは「ネットワークごしにCD-R/DVD-Rに書き込もうとしている」ので、現状では「何をどうやっても不可能」です。 唯一の方法は ・CD-R/DVD-Rを搭載したPCに、監視用の常駐プログラムを常駐させる ・ネットワーク共有で別のPCから特定のフォルダに、書き込みたいファイルを置く ・何らかの方法で、別のPCから常駐プログラムに「書き込み」の指令を送る ・常駐プログラムから、IMAPIを使ってファイルをCD-R/DVD-Rに書き込むプログラムを起動する ・起動された書き込みプログラムは、特定のフォルダに置かれたファイルを書き込みし、書き込みが終了したら、書き終わったファイルを特定のフォルダから削除して後始末する という方法です。

itotyun
質問者

補足

素早く、丁寧なご回答をありがとうございます。 「IMAPI」について、調べてみます。 言葉足らずで申し訳ありません。 出力先は「自分自分のCD/DVDドライブ」だけです。 アプリケーションから直接書き込む方法以外に、 一時ファイルを作成して、常駐プログラムで監視して書き込みプログラムを起動する、という考え方もあるんですね。 今後の設計の参考にさせて頂きます。 ありがとうございます。

関連するQ&A

  • 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("ポートオープン成功"); } }

  • CreateFile関数を用いたファイル作成について

    VisualC++のCreateFile関数を用いて「作成日時が1週間前であれば ファイルをリネームして保存後、以前のファイル名で 空ファイルを作成する」という処理を作っています。 (作成中の関数の抜粋) /* リネーム処理 */ ret_code = MoveFile(logfile_path, rename_path); if(ret_code == API_NG){ return(NG); } /* 以前と同じ名前でファイルを新規作成 */ hfile = CreateFile(logfile_path, GENERIC_WRITE,FILE_SHARE_WRITE, NULL,CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, FILE_FLAG_NO_BUFFERING); if( hfile == INVALID_HANDLE_VALUE ) { return(NG); } CloseHandle(hfile); } return(OK); } リネームする以前と同じ名前でファイルを作成すると ファイルの作成日時がリネームする以前の作成日時になってしまいます。 (例) 4月1日に「aaa.txt」を作成→ 4月8日に「aaa_0401.txt」にリネーム後、新規に「aaa.txt」を作成すると 作成日時が「4月1日」になってしまう。 Microsoftのページによると、キャッシュファイルの情報を取得しているために 以前の作成日時にてファイルが作成されてしまうようです。 http://www.microsoft.com/JAPAN/developer/library/jpwinpf/_win32_createfile.htm 原因は分かったのですが、対処方法が思い浮かびません。 上記問題を解決するにはどういった方法がありますでしょうか? ご教授をよろしくお願いします。

  • 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のようなことはできませんか?

  • CreateFile が ERROR_PATH_NOT_FOUND のエラーになる

    VC++を使っています。OSは Windows2000 です。 CreateFile で指定するファイル名をフルパスで指定し、EXEを同じ ディレクトリに置いて実行したところエラーとなり、詳細コードが ERROR_PATH_NOT_FOUND でした。 プログラムは以下のようになっています。 #define AAA "c:winnt\\system32\\AAA.log" hOpen = CreateFile( AAA, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 上記プログラムの AAA.exe を system32下に置いて実行すると、 パスが不正だと怒られてしまいます。。。 AAA.exe を別ディレクトリで実行すると、sysytem32下にちゃんと ファイルが作成されます。 AAA.exe を CreateProcess する BBB.exe を造って試しましたが、 やはり BBB.exe が system32下にあると駄目でした。 どうやらカレントディレクトリが同じだと駄目みたいです。 「"AAA.log"」とせずにフルパスとしているのは以下の理由のためです。 ・ファイルは必ず system32下に作成したい。 ・AAA.exe は必ず system32下にある。 しかし、BBB.exe が必ず system32下にあるとは限らないため、 「"AAA.log"」とした場合、BBB.exe を実行したディレクトリに 作成されてしまう。 CreateFile には今回のような制限があるのでしょうか??? #ヘルプを見る限り、書いてないです。。。

  • 大きなファイルの読み書き

    WindowsXP + SDKにてC++の開発をしています。 ディスクから50MB程度のファイルを読んで処理を施しまた書き戻すという事をやっていますが HANDLE handle; char fileName[256]; strcpy(fileName , "ファイル名"); handle = CreateFile(fileName , GENERIC_READ , NULL , NULL , OPEN_EXISTING , FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED | FILE_ATTRIBUTE_NORMAL ,NULL); としてファイルのオープンには成功するのですが OVERLAPPED ol; unsigned long size; unsigned long readSize; unsigned char *mem; ReadFile(handle , mem , readSize , &size , &ol) としていざ読もうとすると "ERROR_NO_SYSTEM_RESOURCES"が戻ってきて処理がとまってしまいます。 今までまったく同じコードで1~12MB程度のファイルは問題なく読み書き出来ていたのですが50Mのファイルを扱おうとしたところ問題が発生してしまいました。 FILE_FLAG_NO_BUFFERING と FILE_FLAG_OVERLAPPEDをはずすと読めるのですが余りにもアクセスが遅いので使い物になりません。 何か回避方法がありましたら御教授願います。

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

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

  • 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ポートが開けない

    以下の手順でCOMポートをオープンすると、(4)のCOMオープンが必ず失敗します。 GetLastError関数でエラーコードを取得するとERROR_FILE_NOT_FOUNDが返ってきました。 心優しい方、(4)のCOMオープンを成功させる方法を教えていただけないでしょうか? (1)CreateFile関数でCOMポートをオープンし、オープン中にUSBを抜き差しする。 (2)PurgeComm関数で送受信バッファをクリア (3)CloseHandle関数でCOMポートのハンドルをクローズ (4)CreateFile関数でCOMポートを再度オープン←NG 以上、どうぞよろしくお願いいたします。

  • 【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言語はポインタや文字列の扱いが難しいですね。 初歩的なことで申し訳ありませんがよろしくお願いします。

  • シリアル通信の出力バッファと送信完了イベントについて

    こんにちわ。よろしくお願いします。 どの言語として扱うか迷ったのですが、恐らくはC/C++が一番だろうと思ってここで質問させていただきます。 質問の内容ですが、現在、シリアル通信のアプリケーションを作っていまして、CreateFileの引数にFILE_FLAG_OVERLAPPEDを与えて非同期で読み書きを行うようにしています。 非同期ですので、OVERLAPPED構造体をstaticで宣言し、 WriteFile時に引数で与えています。 --- m_hComm = CreateFile( (const char*)pCom, GENERIC_READ|GENERIC_WRITE,0, NULL,OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL ) ; WriteFile(m_hComm, pwData,dwLen, &dwWrite, &osWriter); --- 問題はここからで、OVERLAPPED構造体のイベントが、シグナル状態になり、GetOverlappedResult(m_hComm, &osWriter, &dwWrite, TRUE)を抜けるのはいいのですが、実際には送信は完了しておらず、GetCommStateで通信速度を変更すると送信途中のデータが化けて通信エラーになってしまいます。 どうやら、今使用しているPCのUARTの出力バッファが大きいのか、Windows側のバッファからUARTバッファに書き込みが完了した時点でWindowsはOVERLAPPED構造体のイベントをシグナルにしているようです。 (もちろんFIFOは切ってあります) 他のPCで確認したところ、問題ありませんでした。 もしどなたか、シリアルの出力バッファを監視するいい方法があったら教えていただけないでしょうか。

専門家に質問してみよう