Windows 8 でしか再現できない奇妙なクラッシュを調査していたところ、またはEBX
の呼び出しからレジスタが復元されていないことがわかりました。Windows 8 での実行で最初に見つけた違いは、これらの関数の win7 バージョンが使用 (したがって復元) している間に使用していることです。(私は他の Windows バージョンを詳細に調査していませんが、Vista ではバグが再現されないことに気付きました。)RmShutdown
RmRestart
ECX
EBX
RM_WRITE_STATUS_CALLBACK
さらに掘り下げてみると、 への呼び出しはスタックから引数をポップすることによってスタックを復元しないことに気付きました。RstrtMgr!CRestartManager::ShutdownApplications
そのため、呼び出し時RstrtMgr!_EH_epilog3
に間違ったレジスタ値がスタックからポップされます。しかし、少なくともESP
は適切に復元され、最後には、呼び出しと終了の間で使用されないRmShutdown
を含む、使用したレジスタが適切にリセットされます...EBP
CRestartManager::ShutdownApplications
したがって、Windows 7では、すべて問題ありませんでした...しかし、Windows 8バージョンは、のECX
代わりに使用されているため、復元されず、呼び出しコードがそれに依存している場合... BOOM !!!EBX
EBX
これを修正するために、使用するコールバック関数を単純に変更しました__stdcall
(これは、実際のRM_WRITE_STATUS_CALLBACK
型を使用できず、API が期待するものに型キャストするか、GetProcAddress
XP で同じコードを実行するために必要な手法を使用する必要があることを意味します)。とりあえず)。
何か足りないのでしょうか、それとも本当に API の問題なのでしょうか? EDI
とはどうESI
ですか?Windows 7 でも適切に復元されません。
これについてマイクロソフトにバグを報告すると思います...誰かがより良い説明を思いつかない限り...