c - Sådan vises en pop op-meddelelsesboks fra en driver (kernel-tilstand)?

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg skriver en chauffør, som umiddelbart skal pope op en dialog for at underrette brugeren om en begivenhed.

(Typen ligner NTFS 'em 'Korrupt fil' meddelelse, bortset fra at dette ikke er en filsystemrelateret driver.)


Jeg kender ExRaiseHardError og IoRaiseInformationalHardError burde være i stand til at gøre kunsten, men de synes ikke at arbejde - de vender tilbage 'med succes' uden at gøre noget.


Hvordan går jeg på at gøre dette ( uden oprette et brugertilstandsprogram)?





En brugermodus version af koden (som fungerer korrekt ) er nedenfor.


I kernel-modeversionen kalder jeg ExRaiseHardError i stedet for NtRaiseHardError, men på samme måde.


#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;
}

Bedste reference


En kernel driver kan ikke vise en MessageBox. Hvis du gerne vil gøre det, skal du levere en kommunikationsfunktionalitet via en bruger-land-applikation med kernel driveren og derefter vise MessageBox fra din brugerland applikation.


Alt tal om [Zw/Nt]RaiseHardError er irrelevant. Hvis du demonterer MessageBox, vil du bemærke, at denne API bliver kaldt til sidst.

Andre referencer 1


Jeg tror ikke, at uden en applikation (eller en tjeneste), der kører i brugerfunktionen, kan du indlæse en driver i hukommelsen (selvom det bliver en filterdriver).