如何从驱动程序显示弹出消息框(内核模式)? [英] How to display a pop-up message box from a driver (kernel mode)?
问题描述
我正在编写一个驱动程序,该驱动程序需要立即弹出一个对话框来通知用户事件。
(种类类似于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屋!