格闘三日。リセットせずにUSBの機能を切り替えるUSB SelectのVer 0.90を、ここに公開します。実行には、.NET Compact Framework 2.0と、何が起きても動じない勇気と、自己責任が必要です。ぶっちゃけ、レジストリは触るわ、デバイスにけったいなioctlは発呼するわ、とてもじゃないけれど、データが消えたりシステムが立ち上がらなくなったりする被害が起きても、全く責任なんて取れないからです。
これらの、条件を満たす方は、こちらからダウンロードしてください。W-ZERO3でしか動作検証していませんが、大抵のUSB機能を持ったWndows Mobile 5.0で動作すると思います。思っているだけで、動かなくても責任は負えません。なお、このソフトは、フリーソフトとします。
レジストリの書き換えは、先に書いたとおりに、瞬殺でしたが、その先が長かったです。まず、既にご存知のように、IOCTL_UFN_CHANGE_CURRENT_CLIENTの値と、UFN_CLIENT_INFOの中身がわからないという件。これにはシェクまくさんからいただいた情報が大変に役に立ちました。この場を借りて感謝の意を表します。とっとと買ってください(それが、感謝している態度か!? > オレ)
次に悩んだのは、楽して、C#.NETで始めてしまったので、Win32に属する低レベルなシステムコールをどうするかということです。一瞬、このあたりの処理を、Win32プロジェクトでDLLとしてまとめて……と思って、実際、DLLを作りかけたのですが、Visual Studioに不慣れな身は、デバッグ時に、この別々のプロジェクト(ソリューションは一緒にしてありますが)をどうやって強調動作するように出来るのかがわからず頓挫。
しかし、捨てる神あれば拾う神アリ。C#.NETにも、抜け道があるじゃないですか。Win32の低レベルなAPIを呼び出すすべがちゃんと用意してありました。
public static extern bool DeviceIoControl(IntPtr handle,
uint dwCommand,
IntPtr lpInBuffer,
uint nInBufferSize,
IntPtr lpOutBuffer,
uint nOutBufferSize,
ref uint lpnOutputSize,
IntPtrlpOverruped);
と、こんな感じで必要な関数を、次々と宣言して、実行。あり、ioctlが失敗する……。それも、ERROR_INVALID_HANDLEとかじゃなくて、ERROR_INVALID_PARAMETERSで、です。これが出るのは、正しい引数がわたっていないときのはず。ここまでたどり着いたのが、土曜日の朝で、ここからほぼ丸二日、この問題と格闘することになりました。
結論から言えば、MDD層で処理されるべきioctlがPDD層まで行ってしまっていたようなのです。さらに、ごにょごにょと調べると、そうなるのは、デバイスドライバを CreateFile()で開くときに、FILE_WRITE_ATTRIBUTEを指定しないとき、というのがわかりました。ここには、単にGENERIC_WRITE|GENERIC_READを指定していただけだったのですから、正しく動作しないのは当然です。でも、そんなこと、書いてあるところ見つけられなかったヨ oTL
適切なパーミッションで開いたデバイスには、あっさりと変更コマンドが通りました。めでたしめでたし。というわけで、動いてしまえば後は、一瞬のことでした。
現状でわかっている問題点は次のようなものがあります。- インストールすると、古いOS向けだといわれる。
→Visual Studio 2005 Standard製品版を買ったら消せる予定。 - インストールすると、スタートメニューの直下にリンクを作る。
→控えめに、「プログラム」フォルダの下に引っ越したいのですが、やり方がわかりません。 - Mass Storageから、他に切り替えると、「画像メモリ カードが挿入されました」とかいうダイアログが出る。
→たまには画像の棚卸でもしてやってください。 - ドキュメントの一つもない。
→ごめんなさい。正式版の時点でつけたいと思います。 - 画面のレイアウトがださい。
→一応、縦横、どちらでも操作できるようにしてあるのですが、不慣れなもので。 - 胡散臭い
→マイクロソフトのUSB Mass Storageのドライバに「サンプルだから」とか「idProductを変えろよ」とか書いてあり、そいつからして胡散臭いので、これ以上はどうにもならないかもしれません。 - USB Serialはなぜリストに出てこない?
→あ、あるのお気づきですか。正式版の時点では入れようかと思います。 - コントロールパネルアプレットではない。
→すんません。C#.NETで、アプレットにする方法を編み出したらそうします。 - 起動が遅い。
→.NETアプリはみんなそうなんです。
himazu
おめでとうございます。雑誌の記事にネタにできますね。W-ZERO3のためなら、.NETプログラミングも厭わないけど、やったことないしなあ、という人は世の中結構いるのでは。
hiro
ありがとうございます。himazuさんにも、助けてメールを投げたりして、具合が悪かったのに、すみませんでした。
皆さんのオカゲサマで、一応かたちになりました。
.NETに関しては、C#が良く出来ているので、非常におき楽にプログラムができました。C++を知っているヒトはほとんど違和感なく、移行できそうです。またIDEの補完機能もうざい時もありますが、初心者には大助かりでした。
C#にゃ、ポインタもないので妙なバグの温床もなくていいや……と、思っていたのですが、DllImportやMarsharlとかいう暗黒面を使ったら、バリバリ、ポインタ地獄に落とされました。
例外吐いて、何度死なれたことか…… oTL
既に、暗黒C#プログラマとなってしまったワタシにアシタはあるのか!?
シェクまく
お役にたててなによりです。
「IOCTL_UFN_CHANGE_CURRENT_CLIENT」でぐぐるとココがHitするようになりましたよ。日本唯一の「IOCTL_UFN_CHANGE_CURRENT_CLIENT」情報発信源という事ですね(笑)
インストーラについてはこのあたりを参考にしてみてください。
http://www.microsoft.com/japan/windowsmobile/pocketpc/techpapers/techguide/guide_4.asp
C#はちょっと見た事しかないのですが、VBをベースにCのニュアンスを詰め込んだイメージを持っています。よくできてると思います。ええ。
hiro
あああっ、ナニからナニまで……。%CE11%ですか。コレが知りたかったんですよ。VS2005のCABプロジェクトは少し違っていて、手で.infを作る必要はないんですが、これは使えそうです。
あとは、日本語を含められない問題をどうにかできれば……ってコレは製品版を待てってことかな?