From d556e79f69685e3e8f43cafaa8743482fae84c15 Mon Sep 17 00:00:00 2001 From: Ryan Richardson <24831926+propagating@users.noreply.github.com> Date: Fri, 27 May 2022 14:33:27 -0700 Subject: [PATCH] Adding DbgPrint and DbgPrintEx to Wdm (#299) * Adding DbgPrint and DbgPrintEx Functions to NtDll.Wdm.cs --- PInvoke/NtDll/Wdm.cs | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 118 insertions(+), 1 deletion(-) diff --git a/PInvoke/NtDll/Wdm.cs b/PInvoke/NtDll/Wdm.cs index 8101a655..506ce79f 100644 --- a/PInvoke/NtDll/Wdm.cs +++ b/PInvoke/NtDll/Wdm.cs @@ -90,6 +90,123 @@ namespace Vanara.PInvoke [PInvokeData("wdm.h", MSDNShortId = "deeac910-2cc3-4a54-bf3b-aeb56d0004dc")] public static extern void DbgBreakPoint(); + /// + /// The DbgPrint routine sends a message to the kernel debugger. + /// + /// In Windows Vista and later versions of Windows, DbgPrint sends a message only when the conditions that you specify + /// apply (see the Remarks section for information). + /// + /// + /// + /// + /// Specifies a pointer to the format string to print. The Format string supports most of the printf-style format specification fields. + /// However, the Unicode format codes (%C, %S, %lc, %ls, %wc, %ws, and %wZ) can only be used with IRQL = PASSIVE_LEVEL. + /// The DbgPrint routine does not support any of the floating point types (%f, %e, %E, %g, %G, %a, or %A). + /// + /// + /// + /// Specifies arguments for the format string, as in printf. + /// + /// + /// If successful, DbgPrint returns the NTSTATUS code STATUS_SUCCESS; otherwise it returns the appropriate error code. + /// + /// + /// + /// DbgPrint and DbgPrintEx can be called at IRQL<=DIRQL. However, Unicode format codes (%wc and %ws) can be used only + /// at IRQL=PASSIVE_LEVEL. Also, because the debugger uses interprocess interrupts (IPIs) to communicate with other processors, + /// calling DbgPrint at IRQL>DIRQL can cause deadlocks. + /// + /// Only kernel-mode drivers can call the DbgPrint routine. + /// + /// In Microsoft Windows Server 2003 and earlier versions of Windows, the DbgPrint routine sends a message to the kernel debugger. + /// In Windows Vista and later versions of Windows, DbgPrint sends a message only if certain conditions apply. + /// Specifically, it behaves like the DbgPrintEx routine with the DEFAULT component and a message importance level of DPFLTR_INFO_LEVEL. + /// + /// DbgPrint ( Format, arguments ), + /// DbgPrintEx ( DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, Format, arguments ) + /// + /// + /// For more information about message filtering, components, and message importance level, see Reading and Filtering Debugging Messages. + /// + /// Regardless of which version of Windows you are using, it is recommended that you use DbgPrintEx instead of DbgPrint, + /// since this allows you to control the conditions under which the message is sent. + /// + /// + /// Unless it is absolutely necessary, you should not obtain a string from user input or another process and pass it to DbgPrint. + /// If you do use a string that you did not create, you must verify that this is a valid format string, and that the format codes + /// match the argument list in type and quantity. The best coding practice is for all Format strings to be static and defined at compile time. + /// + /// + /// There is no upper limit to the size of the Format string or the number of arguments. However, any single call to DbgPrint + /// will only transmit 512 bytes of information. There is also a limit to the size of the DbgPrint buffer. + /// See DbgPrint Buffer and the Debugger for details. + /// + /// + // https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-dbgprint ULONG DbgPrint([in] PCSTR Format,...); + [DllImport(Lib.NtDll, SetLastError = false, ExactSpelling = true)] + [PInvokeData("wdm.h", MSDNShortId = "NF:wdm.DbgPrint")] + public static extern NTStatus DbgPrint([MarshalAs(UnmanagedType.LPTStr)] string Format, IntPtr arguments); + + /// + /// The DbgPrintEx routine sends a string to the kernel debugger if the conditions you specify are met. + /// + /// + /// Specifies the component calling this routine. This must be one of the component name filter IDs defined in the Dpfilter.h header file. + /// To avoid mixing your driver's output with the output of Windows components, you should use only the following values for ComponentId: + /// + /// + /// + /// Specifies the severity of the message being sent. This can be any 32-bit integer. Values between 0 and 31 (inclusive) + /// are treated differently than values between 32 and 0xFFFFFFFF. + /// For details, see Reading and Filtering Debugging Messages. + /// + /// + /// + /// Specifies a pointer to the format string to print. The Format string supports most of the printf-style format specification fields. + /// However, the Unicode format codes (%C, %S, %lc, %ls, %wc, %ws, and %wZ) can only be used with IRQL = PASSIVE_LEVEL. + /// The DbgPrintEx routine does not support any of the floating point types (%f, %e, %E, %g, %G, %a, or %A). + /// + /// + /// + /// Specifies arguments for the format string, as in printf. + /// + /// + /// If successful, DbgPrintEx returns the NTSTATUS code STATUS_SUCCESS; otherwise it returns the appropriate error code. + /// + /// + /// + /// Only kernel-mode drivers can call the DbgPrintEx routine. + /// + /// + /// DbgPrint and DbgPrintEx can be called at IRQL<=DIRQL. However, Unicode format codes (%wc and %ws) can be used only + /// at IRQL=PASSIVE_LEVEL. Also, because the debugger uses interprocess interrupts (IPIs) to communicate with other processors, + /// calling DbgPrint at IRQL>DIRQL can cause deadlocks. + /// + /// DbgPrintEx either passes the specified string to the kernel debugger or does nothing at all, depending on the values of + /// ComponentId, Level, and the corresponding component filter masks. For details, see Reading and Filtering Debugging Messages. + /// + /// + /// Unless it is absolutely necessary, you should not obtain a string from user input or another process and pass it to DbgPrintEx. + /// If you do use a string that you did not create, you must verify that this is a valid format string, and that the format codes + /// match the argument list in type and quantity. The best coding practice is for all Format strings to be static and defined at compile time. + /// + /// + /// There is no upper limit to the size of the Format string or the number of arguments. However, any single call to DbgPrintEx + /// will only transmit 512 bytes of information. There is also a limit to the size of the DbgPrint buffer. + /// See DbgPrint Buffer and the Debugger for details. + /// + /// + // https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-dbgprintex NTSYSAPI ULONG + // DbgPrintEx([in] ULONG ComponentId, [in] ULONG Level,[in] PCSTR Format,...); + [DllImport(Lib.NtDll, SetLastError = false, ExactSpelling = true)] + [PInvokeData("wdm.h", MSDNShortId = "NF:wdm.DbgPrintEx")] + public static extern NTStatus DbgPrintEx(uint ComponentId, uint Level, [MarshalAs(UnmanagedType.LPTStr)] string Format, IntPtr arguments); + /// /// /// The ZwCommitComplete routine notifies KTM that the calling resource manager has finished committing a transaction's data. @@ -3767,4 +3884,4 @@ ZwUnmapViewOfSection function ZwWriteFile function */ } -} \ No newline at end of file +}