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

IARのEWARMで「ファイルから検索」をすると、かなりの数のファイルが読み飛ばされるバグがありました。

なぜか「大文字と小文字を区別する」にチェックを入れると全て検索してくれるのですが、少なくとも6.50.6までありました。

最近7.10.1にしたところ、修正されていました。

DeltaEndとWindows 8.1の顛末

| コメント(0) | トラックバック(0)
いつの間にかキーボードフックが外れる件はDeltaEndの問題ではなく、OSの仕様変更と私の環境固有の傾向による問題とわかりました。

Windows 7から、ローレベルフックにタイムアウトが設定されたのだそうです。300msを10回超えると勝手にフックが外れるというもので、しかも、同じプロセスからは二度とかけ直せない。

そして私は新OSに慎重な場合はサブ環境、つまり遅いPCで使い始めるのを習わしとしているために、最近Vistaから8.1にしたThinkPad X61 Tabletや、DELL Dimension 9200Cで発生していたわけです。

DeltaEndのキーボードフックはかなり単純だと認識していますが、それでも時として300msを超えていることになります。スワップ発生中とかでしょうが、如何に横暴な仕様かわかろうものです。

回避法はレジストリによる設定(最大10秒)ですが...

DWORDで以下の値に設定、単位はms、デフォルトは300(のはず)。
HKEY_CURRENT_USER\Control Panel\Desktop\LowLevelHooksTimeout

上記記事だと300msがデフォルトに見えますが、確認したところレジストリ値は既に存在し5000(5秒)というデータがありました。一説によるとVisual Studio 2010以降のインストーラーが書き込むのだとか。マイクロソフト自身の製品ですら困る仕様ってことですか。

DELL 9200Cの方はしばらく再現していませんが、本格的に使い始めたのでVisual Studioも一通り入っており、タイムアウトが既に5秒になったお陰の可能性が高いです。

MacBook MB062J/Bで発生していなかったのも、7にする前のVista時代から既にVisual Studio 2010が入っていたためと考えられます。

問題は、フックが外された際にそれを検出する方法がないことと、実行ファイルを立ち上げ直さなければならないことです。

定期的かアイドル中に自動再起動をかけ続けるほど重要なソフトではないので、ユーザー操作での再起動で良いでしょう。マスタープロセスはUIだけの担当にして、キーボードフックはスレーブプロセスに担当させる感じでしょうか。

64ビット版Windowsではスレーブプロセスは32と64の2つになり、キーボードフックは両方にかかるので、その片方だけが担当。となると、筆頭スレーブのフラグを新設することになりますね。

何はともあれ、原因がはっきりして良かったです。

Windows 8.1とバージョン番号

| コメント(0) | トラックバック(0)
Windows 8.1ではGetVersionExが6.2と返すらしいというので試してみました。

GetVersionEx function
「Windows 8.1向けと明示(マニフェスト)されていないアプリケーションには6.2と返す」

確かにそうなりました。SupportedOS Idは以下のように。
  • {1f676c76-80e1-4239-95bb-83d0f6d0da78} 8.1/2012 R2
  • {4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38} 8/2012
  • {35138b9a-5d96-4fbd-8e2d-a2440225f93a} 7/2008 R2
  • {e2011457-1546-43c5-a5fe-008deee3d3f0} Vista/2008

8.1のIdが指定されていると6.3が、ないと6.2が返りました。

過去のマイクロソフトのスタンスとはずいぶん異なる挙動です。Vista/7ぐらいの頃は「特定のバージョンでしか動かないような実装はやめなさい」と言っていたのに。諦めたということでしょうか。

早くからこの方針が決まっていれば、SupportedOS IdがVistaなら(※)6.0、7なら6.1...ということもできたでしょうが、8.1で今さらこうなったのも妙な気はします。

※Vista当時にSupportedOS Idはなかったので、requestedPrivilegesだけがあれば、といったあたり

それとは別に、マニフェストに関わらず判定できるAPIがあり、Version Helper functionsと称されています。

IsWindows8Point1OrGreater他、任意のバージョンかそれ以上を判定できるのですが、VersionHelpers.hの中にコードが書かれており、中でVerifyVersionInfoを呼んでいました。

実体がVerifyVersionInfoですから、IsWindows8Point1OrGreaterなどの各関数のサポートOS欄には"Windows 2000"と書かれています。

とどのつまり、マニフェストのSupportedOS Idをちゃんと記述しておきましょう、という話ですが、Win32の世界で8以降の目新しいAPIって何かあったかな...。

ASLRとDeltaEndとAvast!と

| コメント(0) | トラックバック(0)
DeltaEnd Ver.0.62がWindows 8.1でたまにキーに反応しなくなるので、試しに仕入れたばかりの知識を活用とばかりにASLRを無効にすべくリンカーのオプションを変更してみたところ(/DYNAMICBASE:NO)、Win32:Evo-gen [Susp]としてAvast!に検出されてしまいました。

32ビット版EXEのDeltaEnd.exeのみで、ウイルスバスター、MSEは共に全ファイル無害と判定しています。

変更しなければ検出されません。誤検出が多い定義らしいですが、一応レポートを提出しておきました。

(追記2014/2/21)
対応していただけたようです。ビルドし直しても誤検出されていませんので、単純に何らかの形(例えばファイルのハッシュ値)でホワイトリストに加えたとかいうことではなさそうです。
勤務先サブ環境のWindows 8.1ですが、Classic Start Menuのおかげで快調です。コンパネをカテゴリーで起動する、とか詳細設定から変更しなければならない項目もありますが。ちなみにスタートボタンの図柄を変更しないのが好みです。

さて、仕事でサンプルソースコードを用意することもあるのですが、古いものが一部にあります。Visual C++ 6.0はさすがに捨てましたが、2005はまだ少しありまして。

