2015年1月29日木曜日

sylfilterのエラー「迷惑メールフィルタコマンドの実行に失敗しました」

いつも通り、Sylpheedで迷惑メールの振り分け作業をしていたら、突然、つぎのようなエラーが:


「エラー」
「迷惑メールフィルタコマンドの実行に失敗しました。」
「迷惑メール対策の設定を確認してください。」
「OK」

ーーー
そこで、「ツール」→「ログウィンドウ」を表示しました所、末尾に次のエラーが:

** Sylpheed-WARNING: summary_junk_func: junk filter command returned 127
** Sylpheed-WARNING: summary_junk_func: junk filter command returned 127

ーーー
SylFilterのjunk.dbが壊れている様子です。

%APPDATA%\SylFilter\junk.db

ーーー
SQLiteと思いましたが、ちがいました。QDBMを採用している模様。

"C:\Program Files (x86)\Sylpheed\sylfilter-cui.exe" --help

...
Available key-value stores:
  QDBM

ーーー
QDBMの開発元 http://fallabs.com/qdbm/

最新のソースパッケージ(バージョン1.8.78)

VisualStudio2005でビルド

ーーー
Depot用コマンド
http://fallabs.com/qdbm/spex-ja.html#depotcli

ーーー
ビルドしたdpmgr.exeで修復を試みる。

C:\DL\qdbm-1.8.78>dpmgr inform j.db
dpmgr: j.db: broken database file

C:\DL\qdbm-1.8.78>dpmgr repair j.db

C:\DL\qdbm-1.8.78>dpmgr inform j.db
name: j.db
file size: 2093929
all buckets: 81919
used buckets: 31556
records: 39815
inode number: 21899
modified time: 1422490817
ーーー
修復したデータベースを元の場所に戻したら、いけました!

ただ、きちんと修復されているのかどうか、つまり、データに整合性が有るのかどうか、知る術がないので、自己責任で、という話になります。

ちなみにオフィシャルの対応では、削除→作り直しを推奨しているようです。ここ

2015年1月21日水曜日

WMIの調子が悪いと、ライセンス準拠の確認に失敗する事がある?

恐らく、Winmgmt (Windows Management Instrumentation) サービスの不調が原因で、良く分からない現象が起こっています。

ーーー
「ライセンス準拠の確認が不完全です」
「サーバーによるライセンス準拠の確認は完了しませんでした。サーバーがドメインに参加している場合、サーバーがドメインコントローラーに接続できることを確認してください。ライセンス準拠の確認が完了できない場合、サーバーは3日2時間0分で自動的にシャットダウンされます。詳細については[ヘルプ]をクリックしてください。」


サーバーを50時間後に自動シャットダウンすると申しております。。。

ーーー
「ライセンス準拠の確認が不完全です」
「サーバーによるライセンス準拠の確認は完了しませんでした。サーバーがドメインに参加している場合、サーバーがドメインコントローラーに接続できることを確認してください。詳細については[ヘルプ]をクリックしてください。」
 

ーーー
怪しい表示に対しては、常にイベントビューアを確認せよ、との教訓に従いまして:

こういうログが記録されていました:

サーバー {73E709EA-5D93-4B2E-BBB0-99B7938DA9E4} は、必要なタイムアウト期間内に DCOM に登録しませんでした。
ソース: DistributedCOM
イベントID: 10010
レベル: エラー

ーーー
レジストリエディタで当該のCLSIDを調べますと、「Microsoft WMI Provider Subsystem Host」に関する事かと分かりますので、WMIの仕業かと考えます。

ーーー
Googleで検索。

http://blogs.technet.com/b/askperf/archive/2009/04/13/wmi-rebuilding-the-wmi-repository.aspx

http://windowsxp.mvps.org/repairwmi.htm

ーーー
診断らしきコマンドを実行:

C:\WMIDiag>winmgmt /verifyrepository
WMI データベースに矛盾はありません

ーーー
他にも随所にエラーの痕跡が認められます。

サーバーマネージャーで管理状態に問題が。


「オンライン - 役割と機能のデータを取得できません」


「サーバーの実行に失敗しました」

 


今はサーバーを再起動できないので、後でサーバーを再起動し、どうなるかを確かめてみます。

→ 再起動すると、改善しました。

0xd00002feは、STATUS_SHUTDOWN_IN_PROGRESSか?

0xC00002FE = STATUS_SHUTDOWN_IN_PROGRESS
https://msdn.microsoft.com/en-us/library/cc704588.aspx

バグチェックコードの形式
http://stop-error-dot-com.blogspot.jp/2014/12/blog-post.html

