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:
+ ///
- DPFLTR_IHVVIDEO_ID
+ /// - DPFLTR_IHVAUDIO_ID
+ /// - DPFLTR_IHVNETWORK_ID
+ /// - DPFLTR_IHVSTREAMING_ID
+ /// - DPFLTR_IHVBUS_ID
+ /// - DPFLTR_IHVDRIVER_ID
+ ///
+ ///
+ /// 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
+}