- PR -

Windows Vistaでのraw I/Oの問題

1
投稿者投稿内容
まにゃの
会議室デビュー日: 2005/03/31
投稿数: 8
投稿日時: 2007-11-12 16:42
こんにちは。初めて書き込みします。

現在仕事でWindows Xpで動作していたアプリケーションの
Vista対応を進めています。
その中にコンパクトフラッシュにraw I/Oする箇所があり、
Win32 APIのWriteFile関数にて実行していますが、
Windows Vistaではデバイスのアクセス拒否にあい、
WriteFile関数がエラー応答となっていることが分かりました。

当初はWindows Vista UAC機能のせいと思いましたが、
Adminログイン、管理者権限でアプリケーションを実行
しても改善されません。

なお、ソースコードはコンパクトフラッシュのハンドルを
参照して、オープンし、書き込むという簡単なつくりなので
ソースコードが悪いとは思えません。
上記がソースコードの書き方が悪いだけだったら
改善すればよいのですが、その改善方法も見えず、
また、OSやデバイスドライバに依存する問題であれば
アプリケーション開発としては手を出せないことになります。

本件に関して何かご存知の方、アドバイスいただけたらと思います。
(Microsoftに質問したほうが良いのかもしれませんが、、、)
れい
ぬし
会議室デビュー日: 2005/11/01
投稿数: 346
投稿日時: 2007-11-12 21:17
引用:

まにゃのさんの書き込み (2007-11-12 16:42) より:
WriteFile関数がエラー応答となっていることが分かりました。
...
なお、ソースコードはコンパクトフラッシュのハンドルを
参照して、オープンし、書き込むという簡単なつくりなので
ソースコードが悪いとは思えません。



どのようなソースでしょうか。

VistaでWriteFileしてますが成功してます。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2007-11-12 22:19
引用:

まにゃのさんの書き込み (2007-11-12 16:42) より:
現在仕事でWindows Xpで動作していたアプリケーションの
Vista対応を進めています。
その中にコンパクトフラッシュにraw I/Oする箇所があり、
Win32 APIのWriteFile関数にて実行していますが、
Windows Vistaではデバイスのアクセス拒否にあい、
WriteFile関数がエラー応答となっていることが分かりました。


 他の質問/回答を参考にしていただけると大変ありがたいのですか、
このように「〜がエラーとなりました」とだけ書かれているものに対しては、
「エラーの内容、詳細を教えて下さい」と返ってくる場合がほとんどです。

 あなたの時間を無駄にしないためにも、エラーの内容、開発環境も明記して下さるようにお願いします。
まにゃの
会議室デビュー日: 2005/03/31
投稿数: 8
投稿日時: 2007-11-13 09:43
ご返答ありがとうございます。
ソースコードを載せていないのは不覚でした。申し訳ありません。

ソースコードはオープンソースとして配布?
されていたraw I/Oのソースコードを参考に作成しています。
開発環境はVC++ 6.0です。

------------------------------------------------------------------------
hDrive = CreateFile(drv_dev_name,
GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);

--- 中略(エラー処理) ---

if ((fd_img = _open(image_file, _O_RDONLY | _O_BINARY)) == -1 ) {
exit(-1);
}

img_len = _filelength(fd_img);

if(DeviceIoControl(hDrive, IOCTL_DISK_GET_DRIVE_GEOMETRY,
NULL,
0,
&dg_flop_geom,
sizeof(dg_flop_geom),
&dwNotUsed, NULL) == FALSE) {
CloseHandle(hDrive);
exit(-1);
}

--- 中略(エラー処理) ---

sects = dg_flop_geom.SectorsPerTrack;
sectsize = dg_flop_geom.BytesPerSector;
sect = 0;
buffer = (char *)malloc(sectsize);
if (SetFilePointer(hDrive, 0, NULL, FILE_BEGIN) == -1) {
exit(-1);
}

while ((count = _read(fd_img, buffer, sectsize)) > 0) {
bs_written += count;
percent = (float)bs_written / img_len;
percent = percent * 100;
if (SetFilePointer(hDrive, sect * sectsize, NULL, FILE_BEGIN) == -1) {
exit(-1);
}
if (WriteFile(hDrive, buffer, sectsize, &dwBsWritten, NULL) == 0) {
exit (-1);
}
sect++;
}

free(buffer);
CloseHandle(hDrive);
------------------------------------------------------------------------

上記のコードで最後のほうにあるWriteFile関数にて
戻り値を確認するとACCESS_DENY(つづりあっているか分かりませんが)
が発生して書き込みが停止していました。


以上です。
れい
ぬし
会議室デビュー日: 2005/11/01
投稿数: 346
投稿日時: 2007-11-15 01:35
引用:

ソースコードはオープンソースとして配布?
されていたraw I/Oのソースコードを参考に作成しています。



ぱっと見たところ、あちこち問題あるソースですね。
もし使い続けるなら気をつけてたほうがいいです。

で、問題になってる件ですが、
http://msdn2.microsoft.com/en-us/library/aa365747.aspx
に明記されてます。

アンマウントしてから書けってことですね。
まにゃの
会議室デビュー日: 2005/03/31
投稿数: 8
投稿日時: 2007-11-15 19:47
れい様
コメントありがとうございました。

確かにMSDNに理由が記載されていますね。
DeviceIoControlにてアンマウントしたらVistaでもうまくいきました。
ひとつ気になる点はWindows2000以降のOSでは必ず
アンマウントしなければならないのに2000/XPでは動作していた点です。
2000/XPではたまたまうまくいっていたと思っておこうと思いますが、、、


今回の件は私の調査方法が足りず、調査のアプローチ方法としても
大変勉強になりました。
どうもありがとうございました。
れい
ぬし
会議室デビュー日: 2005/11/01
投稿数: 346
投稿日時: 2007-11-15 23:20
引用:

まにゃのさんの書き込み (2007-11-15 19:47) より:
ひとつ気になる点はWindows2000以降のOSでは必ず
アンマウントしなければならないのに2000/XPでは動作していた点です。
2000/XPではたまたまうまくいっていたと思っておこうと思いますが、、、



たまたまではありません。

リンク先にはVista以降で変更になり、
アンマウントしなければ書けなくなったと
書いてあります。

2000以降とは一言も書いてありません。
まにゃの
会議室デビュー日: 2005/03/31
投稿数: 8
投稿日時: 2007-11-16 09:16
リンク先を再度読んでみました。
確かにれい様のおっしゃるとおりでした。

英語を読み飛ばしすぎて早合点してしまいました。
お恥ずかしい。
ご指摘、どうもありがとうございました。
1

スキルアップ/キャリアアップ(JOB@IT)