プログラミングの最近のブログ記事

Vistaのデスクトップアイコンにチェックボックスを表示できますが、似たような操作性のものを作ってみました。

つまり、チェックボックスでも、Ctrlクリックでも複数選択ができるというものです。

Ctrlキーの状態によってチェックボックスへの反映を止めているのがポイントで、これをしないとCtrl+スペースが押された時に選択できなくなります。

WM_NOTIFY処理の抜粋
case LVN_ITEMCHANGED:
  pnmlist = (LPNMLISTVIEW)lParam;
  if ( ( pnmlist->uNewState & LVIS_STATEIMAGEMASK ) == 0 ) {
    SHORT ctrlState = GetKeyState( VK_CONTROL );
    if ( ListView_GetItemState( hList, pnmlist->iItem, LVIS_SELECTED ) ) {
      if ( ( ctrlState >= 0 ) ||
        ( ( ctrlState < 0 ) && ( !ListView_GetItemState( hList, pnmlist->iItem, LVIS_FOCUSED ) ) ) ) {
        ListView_SetCheckState( hList, pnmlist->iItem, TRUE );
      }
    }
    else {
      if ( ( ctrlState >= 0 ) ||
        ( ( ctrlState < 0 ) && ( !ListView_GetItemState( hList, pnmlist->iItem, LVIS_FOCUSED ) ) ) ) {
        ListView_SetCheckState( hList, pnmlist->iItem, FALSE );
      }
    }
  }
  else {
    if ( ( pnmlist->uNewState & LVIS_STATEIMAGEMASK ) == INDEXTOSTATEIMAGEMASK(2) ) {
      ListView_SetItemState( hList, pnmlist->iItem, LVIS_SELECTED, LVIS_SELECTED );
    }
    else {
      ListView_SetItemState( hList, pnmlist->iItem, 0, LVIS_SELECTED );
    }
  }
  break;

SHA-2とCryptAPI

| コメント(0) | トラックバック(0)
CryptAPIでハッシュを計算させようとすると、巷に多いサンプルコードではCryptAcquireContextでPROV_RSA_FULLを渡していますが、これだとSHA-2に対応していません。

MSDNのブログにも書かれていますが、PROV_RSA_AESを渡せばCALG_SHA_256等が通るようになります。XP SP3以降に限定されますが。

エラーチェック無しでこんな感じです。
CryptAcquireContext( &hProv, NULL, NULL, PROV_RSA_AES, 0 );
CryptCreateHash( hProv, CALG_SHA_256, 0, 0, &hHash );
CryptHashData( hHash, src, 1024, 0 );
len = 32;
CryptGetHashParam( hHash, HP_HASHVAL, hash, &len, 0 );
CryptDestroyHash( hHash );
CryptReleaseContext( hProv, 0 );

MSDNの原文ポップアップ

| コメント(0) | トラックバック(0)
Web版MSDNライブラリは現在、リクエストの度に機械翻訳されるようになっているようです。キャッシュはあるとしても、最新翻訳エンジンの恩恵を受けられます。

これにありがた迷惑2対8ぐらいの機能がありまして、マウスポインタを重ねた部分の原文が、ポップアップで表示されるのです。消す方法はありません。

上側に表示されるので、テキストを選択しようと下からポインタを移動させていくと邪魔なのです。Visual Studioのバージョン選択(「その他のバージョン」プルダウン)も邪魔されます。

ストレスです。何度かフィードバックを送りましたが、いつ改善されるのやら。

というわけで、Adblock Plusに下記の設定を追加。

msdn.microsoft.com##.MTPopup

原文と比較したければ、タブ切り替えかウィンドウを並べるか勝手にするんですよ。こんな邪魔なUIよく大々的に投入したものです。

TS Demux for D-VHS Ver.0.5

| コメント(0) | トラックバック(0)
dvhsdemux.png音声の時間差出力までできるようになりました。またwav出力が壊れることがあるバグを修正しました。
DVHSDemuxer Ver.0.5

ビデオのストリームは最初のIフレームまで飛ばし、MP2とPCMを含めた他のストリームは、その直後のPESパケットから出力しています。TSDemux 0.18よりPESパケット1個分長く出ていますが、ビデオは全くの同サイズです。TSDemuxが切りすぎ?

時間差は最初に出力したパケットのPTS同士の比較によるものですが、ログファイルへの出力としています。これはTMPGEng Authoring Worksの仕様に合わせたもので、TSDemuxのようにファイル名を変えると、m2vをドロップしてもwavが自動では読まれないためです。

TSのDemuxを考える