それでVisual Studio 2005も入れたわけですが、これの調子が悪い。プリコンパイルヘッダーを使うと頻繁に致命的エラーC1023(pchを再ビルドせよ)が出ます。

何をどうしたら一介のアプリケーションの、たかがファイル入出力で、OS依存の不具合が発生するのか、理解に苦しむ部分もありますが、他にも同じ現象の方がいらっしゃるようです。

devenv.exeのプロパティに互換性タブは表示されませんでしたので、互換性のトラブルシューティングから7/Vista/XPと順に指定してみましたが効果なし。そもそもファイル入出力なんか細工してくれないでしょう。

で、どうも原因はファイル入出力ではなく、ASLRというOS側のメモリ操作に関するセキュリティ機能からの影響らしいとか何とか、関連ありそうな話がMSDNのブログに書かれていました。

要約すると、「Win7で強化されたASLRの副作用でpchが壊れたように見えてしまう。コンパイラ自身はASLRを使わないが、仮想メモリ空間全体の問題なのでそれでは不充分になった。根本対策をすることにした。」

ASLRはWin8でもまた強化されたらしいので、上記記事では2008/2010の話しかされていませんが、対策されなかった2005が遂に引っかかってしまったと推測しています。

それが正しいとすれば、つまり打つ手無しです。一応、しつこくビルドすれば何度目かに通るのですが、効率が悪いことこの上ありません。もちろん、プリコンパイルヘッダーを使わなければどうということはありませんが。

最低でも2008に移行した方が良いのでしょう。XPも終わりますし、2005は元々Vistaに難ありな対応しかされませんでした。もう、ゴールしてもいいよね?

P.S.
話は変わって、Visual C++ 2013はかなりC99に追い付いたようなので、SDKが必要とするからといった消極的な理由でなく、久々に積極的に更新したいと思えました。

DeltaEnd Ver.0.62公開

| コメント(0) | トラックバック(0)
deltaend04.pngPowerPoint(限定ではありませんが)起動時にIMEがONになるのを防止する機能を付けてみました。

PowerPointのバージョンに依存する設定を、自分でDeltaEnd.iniに記述の必要があります。ドキュメントにPowerPoint2003/2007/2010/2013それぞれの場合の設定を書いておきました。

ホームページ側のWin32コーナーにて。
ノートPCは廃熱に制約がある機種が多く、熱源は減らした方が快適です。中でも無線LANは熱いデバイスの一つです。可能な限り無効にしておきたいもの。

机の上では速度、安定性、熱と、三拍子揃って有線LANですが、移動した時に勝手に切り替わったらいいなあ、ということで、VBSで対応しました。WMI Fun!!様のネットワーク接続一覧取得サンプルを参考にしました。

ToggleWLAN.zip

管理者権限で引数を二つ、第一引数が有線LANの名前(「ローカル エリア接続」や「イーサネット」など)、第二引数が無線LANの名前(「ワイヤレス ネットワーク接続」や「Wi-Fi」など)です。

第一引数の接続があれば第二引数を無効にし、なければ有効に。名前に空白が入る場合はダブルクォーテーションで囲ってください。

これをタスクスケジューラで最上位の特権にしてSYSTEMにでも実行させるわけですが、トリガーは3つ。
  • スタートアップ時
  • イベントを2つ
イベントはハードウェア依存です。有線LANのドライバが接続を検出した時と、切断された時に、イベントログ(システムのはず)に記録されるイベントとそのID。MacBookのMarvell Yukonだと接続時に3つぐらい記録されますから、最後のもので。

というわけで、確認できる4機種は以下のようになりました。いずれもログはSystemです。ソース、接続時イベントID、切断時イベントIDの順です。

MacBook Late 2007、Windows 7
yukonw7、ID:134、ID:83

MacBook Pro (非Retina)、Windows 7
Early 2011, Mid 2012共通
b57nd60a、ID:11、ID:4

ThinkPad X61 Tablet、Windows 8.1
e1express、ID:32、ID:27
Win8.1用のカタログ(.cat)を作ろうとしたら、inf2catがエラーを出しました。8_X86、8_X64、6_3_X86、6_3_X64のいずれかが指定されていると、拒否されてしまうようです。

WDKは8.1用のもの。

Signability test complete.

Errors:
None

Warnings:
None

Unable to save the catalog.
Signability test failed.

MSDNのフォーラムによると、更新プログラムKB2862966が悪さをしているのだそうな。アンインストールで直りました。また書き込みの中にKB2837108で直るというのもありまして、こちらでも大丈夫でした。早くWindows Updateで公開してほしいですね。

特定カテゴリの除外

| コメント(0) | トラックバック(0)
たまーに、このブログにリンクをしていただいている方があるようで、ありがたい限りです。

そんなわけで、内面の云々を時々吐き出している毒カテゴリがありますが、これのエントリをメインページと月別インデックスから除外することにしました。

私自身も見返すと気が滅入るのですが、こうしたものは基本的に誰かに聞いてもらわないと痞えが取れないので、公開する必要があるのです。そこでカテゴリを直接クリックしないと見られないように。

公式のテンプレートタグ解説のMTEntriesに記述がありまして、
<mt:Entries categories="NOT (カテゴリ名)">
と指定することでできました。

KeePass 2.24 Windows版修正ビルド

| コメント(0) | トラックバック(0)

自動入力時に"@"から後が全角になる現象の修正版。

SendInput.Keysの代わりにWshShellオブジェクトのSendKeysを使う改造の2.24です。差し替えexeと修正ソースのみとなっています。

KeePass224mod.zip

<<前のページへ 12345678

アーカイブ

ウェブページ

Powered by Movable Type 5.2.13

ホームページ