2006年5月29日(月)
MultiByteCabEnablerアップデート
設定するレジストリに最上位ビット(0x80000000)が立ったDWORD値が含まれていたcabの場合、インストールが完了しない問題の対策を追加。
http://www.geocities.jp/hou_ming_2/MultiByteCabEnabler.zip
作成者
ホーミン
: 2006年5月29日(月) 07:24
[
コメント
: 1]
2006年5月26日(金)
WndowsMobile5でAdobeReaderが動かない理由(解決編)
と言うことで原因は判明したので、その対処方法を考えてみる。
方法1. DS_MODALFRAME掃討作戦
DS_MODALFRAMEがついてるから死ぬのでDS_MODALFRAMEを外すことで対処する。
問題のダイアログはRdLang32.JPNに含まれるものなので、これを書き換えればいいのだが、、、こいつは大量のリソースが含まれているので編集は厄介、と言うことでmuiで逃げる。
・DumpRCでRdLang32.JPNのダイアログリソースだけ抜き出す
・さらにスタイルにDS_MODALFRAME(0x80)を含むダイアログリソースだけ残す
・各ダイアログのスタイルからDS_MODALFRAME(0x80)を取り除く
・リソースdllを作成し、RdLang32.JPN.0411.muiにリネーム
・RdLang32.JPNと同じフォルダにRdLang32.JPN.0411.muiを置く
方法2. DS_MODALFRAME無視作戦
DS_MODALFRAMEを外す処理をしなければ死なないので、この処理を飛ばすことで対処する。
この処理はmfcce300.dllで行われているがROMファイルを直接書き換える術はないので、以前のSDKからmfcce300.dllを持ってきて書き換えを行う。
・PocketPC,PocketPC2002,PocketPC2003いずれかのSDKからmfcce300.dllを入手(PocketPC2003なら標準インストールでC:\Program Files\Windows CE Tools\wce420\POCKET PC 2003\Mfc\Lib\armv4)
・mfcce300.dllの80 30 13 E2 1B 00 00 0A→80 30 13 E2 1B 00 00 EA に書き換え(if(lpDialogTemplate->style & DS_MODALFRAME)の部分に相当)
・書き換えたmfcce300.dllをAcroRd32.exeと同じフォルダまたはWindowsフォルダに置く
こちらで確認した限りではどちらの方法でもうまくいっているが動作保証はしかねるので、自己責任でどうぞ。
作成者
ホーミン
: 2006年5月26日(金) 09:07
[
コメント
: 2]
WindowsMobile5でAdobeReaderが動かない理由(その2)
まずは原因個所を説明すると
BOOL CWnd::CreateDlgIndirect(LPCDLGTEMPLATE lpDialogTemplate, CWnd* pParentWnd, HINSTANCE hInst)
{
:
:
if (lpDialogTemplate->style & DS_MODALFRAME)
{
LPDLGTEMPLATE lpTemplate = (LPDLGTEMPLATE)lpDialogTemplate;
:
:
dwResult = VirtualQuery (lpTemplate, &mbiMemory, sizeof(MEMORY_BASIC_INFORMATION));
if (sizeof(MEMORY_BASIC_INFORMATION) == dwResult)
{
if (mbiMemory.Protect == PAGE_READWRITE)
{
lpTemplate->style &= ~DS_MODALFRAME;
}
else if (mbiMemory.Protect == PAGE_READONLY)
{
// Mark the dialog template as read-write.
VirtualProtect(lpTemplate, sizeof(DLGTEMPLATE), PAGE_READWRITE, &dwResult);
lpTemplate->style &= ~DS_MODALFRAME;
}
:
:
}
最後の赤いところでReadOnlyのメモリに書き込みしようとして死ぬのですが、、、ある意味すごいコードです。
ダイアログのスタイルにDS_MODALFRAMEがついていたら外す処理をしているのですが、、、
まずLPCDLGTEMPLATE(つまりconstな)型の lpDialogTemplateをLPDLGTEMPLATEにキャストしています。せっかくのconstの意味が無くなるやばいコードです。
さらにメモリがReadOnlyだった場合、VirtualProtect()を使いReadWriteに変更しようとしてますが、その戻り値を見てません。失敗してメモリがReadOnlyのままでも構わず書き込みアクセスをしてしまいます。
ということで不正なメモリアクセスで死んじゃいます。
さらに付け加えておくと、ダイアログのスタイルにDS_MODALFRAMEがついていると何か不都合があるかと言うと何もありません。普通に表示できます。こんな処理をしていること自体が謎です。
まったくMSさん、(ry
次回解決編に続く、、、
作成者
ホーミン
: 2006年5月26日(金) 08:28
[
コメント
: 0]
WindowMobile5でAdobeReaderが動かない理由
AdobeReader2.0はMultiByteCabEnablerを使用しなくてもインストールは正常に完了する(ユーザーマニュアルのファイル名が化けるが、、、)
しかし、実行すると不正な処理で落ちてしまい起動できない。この原因を調べようとしたが結構面倒だった。
落ちてる場所はMFCCE300.dllの中、しかしWindowsMobile5SDKではMFCCE300.dllのソースが含まれていない。MFCCE300は廃止する方針だからなんだろうけど、、、
仕方ないのでPocketPC2003SDKのMFCCE300.dllを持ってくる。サイズが微妙に違うが動かしてみる。結局死に様に変わりはないのでビルド環境の違いぐらいでソースは同じものらしい。(ちなみにMFCは初代PocketPCからPocketPC2003まですべて同一ソース)
ということでPocketPC2003SDKからMFCの一式を持ってきてVS2005でデバッグ環境を整え実行!落ちる部分のソースを読んでみると、、、
またMSのバグかよ、、、
正直なところ、この問題はAdobeReaderの方がお行儀の悪い処理をしているのが原因とにらんでいたけど、その予想は外れた。MSの方がお行儀の悪い処理をしていた。
MFCCE300.dllは潜在的に問題のあるコードだが、今までは幸運にも問題が起きるようなパターンにあたっていなかったと言うことだったんだよ!!
「な・・・・なんだってー!!」
続く
作成者
ホーミン
: 2006年5月26日(金) 07:50
[
コメント
: 0]
リソースdll簡単作成方法訂正
以前紹介した方法(http://geocities.yahoo.co.jp/gl/hou_ming_2/view/20060415)にミスがあったので訂正。(ファイルパスにスペースが入っていた場合にきちんと動かなかった。)
>3.以下のbatファイルでリソーススクリプト(.rc)をコンパイルしてresファイルを作成
>"(rc.exeのパス)\rc.exe" /l0 "%1"
↓
"(rc.exeのパス)\rc.exe" /l0 %1
>※もしrcのStringTableに \000で終わっているところがあったら( \000" を検索して見つかったら) /n オプションを追加
>"(rc.exeのパス)\rc.exe" /l0 /n "%1"
↓
"(rc.exeのパス)\rc.exe" /l0 /n %1
>4.以下のbatファイルでresファイルをリンクしてdllを作成
>"(link.exeのパス)\link.exe" /DLL /NOENTRY /MACHINE:ARM /SUBSYSTEM:windowsce,4.0 /INCREMENTAL:NO /NOLOGO /OPT:REF /OPT:ICF /OUT:"%1.dll" "%1"
↓
"(link.exeのパス)\link.exe" /DLL /NOENTRY /MACHINE:ARM /SUBSYSTEM:windowsce,4.0 /INCREMENTAL:NO /NOLOGO /OPT:REF /OPT:ICF /OUT:"%~dpn1.dll" %1
作成者
ホーミン
: 2006年5月26日(金) 06:57
[
コメント
: 0]