1

Windows Server 2003でサービスとして実行しているアプリケーションサーバー(JBossですが、これはTomcatでも発生します)があります。-Xrsフラグを付けて実行しています。

アプリケーションサーバーで実行されているJavaアプリケーションは、JNIを介してC ++で記述されたカスタマイズ可能なインターフェイスを呼び出し(このコードを変更できることを意味します)、イメージを処理するためにサードパーティのDLLファイル(PostScriptを変換するためのリンカーン)を参照します。

mstsc /consoleコンソール()モードまたは管理者( )モードのいずれかでリモートデスクトップ接続を介してサーバーにログインするmstsc /admin場合、ログアウトすると、リンカーンDLLファイルがロードされている場合、アプリケーションサーバーはログオフ信号を確認し、サービスプロセスはすぐに終了します。偏見。

信号はCTRL_LOGOFF正しいと思いますが、間違っている可能性があります。

シグナル処理に関するJavaJiggleの記事の後、DLLファイルの処理中にシグナルハンドラーがDLLファイルに渡されるようです。これは、サードパーティのDLLファイル(この場合はリンカーン)がログオフすることでCTRL_LOGOFF信号をリッスンし、応答することを意味します。

DLLに到達する前にインターセプトするためにC++インターフェイスでDLLへのシグナルキャッチャーをコーディングできるはずCTRL_LOGOFFです。そうであれば、誰かがコンソール/管理者RDPからログオフしたときに絶えず死ぬことはありません。

これが私が必要とするものです:

  1. console / admin logoff / logoutで取得しているシグナルが正しいCTRL_LOGOFFですか?

  2. C ++インターフェイスでシグナルインターセプターを作成できますか?

  3. その信号インターセプターをコーディングするにはどうすればよいですか、または既存のコードがありますか?32ビットDLLを使用しています。

この質問に答えるのに役立つ可能性のあるMicrosoftの記事「コントロールハンドラー関数の登録」を見つけました。

4

1 に答える 1

0

サードパーティのDLLが呼び出されるたびに無視ハンドラーをスタックに追加することで解決したようですが、メソッドを呼び出すたびに、スタックにハンドラーを追加し続けますが、明らかにサードパーティのDLLは追加しません。そのハンドラーを削除します。これがメモリリークを引き起こしているかどうかはわかりません。

サードパーティのハンドラーが最初に配置されるのを防ぐ方法はありますか?これに答えるためにフォローアップの質問をしました: コンソールコントロールハンドラーが上書きされないようにするにはどうすればよいですか?

これが私のカスタムJNIクラスメソッドで、サードパーティのDLLファイルを呼び出します。

JNIEXPORT jint JNICALL Java_com_company_ConvertProxy_convertToImageType(JNIEnv *env, jclass cls, jstring input, jstring output) {

    jboolean isCopy;
    inFilename = env->GetStringUTFChars(input, &isCopy);
    outFilename = env->GetStringUTFChars(output, &isCopy);

    // I tried to call SetConsoleCtrlHandler() here, but failed;
    // it turns out third-party code in ConvertImage() also
    // calls SetConsoleCtrlHandler and overrides it if placed here.

    int value = ConvertImage();

    // Deafen Control Logoffs set by third-party ConvertImage.
    // SetConsoleCtrlHandler( NULL, TRUE ); // DOES NOT WORK, must use custom CtrlHandler.
    SetConsoleCtrlHandler( (PHANDLER_ROUTINE) CtrlHandler, TRUE );

    return value;
}

BOOL CtrlHandler( DWORD fdwCtrlType ) {
    switch( fdwCtrlType )
    {
        // Handle the CTRL-C signal.
        case CTRL_C_EVENT:
          return( TRUE );

        // CTRL-CLOSE: confirm that the user wants to exit.
        case CTRL_CLOSE_EVENT:
          return( TRUE );

        case CTRL_BREAK_EVENT:
          return( TRUE );

        case CTRL_LOGOFF_EVENT:
          return( TRUE );

        case CTRL_SHUTDOWN_EVENT:
          return( TRUE );

        default:
          return FALSE;
      }
}
于 2011-10-12T22:21:39.560 に答える