http://127.0.0.1/ のようなURLにキャッシュ可能な文書を置いてアクセスし、Temporary Internet Files に生成されるファイル名を確認すると、
- IE6 では、 127.0.0.1[1].txt となる
- IE7/8 では、 127_0_0_1[1].txt となる
なんて微妙な仕様変更。
http://127.0.0.1/ のようなURLにキャッシュ可能な文書を置いてアクセスし、Temporary Internet Files に生成されるファイル名を確認すると、
なんて微妙な仕様変更。
ffmpeg で -i オプションにワイルドカードを使ったらSDカード内のAVIがごっそり0バイトになって焦った。
ここは本気を出さねばならない。
selfImageで、メディアまるごとのバイナリイメージを取って、以下のコードを実行し、「”RIFF”から始まるファイル」に分割。なんせ元のファイルサイズが失われてるのでほんとはきちんとRIFFフォーマットを解析しなきゃならないのだが、面倒なので。
あとは、出来上がった「後ろにおまけのついた動画ファイル」を無理やり動画コンバータに放り込んで変換成功。
ふぅ、冷汗かいた。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
<span class="synType">int</span> _tmain(<span class="synType">int</span> argc, _TCHAR* argv[]) { <span class="synType">char</span> buf[BUF_SIZE]; <span class="synType">FILE</span>* fp; ::fopen_s(&fp, <span class="synConstant">"sd_card.img"</span>, <span class="synConstant">"rb"</span>); <span class="synType">FILE</span>* fOut=<span class="synConstant">NULL</span>; <span class="synType">int</span> count=<span class="synConstant">0</span>; <span class="synStatement">while</span>(!::feof(fp)){ ::fread(buf, <span class="synConstant">1</span>, BUF_SIZE, fp); <span class="synStatement">if</span>(fOut)::fwrite(buf, <span class="synConstant">1</span>, BUF_SIZE,fOut); <span class="synType">long</span> cur=<span class="synConstant">0</span>; <span class="synStatement">while</span>(cur<BUF_SIZE){ <span class="synType">const</span> <span class="synType">char</span>* pos=(<span class="synType">const</span> <span class="synType">char</span>*)::memchr(buf+cur, <span class="synConstant">'R'</span>, BUF_SIZE-cur); <span class="synStatement">if</span>(!pos){ <span class="synStatement">break</span>; } <span class="synStatement">if</span>(::memcmp(pos, <span class="synConstant">"RIFF"</span>, <span class="synConstant">4</span>)==<span class="synConstant">0</span>){ <span class="synStatement">if</span>(fOut)::fclose(fOut); <span class="synType">char</span> fname[<span class="synConstant">20</span>]; ::sprintf(fname, <span class="synConstant">"</span><span class="synSpecial">%d</span><span class="synConstant">.avi"</span>, count); fOut=::fopen(fname, <span class="synConstant">"wb"</span>); ::fwrite(pos, <span class="synConstant">1</span>, BUF_SIZE-(pos-buf), fOut); count++; } cur=pos-buf+<span class="synConstant">1</span>; } } <span class="synStatement">if</span>(fOut)::fclose(fOut); ::fclose(fp); <span class="synStatement">return</span> <span class="synConstant">0</span>; } |
きもーい。
Windows上でワイルドカードを処理するAPIがPathMatchSpecである。
http://msdn.microsoft.com/en-us/library/bb773727(VS.85).aspx
しかしここに載っているサンプルがあまりにもセンスが悪い。
ということでテストコードを書いた。コードは後述。結果は以下。
1 2 3 4 5 6 7 8 9 10 |
"somepath.html" , "somepath?html" => true "somepath.html" , "" => true "somepath.html" , "(null)" => false "" , "*" => true "" , "a" => false "somepath" , "*." => false "somepath" , "*.*" => true "hoge\fuga.html" , "hoge*" => true "hoge\fuga.html" , "hoge*html" => true "hoge\fuga.html" , "hoge\*" => true |
コードはこんな。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<span class="synPreProc">#include </span><span class="synConstant"><stdio.h></span> <span class="synPreProc">#include </span><span class="synConstant"><Shlwapi.h></span> <span class="synPreProc">#pragma comment(lib, </span><span class="synConstant">"shlwapi.lib"</span><span class="synPreProc">)</span> <span class="synType">void</span> test(<span class="synType">const</span> <span class="synType">wchar_t</span>* path, <span class="synType">const</span> <span class="synType">wchar_t</span>* spec){ wprintf(<span class="synConstant">L"</span><span class="synSpecial">\"%s\"</span><span class="synConstant"> , </span><span class="synSpecial">\"%s\"</span><span class="synConstant"> => </span><span class="synSpecial">%s\n</span><span class="synConstant">"</span> , path, spec , ::PathMatchSpec(path, spec)?<span class="synConstant">L"true"</span>:<span class="synConstant">L"false"</span>); } <span class="synType">int</span> main(<span class="synType">const</span> <span class="synType">int</span> &){ test(<span class="synConstant">L"somepath.html"</span>, <span class="synConstant">L"somepath?html"</span>); test(<span class="synConstant">L"somepath.html"</span>, <span class="synConstant">L""</span>); test(<span class="synConstant">L"somepath.html"</span>, <span class="synConstant">NULL</span>); test(<span class="synConstant">L""</span>, <span class="synConstant">L"*"</span>); test(<span class="synConstant">L""</span>, <span class="synConstant">L"a"</span>); test(<span class="synConstant">L"somepath"</span>, <span class="synConstant">L"*."</span>); test(<span class="synConstant">L"somepath"</span>, <span class="synConstant">L"*.*"</span>); test(<span class="synConstant">L"hoge</span><span class="synSpecial">\\</span><span class="synConstant">fuga.html"</span>, <span class="synConstant">L"hoge*"</span>); test(<span class="synConstant">L"hoge</span><span class="synSpecial">\\</span><span class="synConstant">fuga.html"</span>, <span class="synConstant">L"hoge*html"</span>); test(<span class="synConstant">L"hoge</span><span class="synSpecial">\\</span><span class="synConstant">fuga.html"</span>, <span class="synConstant">L"hoge</span><span class="synSpecial">\\</span><span class="synConstant">*"</span>); } |
なんだかいろんな人がいろんなことを言っているが、
に載っていたコードが実装しやすそうだったので入れてみたら直った。
一度直ればこっちのもんで、コード修正と実行を繰り返し、最終的に落ち着いたのは以下のコード。
1 2 3 4 5 6 7 8 9 10 |
LRESULT BrowserDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { <span class="synStatement">if</span>( (message==WM_SYSCOMMAND && wParam==SC_MINIMIZE) <span class="synComment">//最小化ボタン</span> || (message==WM_ACTIVATE && wParam==WA_INACTIVE) <span class="synComment">//フォーカスアウト</span> || (message==WM_SHOWWINDOW && wParam==FALSE) <span class="synComment">//不可視化</span> ){ ::SetFocus(<span class="synConstant">NULL</span>); } <span class="synStatement">return</span> CDialog::WindowProc(message, wParam, lParam); } |
IWebBrowserを乗っけたダイアログ上でJavaAppletを開き、アプレット上のUIをいじっているとメインスレッドがフリーズ。
なんだろうと思ってブレークをかけてみると、ダイアログの子要素に対してWM_GETDLGCODEがものすごい勢いで投げまくられている状態。
で、調査した。
WM_GETDLGCODEのなんたるか:
http://msdn.microsoft.com/ja-jp/library/ms645425
http://support.microsoft.com/kb/83302/en
タブコントロールを使っている場合に同じ状況に陥るケースが頻繁に報告されている。僕には関係ない。次。
http://blog.goo.ne.jp/satomi_takeo/e/b058ef705da6ca88ec87db660878c789
あたりっぽいんだが、リンク先サイトが死んでいて状況を追えず。次。
http://www.guyswithtowels.com/articles/2002-08-15-1600.html#ModelessDialogs
具体的なコードも出ていて助かる。が、メッセージポンプはMFC側にあるので、この通りに実装するの難しそう。
loadXMLを使うと encoding が期待通り処理されない。
以下のようにする。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
VARIANT var; { SAFEARRAYBOUND rgb={strlen(xml),<span class="synConstant">0</span>}; <span class="synComment">//末尾にNULL文字つけちゃだめ</span> SAFEARRAY* psa = SafeArrayCreate(VT_UI1,<span class="synConstant">1</span>, &rgb); <span class="synStatement">if</span>(!psa){ assert(<span class="synConstant">false</span>); <span class="synStatement">return</span> <span class="synConstant">false</span>; } <span class="synType">char</span>* buf; SafeArrayAccessData(psa,(<span class="synType">void</span>**)&buf); <span class="synComment">// 作成したSAFEARRAYのポインタ取得及びロック</span> memcpy(buf,xml,strlen(xml)); <span class="synComment">// 末尾のNULL文字分のバッファは無い!</span> SafeArrayUnaccessData(psa); <span class="synComment">// アンロック</span> var.vt=VT_ARRAY|VT_UI1; var.parray=psa; } <span class="synType">bool</span> ret=manifest->load(var); ::SafeArrayDestroy(var.parray); <span class="synStatement">if</span>(!ret){ ::OutputDebugString(manifest->GetparseError()->Getreason()); ::OutputDebugString(manifest->GetparseError()->GetsrcText()); <span class="synStatement">return</span> <span class="synConstant">false</span>; } |
末尾にNULLが付いているとパースエラーになるのが落とし穴。
IWebBrowserを乗っけたダイアログ上でTextFieldを含んだJavaAppletを開き、そのあたりをいじっているとメインスレッドがフリーズ。
なんだろうと思ってブレークをかけてみると、ダイアログの子要素に対してWM_GETDLGCODEがものすごい勢いで投げまくられている状態。
で、調査した。
WM_GETDLGCODEのなんたるか:
http://msdn.microsoft.com/ja-jp/library/ms645425
http://support.microsoft.com/kb/83302/en
タブコントロールを使っている場合に同じ状況に陥るケースが頻繁に報告されている。僕には関係ない。次。
http://blog.goo.ne.jp/satomi_takeo/e/b058ef705da6ca88ec87db660878c789
あたりっぽいんだが、リンク先サイトが死んでいて状況を追えず。次。
http://www.guyswithtowels.com/articles/2002-08-15-1600.html#ModelessDialogs
具体的なコードも出ていて助かる。が、メッセージポンプはMFC側にあるので、この通りに実装するの難しそう。
複数のプロセスをまとめて管理する仕組みとしてJobObjectというものがある。
http://msdn.microsoft.com/en-us/library/ms684161(VS.85).aspx
POSIX準拠の仕組みらしく、古くはapacheのようなヤツがいくつかのプロセスを立ち上げて堅牢性を向上させていたり、最近はGoogle Chromeなどでも使われている。
SetInformationJobObject のリファレンスを見ると、
http://msdn.microsoft.com/en-us/library/ms686216(VS.85).aspx
JobObjectに対して様々な制約をかけることができることが分かる。
例えば、総プロセッサ時間、総メモリ消費量のようなものだ。
その他に、JOB_OBJECT_UILIMIT_DISPLAYSETTINGS, JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS のようなものもあり、ジョブ配下のプロセスがシステム全体に影響を及ぼすことがないようにする仕組みと考えられる。
VISTAではすべてのプロセスは Explorer のジョブグループに属してしまうようだ。(しかもProcessExplorerでも見えない?)
CREATE_BREAKAWAY_FROM_JOB を使って新規プロセスを作ると、そこでは AssignProcessToJobObject が成功する。
UACのせいだとかいろんなことを言っている人がいるが、たぶん間違い。
だって REATE_BREAKAWAY_FROM_JOB だけで出来たもん。
で、どこにも書いてないけどほかにも様々な壁があるっぽい。