加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 如何从驱动程序显示弹出消息框(内核模式)?

发布时间:2020-12-16 06:59:27 所属栏目:百科 来源:网络整理
导读:我正在编写一个驱动程序,需要立即弹出一个对话框来通知用户一个事件. (类似于NTFS的“损坏文件”通知,除了这不是与文件系统相关的驱动程序.) 我知道ExRaiseHardError和IoRaiseInformationalHardError应该可以做到这一点,但它们似乎不起作用 – 它们“成功”
我正在编写一个驱动程序,需要立即弹出一个对话框来通知用户一个事件.
(类似于NTFS的“损坏文件”通知,除了这不是与文件系统相关的驱动程序.)

我知道ExRaiseHardError和IoRaiseInformationalHardError应该可以做到这一点,但它们似乎不起作用 – 它们“成功”返回而不实际做任何事情.

我该怎么做(没有创建用户模式程序)?

代码的用户模式版本(可正常工作)如下所示.

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

#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,NULL,&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,&r);

    return 0;
}

解决方法

内核驱动程序无法显示MessageBox.如果您想这样做,那么您必须通过内核驱动程序通过用户登陆应用程序提供通信功能,然后从您的用户登陆应用程序中显示MessageBox.

所有关于[Zw / Nt] RaiseHardError的讨论都是无关紧要的.如果您反汇编MessageBox,您会注意到最终会调用此API.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读