同じ内容のようです。ReservedBitが異なるだけで。。。

ーーー
D000 02FE

1101 0000 0000 0000 0000 0010 1111 1110

Sev: 3 (Error)
C: 0 (Customer code flag)
R: 1 (Reserved bit)
Facility: 0
Code: 766

ーーー
C000 02FE

1100 0000 0000 0000 0000 0010 1111 1110

Sev: 3 (Error)
C: 0 (Customer code flag)
R: 0 (Reserved bit)
Facility: 0
Code: 766

ーーー

2015年1月14日水曜日

Context Menu Handlerで、きちんとアイコンを付ける方法

MSDNのHow to Implement the IContextMenu Interfaceとうで紹介されています、エクスプローラの右クリックメニュー拡張機能。

テキストの隣に画像を付ける方法が、実はいくつも有り、困っています。。。

正しい方法を模索しています。

主にWindows 7でテスト中。

ーーー
次図は、InsertMenuとSetMenuItemBitmapsを使った例です。あげとさげを追加しました。



お馴染みのDropboxやTortoise系を並べる事で、どのような塩梅か、比べています。

表示した直後は普通ですが、一度でもハイライトすると、背景色が白くなります。これはマズい。

ーーー
次図は、IContextMenu3+MF_OWNERDRAW+WM_DRAWITEMで対応した例です。


一応目的は果たしているように思えますが、、、どうも周囲とのバランスが取られていません。

ーーー
次図は、InsertMenuItem+MIIM_BITMAPで行った例です。hbmpItemには、ビットマップハンドルを渡しています。


最初と同じ動作のようです。

ーーー
次図は、HBMMENU_SYSTEMを用いた例です。hbmpItem = HBMMENU_SYSTEM


しかし、如何様に頑張ってみても、図のような、ウィンドウのアイコンしか出てきません。。。

ーーー
次図は、HBMMENU_CALLBACK+WM_DRAWITEM+WM_MEASUREITEMを用いた例です。hbmpItem = HBMMENU_CALLBACK


意図したような表示になり、一応成功していますが、メニューデザインがXP時代の物に退化してしまっています。

ーーー
次図は、先のInsertMenuItem+MIIM_BITMAPで行った例です。hbmpItemには、32bppのビットマップハンドルを渡しています。


どうもこれが正解のようです。TortoiseSvnのソースコードを覗いたら、そのような実装になっていました。

PArgbかArgbか、どちらが良いのか、そこまでは判りませんが。。。 PArgbでないと、表示が変になっていました。

2015年1月7日水曜日

PostgreSQL 9.3.3 (x64) + textsearch_ja 9.0.0改 (x64) + libmecab 0.996 (x64) for Windows

textsearch_jaを独自にビルドしました。

textsearch_ja-pgsql-9.3-x64.7z
textsearch_senna-pgsql-9.3-x64.7z
https://drive.google.com/folderview?id=0Bygl-em20CSKTXAxZURNUTdydHM&usp=sharing#list

ご利用前に、毒が入っていないかどうか、念のため、お確かめください。

拙作ビルド成果物につきましては、こちらでも公開しています:
https://github.com/HiraokaHyperTools/textsearch_senna/releases
https://github.com/HiraokaHyperTools/textsearch_ja/releases

インポートライブラリの件

インポートライブラリは厄介です。。。

1>textsearch_ja.obj : error LNK2001: 外部シンボル "__imp_mecab_new" は未解決です。

結論
x64  __imp_mecab_new
x86  __imp__mecab_new

ーーー
という訳で、ちょっと確かめてみます。

dumpbin /exports libmecab.dll | find /i "mecab_new"
         97   60 00027540 mecab_new
         98   61 0004F450 mecab_new2

dumpbin /exports libmecab.lib | find /i "mecab_new"
                  _mecab_new
                  _mecab_new2

DependencyWalkerで見ると、「mecab_new」

Cygwinで:

