さっさと結論を
さて前回の案はその当時は微妙だったので(Gakuさん案は思いつかなかった)。
原点に立ち戻ることを考えた。
原点とは8/12の日記の以下の部分だ。
001 void カーネルのマウスハンドラ() 002 { 003 004 // 登録されたマウスハンドラをcall pは関数ポインタ 005 p(); 006 }
登録された関数ポインタを実行する方法。この方法の問題点は
- 割込みが発生したプロセス空間=登録されたマウスハンドラの空間とは限らない
この部分につきる。
では、逆転の発想をしてしまおう。(単純だなぁ)
以下のような感じ。
001 void カーネルのマウスハンドラ() 002 { 003 004 // p();のプロセス空間に切り替えちゃえ 005 g_page_manager->setPageDirectory( (dword)thread->process->getPageDirectory() ); 006 007 // 登録されたマウスハンドラをcall pは関数ポインタ。自分の空間だかららくらくcall出来るね。 008 p(); 009 010 // 元のプロセス空間に切り替える 011 g_page_manager->setPageDirectory( (dword)g_currentThread->process->getPageDirectory() ); 012 } 013 014
ハンドラがプロセス空間のせいでうまく実行できないならばうまいこと切り替えてしまえばいいという発想である。
そしてこれが見事にはまってうまくいったのだった(今のところ)
めでたしめでたし。