| コメント(0) | トラックバック(0)
DVHSDemuxerをいじっています。

continuity_counterを利用して、パケットロストで異常終了させるようにはしてみました。なぜかboolになっていたので修正した上で。

あとはTSDemuxがやっていたように、MP2/LPCM各ストリームの遅延時間を取り出したいのですが、PTS/DTSあたりを参照しているのかどうか。

とりあえずTSDemuxと冒頭のサイズが異なるのは、GOPを調べて最初のIフレームまで飛ばしているようでした。
MP2もLPCMも、それ以後のものでした。従って、ともかく最初のIフレームまで飛ばせば同じ出力になります。

しかし真面目に解析するのは骨が折れます。シーケンスヘッダとピクチャースタートコードを探すだけの簡易解析で行けるかどうか、やってみましょうか。

ないないアルよ~

| コメント(0) | トラックバック(0)
BUG: 未処理の例外フィルターがデバッガー内呼び出されますされません。

いくら機械翻訳といってもこれは酷くないでしょうか。

原語は「BUG: Unhandled exception filter not called inside debugger」で、見出しなのでbe動詞が省略、「未処理例外フィルターがデバッガー内で呼ばれない」となります。

「英語を並べて表示英語と日本語を並べて表示する」をクリックすると、最新版Bing翻訳による表示がされるようで、こちらは「BUG: デバッガー内呼び出されない例外フィルター」と、現時点でそれなりに意味が通る訳になっています。

後置修飾扱いなのは仕方ないとして、最初は正しく訳されていたUnhandledはどこ行ったとか、まだツッコミ所はありますが。

このKB自体はWin9xのものですが、他にも昔の翻訳エンジンで訳したままのページが大量にあります。意味不明な日本語にしておくぐらいなら、英語のままにしておき任意で「並べて表示」ボタンを押させるのが良いように思うのですが。

# 某国総理と違って文法の誤りだけで済むのがマシではあります

技術情報は英語で読む人も多いでしょうから、現状では却って二度手間になっているのです。「たまには機械翻訳済みページを更新してあげたらどうか」とフィードバックに入れましたが、反映されるのはいつのことか。

日本語のページは本文中のAPI名や構造体名が消えているとか、あまりにも状態が酷いので見ない方が良いのですが、ネットで調べ物をしている最中はそのままオンラインで見ることが多く、困ってしまいます。
自作のダイアログベースのプログラムが、英語版Windows XPでのみ動かない現象が発生したので調べてみました。

リソースをあれこれいじりましたが、コモンコントロールの初期化を忘れていたのが原因でした。

InitCommonControlsEx();

このおまじないは「コモンコントロールを使う場合は必要」と方々で注意されているのですが、日本語版Windowsでは2000以来ずっと、なくても動いていたので記憶に残らなかったのです。

しかしこうして現実に、英語版にて問題が発生したのでした。建前は偉大です。英語版Vista(Ultimateの言語切り替えではなく英語版)でも試してみましたが、こちらは大丈夫でした。

ダイアログをデザインしている最中に、どれがコモンコントロールなのかあまり意識しませんから、MFCテンプレートのように常時InitCommonControlsExするのは、多少のメモリ消費が増えるとしても安全と言えます。

現象の詳細としては、CreateDialogが失敗、GetLastErrorが6を返します。ERROR_INVALID_HANDLEです。

WM_CREATEは来るのですが、その後WM_SETFONTの直後にWM_DESTROYが来てしまう、という流れでした。WM_INITDIALOGの前に終了します。

日本語版Windowsはどうして問題ないのか謎ですが、お約束は忘れると怖いという話でした。

+1

| コメント(0) | トラックバック(0)
3GBと4GBなんて違わないだろう、と64ビットWindowsの出始めの頃には思っていましたさ。当時はXPメインの時代、画像や動画を扱わなければ2GBで余裕でしたから。

しかしOSとアプリがメモリを食い尽くした後の余力ですから、そうした状況がひとたび発生すれば、スワップ(残量0)と1GBの比であって、倍率は計算不能のゼロ除算となります。

私とMacBookをそこに追い詰めたのはVisual Studio 2010でした。というわけでVS2010の使用頻度が上がったため、OSとHDDを強化しました。

Vista x86から7 x64へ。せっかく延命されたばかりでしたが、OS上のプログラムも多い立場なので、遅すぎたぐらいです。もう8がリリース間際、経費節減といっても自粛しすぎはダメですね。

250GB/5400rpmから750GBハイブリッド/7200rpmへ。出たばかりのSeagateのハイブリッドです。Mac側は120GBから160GBの微増としました。

