当远程桌面会话注销时,如何阻止 DLL 终止应用程序服务器?

发布于 2024-12-09 02:04:58 字数 1234 浏览 0 评论 0 原文

我有一个应用程序服务器(JBoss,但这也发生在 Tomcat 中)作为 Windows Server 2003 中的服务运行。它使用 -Xrs 标志运行。

在应用服务器下运行的 Java 应用程序通过 JNI 调用用 C++ 编写的可自定义接口(这意味着我们可以更改此代码),引用第三方 DLL 文件来处理图像 (Lincoln 用于转换 PostScript)。

当我们在控制台 (mstsc /console) 或管理员 (mstsc /admin) 模式下通过远程桌面连接登录服务器时,当我们注销时,如果 Lincoln DLL 文件一旦加载完毕,应用程序服务器将确认注销信号,并且服务进程将立即终止而不影响。

我相信信号是CTRL_LOGOFF,但我可能是错的。

关于信号处理的JavaJiggle文章之后,显然信号处理程序是在DLL文件处理时传递给DLL文件的。这意味着第三方 DLL 文件(在本例中为 Lincoln)通过注销来侦听并响应 CTRL_LOGOFF 信号。

我相信,我应该能够在 DLL 的 C++ 接口中编写一个信号捕获器,以在 CTRL_LOGOFF 到达 DLL 之前拦截它,如果是这样,那么当有人注销时我们就不会不断地死掉控制台/管理 RDP。

这是我需要的:

  1. 我在控制台/管理员注销/注销上收到的信号是CTRL_LOGOFF,我是否正确?

  2. 我可以在C++接口中编写信号拦截器吗?

  3. 如何编写该信号拦截器的代码,或者是否有预先存在的代码?我使用的是 32 位 DLL。

我找到了 Microsoft 文章注册一个控制处理函数,这可能有助于回答这个问题。

I have an application server (JBoss, but this also happens in Tomcat) running as a service in Windows Server 2003. It is running with the -Xrs flag.

The Java application running under the application server calls a customizable interface written in C++ via JNI (meaning we can alter this code), referencing a third-party DLL file for processing images (Lincoln for converting PostScript).

When we log into the server via Remote Desktop Connection in either console (mstsc /console) or administrator (mstsc /admin) mode, when we logout, if the Lincoln DLL file has been loaded, the application server will acknowledge the logoff signal and the service process will immediately terminate without prejudice.

I believe the signal is CTRL_LOGOFF, but I could be incorrect.

After JavaJiggle Article on Signal Handling, apparently signal handlers are passed to the DLL file when the DLL file is processing. This means the third-party DLL file (Lincoln in this case) listens to and responds to the CTRL_LOGOFF signal by logging off.

I believe, I should be able to code a signal catcher in my C++ interface to the DLL to intercept the CTRL_LOGOFF before it reaches the DLL and if so, then we won't constantly die when someone logs off of a console/admin RDP.

Here is what I need:

  1. Am I correct that the signal that I am getting on console/admin logoff/logout is CTRL_LOGOFF?

  2. Can I write a signal interceptor in the C++ interface?

  3. How do I code that signal interceptor, or is there pre-existing code? I am using a 32-bit DLL.

I have found Microsoft article Registering a Control Handler Function, which may help answer this question.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

惟欲睡 2024-12-16 02:04:58

我似乎已经通过每次调用第三方 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;
      }
}

I seem to have resolved it by adding an ignore handler to the stack every time the third-party DLL is called, but I fear each time I call my method, we keep adding handlers to the stack and obviously the third-party DLL does not remove its handlers. I do not know whether this is creating a memory leak.

Is there is a way to prevent a third-party handler from being placed in the first place? I have asked a follow-up question to answer this: How can I prevent my Console Control Handler from being overridden?.

Here is my custom JNI class method, which calls the third-party DLL file:

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;
      }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文