$ objdump.exe -t Program\ Files\ \(x86\)/MeCab/sdk/libmecab.lib | grep "mecab_new"
[  4](sec  1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 __imp__mecab_new
[  5](sec  3)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 _mecab_new
[  4](sec  1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 __imp__mecab_new2
[  5](sec  3)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 _mecab_new2

$ objdump.exe -p Program\ Files\ \(x86\)/MeCab/bin/libmecab.dll | grep "mecab_new"
        [  96] mecab_new
        [  97] mecab_new2

ーーー
という訳で、ちょっと作って確かめてみました。(後から注記:x86

extern "C" __declspec(dllexport) int ExportIt() {
 return 0;
}

dumpbin /exports OneDLL.dll | find "ExportIt"
          1    0 00001000 ExportIt = _ExportIt

dumpbin /exports OneDLL.lib | find "ExportIt"
                  _ExportIt

DependencyWalkerで見ると、「ExportIt」

Cygwinで:

$ objdump.exe -t Proj/Solution1/release/OneDLL.lib | grep "ExportIt"
[  4](sec  1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 __imp__ExportIt
[  5](sec  3)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 _ExportIt

$ objdump.exe -p Proj/Solution1/release/OneDLL.dll | grep "ExportIt"
        [   0] ExportIt

ーーー
(後から注記:x64

extern "C" __declspec(dllexport) int ExportIt() {
 return 0;
}

dumpbin /exports OneDLL.dll | find "ExportIt"
          1    0 00001000 ExportIt = ExportIt

dumpbin /exports OneDLL.lib | find "ExportIt"
                  ExportIt

DependencyWalkerで見ると、「ExportIt」

$ objdump.exe -p Proj/Solution1/x64/release/OneDLL.dll | grep "ExportIt"
objdump: Proj/Solution1/x64/release/OneDLL.dll: ファイル形式が認識できません
$ objdump.exe -t Proj/Solution1/x64/release/OneDLL.lib | grep "ExportIt"
objdump: OneDLL.dll: ファイル形式が認識できません
objdump: OneDLL.dll: ファイル形式が認識できません
objdump: OneDLL.dll: ファイル形式が認識できません
BFD: Proj/Solution1/x64/release/OneDLL.lib(OneDLL.dll): インポートライブラリ形式書庫のマシン型 (0x8664) は認識できますが扱えません
BFD: Proj/Solution1/x64/release/OneDLL.lib(OneDLL.dll): インポートライブラリ形式書庫のマシン型 (0x8664) は認識できますが扱えません
objdump: OneDLL.dll: ファイル形式が認識できません

ーーー
特に問題ないように思えます。。。

ところが、x64という可能性を考え、追試をするとビンゴ!

x64では、最初の _ 記号が取れているでは在りませんか。。。

ESENT(JET Red)のDatabasePageSizeは…?

ESENT Managed Interfaceを用いて、JET Redのデータベースを開いたりしています。

そこでいつも問題になるのが、DatabasePageSizeです。

私の指定と、DBの仕様が一致しなければ、EsentPageSizeMismatchExceptionが発生。

ーーー
esentutl /? 等で表示される内容を参考にしますと、DatabasePageSizeの取りうる値は2048, 4096, 8192, 16384, 32768の5つが有るようです。

/2         - set 2k database page size (default: auto-detect)
/4         - set 4k database page size (default: auto-detect)
/8         - set 8k database page size (default: auto-detect)
/16        - set 16k database page size (default: auto-detect)
/32        - set 32k database page size (default: auto-detect)

ーーー
参考までに、

C:\Windows\SoftwareDistribution\DataStore\DataStore.edbは、32768

%LOCALAPPDATA%\Microsoft\Windows Live Mail\Mail.MSMessageStoreは、8192

でした。

ーーー
実際に調べる方法は、esentutl /mがお手軽です。

esentutl /m C:\Windows\SoftwareDistribution\DataStore\DataStore.edb

Extensible Storage Engine Utilities for Microsoft(R) Windows(R)
Version 6.1
Copyright (C) Microsoft Corporation. All Rights Reserved.

Initiating FILE DUMP mode...
         Database: C:\Windows\SoftwareDistribution\DataStore\DataStore.edb


DATABASE HEADER:
Checksum Information:
Expected Checksum: 0x0b814322
  Actual Checksum: 0x0b814322

Fields:
        File Type: Database
         Checksum: 0xb814322
   Format ulMagic: 0x89abcdef
   Engine ulMagic: 0x89abcdef
 Format ulVersion: 0x620,17
 Engine ulVersion: 0x620,17
Created ulVersion: 0x620,17
     DB Signature: Create time:01/07/2015 11:54:17 Rand:176326398 Computer:
         cbDbPage: 32768
           dbtime: 219204 (0x35844)
            State: Clean Shutdown
     Log Required: 0-0 (0x0-0x0)
    Log Committed: 0-0 (0x0-0x0)
  GenMax Creation: 00/00/1900 00:00:00
         Shadowed: Yes
       Last Objid: 46
     Scrub Dbtime: 0 (0x0)
       Scrub Date: 00/00/1900 00:00:00
     Repair Count: 0
      Repair Date: 00/00/1900 00:00:00
 Old Repair Count: 0
  Last Consistent: (0x0,0,0)  01/07/2015 11:55:09
      Last Attach: (0x0,0,0)  01/07/2015 11:54:17
      Last Detach: (0x0,0,0)  01/07/2015 11:55:09
             Dbid: 2
    Log Signature: Create time:00/00/1900 00:00:00 Rand:0 Computer:
       OS Version: (6.1.7601 SP 1 NLS 60101.60101)


ーーー

2015年1月5日月曜日

アプリ起動時のCLR exception(0xe0434352)をWinDbgで追跡する

ちょっと、C#でIContextMenuを実装した際に不備が有り、Process Monitorが起動しなくなる、という事件が有りました。

そこで、その、CLR exception(0xe0434352)をWinDbgで追跡する方法をまとめました。

ーーー
まずは、WinDbgを起動します。ターゲットのexeに合っている方(x86,x64)を選んでください。


ーーー
[File]→[Open Executable...]で、exeを開きます。

ーーー
[Debug]→[Event Filters...]を開きます。

"CLR exception"を選び、"Enabled"を選択。閉じます。


ーーー
[Debug]→[Go]で実行します。

ーーー
デバッガが停止した場合、例外コードを確認します。ちょうど、オレンジ色の部分です。


(1c14.1fc4): CLR exception - code e0434352 (first chance)

この例外であれば、次に進みます。

ーーー
SOS.dllを読み込みます。

SOS.dll (SOS デバッガー拡張)

.loadby sos clr

で良いようです。。。

参考:WinDbgとSOS拡張でVSを使わずに.NETアプリをデバッグ - 異常終了時の調査

SOS.dllを読み込むには、通常、次の4つのうち、1つを実行するのですが。。。

.load C:\Windows\Microsoft.NET\Framework\v2.0.50727\SOS.dll
.load C:\Windows\Microsoft.NET\Framework\v4.0.30319\SOS.dll
.load C:\Windows\Microsoft.NET\Framework64\v2.0.50727\SOS.dll
.load C:\Windows\Microsoft.NET\Framework64\v4.0.30319\SOS.dll


WinDbgの出力を見て考えます。画面上に、

C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll

という出力が有るので、上から2番目の物が該当します。

.load C:\Windows\Microsoft.NET\Framework\v4.0.30319\SOS.dll

.load がうまくいっても、特にこれといった表示は有りません。

.chain を使うと分かるようです。(.chain は Meta-Commands の 1 つ)

0:000> .chain
Extension DLL search Path:
    C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\WINXP;...
Extension DLL chain:
    C:\Windows\Microsoft.NET\Framework64\v4.0.30319\sos.dll: image 4.8.4510.0, API 1.0.0, built Fri Apr  1 06:30:03 2022
        [path: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\sos.dll]
    ELFBinComposition: image 10.0.22621.1, API 0.0.0, 
        [path: C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\winext\ELFBinComposition.dll]
    dbghelp: image 10.0.22621.1, API 10.0.6, 
        [path: C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\dbghelp.dll]
    exts: image 10.0.22621.1, API 1.0.0, 
        [path: C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\WINXP\exts.dll]
    uext: image 10.0.22621.1, API 1.0.0, 
        [path: C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\winext\uext.dll]
    ntsdexts: image 10.0.22621.1, API 1.0.0, 
        [path: C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\WINXP\ntsdexts.dll]
 

ーーー
次に、3つコマンドを実行しました。その結果が次の図になります。 企業秘密は、黒棒で消しました。


!Threads で、実行中のスレッドの様子を見ています。

!pe (!PrintException) で、例外の中身を確認しています。

!CLRStack で、スタックトレースを確認しています。

ここまでやると、大体は見当が付いてくると思います。

今回の事例では「IContextMenu.GetCommandStringの中で、HRESULTを返す為に『throwを呼ぶ』という手段を選択したことが良くなかった」事が判りました。

IContextMenuの中でthrowするとProcmon.exeが起動しない?

C#を使い、IContextMenuを実装しています。

エラーを返す場合、GetCommandStringやInvokeCommandの中で、例外を使っていました。

public void GetCommandString(...) {
  ...
  throw Marshal.GetExceptionForHR(-2147467259);

}

プロトタイプ宣言がvoidなので仕方ない事だな、とばかり思っていました。

しかし、そのような実装をしていますと、ProcessMonitorが起動しない事が分かりまして、次の様に実装し直しました。

public uint GetCommandString(...) {
  ...
  return (0x80070057);
}

これで、ProcessMonitorが起動するようになりました。

何か、その、一時フォルダに Procmon64.exe を作成し、私のContext Menu Handlerに Open を投げ掛けて、起動しようとしていたようです。