使い物にならないレベルだったVS2010が、かなりまともになりました。次期版(2012?)ではもう一歩の高速化を期待したいところです。

電源投入からログオン画面までもかなり速くなったのですが、ログオン後が嘘みたいな速さです。ひょっとしたら64ビット版ウイルスバスターが速い、なんてこともあるかもしれません。

しかし、そうなるとまたタイミング問題が出るわけです。ログオン時タスクからのShell_NotifyIconで、FALSEなのにERROR_SUCCESS、何の関係があるのか不明なERROR_NO_TOKEN、この2パターンが新たに出現しました。

前者はともかく後者は何なのか。GetLastErrorの戻り値は判別せず、回数を制限してリトライするのが無難に思えてきました。

環境依存であるタイムアウトや回数制限を避けるとすれば、通知領域へのアイコン登録は後回しにして、登録できるまでウィンドウを表示してしまう(消すと終了できないため)ことになります。

真っ白ウィンドウでは格好が悪いので、いっその事スプラッシュウィンドウを登録できるまで常時表示するようにするのが、UIとしての妥協点でしょうか。

CERTUMシステム変更

| コメント(0) | トラックバック(0)
certumform.pngメールアドレスがgmailからHotmailに変わりました。無線APの_nomap騒動がちょっと癇に触りまして。

それでCERTUMのオープンソース開発者向けAuthenticode証明書を、少し繰り上げて発行してもらいました。

どうもシステムが改良されたようで、相変わらず最初のフォームはポーランド語なのですが、アンケート的なその最初さえ入力してしまえば、後は何とかなるようになりました。

名前、メールアドレス、電話番号、種別。その次がよくわからないのですが、業種でしょうか。そこから下はアンケートで、他に興味があるもの、どこでCERTUMを知りましたか、個人情報の使用に合意しますチェック、です。

最初の連絡メールもポーランド語ですが、そこには受付番号と入力の注意点(CNにOpen Source Developerが追加される、OにOpen Source Developerと入れること)があるぐらいで、本番の入力フォームは英語でできます。

次のメールにパスポートのスキャン画像を返信すれば万事完了です。

GetProcAddressの罠 (2)

| コメント(0) | トラックバック(0)
その後Windows 7 x64環境で確認したところ、x86バイナリ・x64バイナリ共に再現せず。OSの違いなのか何なのか、と謎が深まってしまいました。

Visual Studioのデバッガにモジュールの一覧表示があったのに気付き、Vista x86で表示させたところ、shimeng.dllのアドレス範囲となっていました。Windows互換性テクノロジの中の人だそうな。

色々試した結果、slnファイルをUAC昇格して開くための自作ツールが原因だと判明しました。といっても、requireAdministratorなmanifestを持たせ、ShellExecuteExするだけの小さな小さなものなのですが。Vista環境でのみ、Send Toに入れて使っていたのです。

ファイル名に"launch"を含んでいると、問答無用で互換性テクノロジの餌食となるようです。互換性レイヤーを示す環境変数__COMPAT_LAYER=ElevateCreateProcessとありましたが、GetProcAddressに介入するのはWRPDllRegisterとかいうものだけではないのでしょうか。

インストーラー検出のinstall,setup,update,etc.とは異なり(他にpatchも)、今のところファイル名にlaunchを含むx86バイナリのみですが、Vista/7共にOSはx86/x64両方で再現しています。

asInvokerの中ILでも互換性レイヤーが入り込み、GetProcAddressをshimeng.dllに取られます。requestedPrivilegesがあってもダメということは、Vista以降用として作っても回避できない、ということです。

こんなテストコードを作りました。実行ファイル名を変えるとアドレスが変わることがあるのがわかります。
GetProcAddress.zip

昇格ランチャーのファイル名変更で回避できたのですが、真正面から行く場合、GetModuleInformationでkernel32.dllの範囲を取得し、その中にあるかどうかを確認して、外れていればLdrGetProcedureAddressする、という方法になるでしょうか。

余談ですがANSI_STRINGのMaximumLengthはLength+1になるようなので、RtlInitAnsiString/RtlFreeAnsiStringを使わずとも、構造体の決め打ち初期化で大丈夫でした。

ANSI_STRING str = {14,15,"GetProcAddress"};

上のサンプルもこのコードになっています。実はRtlFreeAnsiStringがx64でヒープエラーになったせいで、こう逃げたという側面もあったり。
<<前のページへ 12345678

アーカイブ

ウェブページ

Powered by Movable Type 5.2.13

ホームページ