如何从驱动程序显示弹出消息框(内核模式)? [英] How to display a pop-up message box from a driver (kernel mode)?

查看:285
本文介绍了如何从驱动程序显示弹出消息框(内核模式)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个驱动程序,该驱动程序需要立即弹出一个对话框来通知用户事件。

(种类类似于NTFS的损坏的文件 通知,除了不是与文件系统相关的驱动程序。)

I'm writing a driver which needs to immediately pop up a dialog to notify the user of an event.
(Kind of similar to NTFS's "Corrupt file" notification, except that this is not a filesystem-related driver.)

我知道 ExRaiseHardError IoRaiseInformationalHardError 应该可以解决问题,但是它们似乎没有用,它们在没有做任何事情的情况下成功返回。

I know ExRaiseHardError and IoRaiseInformationalHardError should be able to do the trick, but they don't seem to work -- they return "successfully" without actually doing anything.

如何执行此操作(创建用户模式程序)?

How do I go about doing this (without creating a user-mode program)?

下面的代码的 user-mode 版本(可以正常工作)。

A user-mode version of the code (which works correctly) is below.

在内核中模式版本,我调用 ExRaiseHardError 而不是 NtRaiseHardError ,但使用的方式完全相同。

In the kernel-mode version, I call ExRaiseHardError instead of NtRaiseHardError, but in the exact same way.

#include <windows.h>

#pragma comment(lib, "ntdll.lib")    // Needs ntdll.lib from Windows Driver Kit

typedef enum HardErrorResponseType {
    ResponseTypeAbortRetryIgnore,
    ResponseTypeOK,
    ResponseTypeOKCancel,
    ResponseTypeRetryCancel,
    ResponseTypeYesNo,
    ResponseTypeYesNoCancel,
    ResponseTypeShutdownSystem,
    ResponseTypeTrayNotify,
    ResponseTypeCancelTryAgainContinue
} HardErrorResponseType;

typedef enum HardErrorResponse {
    ResponseReturnToCaller,
    ResponseNotHandled,
    ResponseAbort, ResponseCancel,
    ResponseIgnore,
    ResponseNo,
    ResponseOk,
    ResponseRetry,
    ResponseYes
} HardErrorResponse;

typedef enum HardErrorResponseButton {
    ResponseButtonOK,
    ResponseButtonOKCancel,
    ResponseButtonAbortRetryIgnore,
    ResponseButtonYesNoCancel,
    ResponseButtonYesNo,
    ResponseButtonRetryCancel,
    ResponseButtonCancelTryAgainContinue
} HardErrorResponseButton;

typedef enum HardErrorResponseDefaultButton {
    DefaultButton1 = 0,
    DefaultButton2 = 0x100,
    DefaultButton3 = 0x200
} HardErrorResponseDefaultButton;

typedef enum HardErrorResponseIcon {
    IconAsterisk = 0x40,
    IconError = 0x10,
    IconExclamation = 0x30,
    IconHand = 0x10,
    IconInformation = 0x40,
    IconNone = 0,
    IconQuestion = 0x20,
    IconStop = 0x10,
    IconWarning = 0x30,
    IconUserIcon = 0x80
} HardErrorResponseIcon;

typedef enum HardErrorResponseOptions {
    ResponseOptionNone = 0,
    ResponseOptionDefaultDesktopOnly = 0x20000,
    ResponseOptionHelp = 0x4000,
    ResponseOptionRightAlign = 0x80000,
    ResponseOptionRightToLeftReading = 0x100000,
    ResponseOptionTopMost = 0x40000,
    ResponseOptionServiceNotification = 0x00200000,
    ResponseOptionServiceNotificationNT3X = 0x00040000,
    ResponseOptionSetForeground = 0x10000,
    ResponseOptionSystemModal = 0x1000,
    ResponseOptionTaskModal = 0x2000,
    ResponseOptionNoFocus = 0x00008000
} HardErrorResponseOptions;

typedef LONG NTSTATUS;

typedef struct _UNICODE_STRING {
    USHORT Length;
    USHORT MaximumLength;
    PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

EXTERN_C DECLSPEC_IMPORT NTSTATUS NTAPI NtRaiseHardError(
    IN NTSTATUS ErrorStatus, IN ULONG NumberOfParameters,
    IN ULONG UnicodeStringParameterMask, IN PULONG_PTR Parameters,
    IN ULONG ValidResponseOptions,
    OUT HardErrorResponse *Response);

EXTERN_C DECLSPEC_IMPORT VOID NTAPI RtlInitUnicodeString(
    IN OUT PUNICODE_STRING DestinationString, IN PCWSTR SourceString);

#define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L)
#define STATUS_SERVICE_NOTIFICATION ((NTSTATUS)0x50000018L)

int main(void)
{
    HardErrorResponse r;

    // To display a standard NTSTATUS value:
    NtRaiseHardError(STATUS_ACCESS_DENIED, 0, 0, NULL, ResponseTypeOK, &r);

    // To display a custom string:
    UNICODE_STRING wTitle, wText;
    RtlInitUnicodeString(&wTitle, L"Title");
    RtlInitUnicodeString(&wText, L"Text");
    ULONG_PTR params[4] = {
        (ULONG_PTR)&wText,
        (ULONG_PTR)&wTitle,
        (
            (ULONG)ResponseButtonOK   |
            (ULONG)IconInformation    |
            (ULONG)ResponseOptionNone |
            (ULONG)DefaultButton1
        ),
        INFINITE
    };
    NtRaiseHardError(STATUS_SERVICE_NOTIFICATION, 4, 0x3, params, 0, &r);

    return 0;
}


推荐答案

内核驱动程序无法显示消息框。如果您要这样做,则必须通过带有内核驱动程序的用户界面应用程序提供通信功能,然后从用户界面应用程序显示该MessageBox。

A kernel driver can not display a MessageBox. If you would like to do that then you have to provide a communication functionality through a user-land application with the kernel driver then show that MessageBox from your user-land application.

关于 [Zw / Nt] RaiseHardError 的所有讨论都是无关紧要的。如果您拆开MessageBox,您会注意到该API最终会被调用。

All the talk about [Zw/Nt]RaiseHardError is irrelevant. If you disassembled MessageBox you will notice that this API gets called eventually.

这篇关于如何从驱动程序显示弹出消息框(内核模式)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