diff --git a/src/drivers/kmdf/queries/FloatUnsafeExit/FloatUnsafeExit.md b/src/drivers/kmdf/queries/FloatUnsafeExit/FloatUnsafeExit.md
new file mode 100644
index 00000000..74a898db
--- /dev/null
+++ b/src/drivers/kmdf/queries/FloatUnsafeExit/FloatUnsafeExit.md
@@ -0,0 +1,68 @@
+# Float Unsafe Exit
+Exiting without acquiring the right to use floating hardware
+
+
+## Recommendation
+The _Kernel_float_saved_ annotation was used to acquire the right to use floating point, but a path through the function was detected where no function known to perform that operation was successfully called. This warning might indicate that a conditional (_When_) annotation is needed, or it might indicate a coding error.
+
+
+## Example
+Function has _Kernel_float_saved_ annotation but has a path where the floating point state is not saved. Additionally, KeSaveFloatingPointState return value is not checked so the call might fail
+
+```c
+
+ _Kernel_float_saved_
+ void float_used_bad3()
+ {
+ float f = 0.0f;
+ // Status not checked here
+ int some_condition = 1;
+ KFLOATING_SAVE saveData;
+ NTSTATUS status;
+
+ if (some_condition)
+ {
+ // This code path doesn't save the floating point state
+ for (int i = 0; i < 100; i++)
+ {
+ f = f + 1;
+ }
+ }
+ else
+ {
+ status = KeSaveFloatingPointState(&saveData);
+ // Status not checked here
+ for (int i = 0; i < 100; i++)
+ {
+ f = f + 1.0f;
+ }
+ }
+ }
+
+```
+Good example
+
+```c
+
+ Kernel_float_saved_
+ void float_used_good1()
+ {
+ KFLOATING_SAVE saveData;
+ NTSTATUS status;
+ float f = 0.0f;
+ status = KeSaveFloatingPointState(&saveData);
+ if (status != STATUS_SUCCESS)
+ {
+ return;
+ }
+ for (int i = 0; i < 100; i++)
+ {
+ f = f + 1.0f;
+ }
+ KeRestoreFloatingPointState(&saveData);
+ }
+
+```
+
+## References
+* [ Warning C28161 ](https://learn.microsoft.com/en-us/windows-hardware/drivers/devtest/28161-exiting-without-right-to-use-floating-hardware)
diff --git a/src/drivers/kmdf/queries/FloatUnsafeExit/FloatUnsafeExit.qhelp b/src/drivers/kmdf/queries/FloatUnsafeExit/FloatUnsafeExit.qhelp
index 354fe0bc..54be31c3 100644
--- a/src/drivers/kmdf/queries/FloatUnsafeExit/FloatUnsafeExit.qhelp
+++ b/src/drivers/kmdf/queries/FloatUnsafeExit/FloatUnsafeExit.qhelp
@@ -41,7 +41,6 @@
f = f + 1.0f;
}
}
- }
}]]>
@@ -64,14 +63,9 @@
f = f + 1.0f;
}
KeRestoreFloatingPointState(&saveData);
- }
}]]>
-
-
-
-
diff --git a/src/drivers/kmdf/queries/experimental/DeviceInitApi/DeviceInitApi.md b/src/drivers/kmdf/queries/experimental/DeviceInitApi/DeviceInitApi.md
new file mode 100644
index 00000000..72d4b687
--- /dev/null
+++ b/src/drivers/kmdf/queries/experimental/DeviceInitApi/DeviceInitApi.md
@@ -0,0 +1 @@
+# Calling WDF object initialization API after WdfDeviceCreate
diff --git a/src/drivers/kmdf/queries/wfp/ConnectRedirectHandleCreation/ConnectRedirectMultipleCallsHandleCreation.md b/src/drivers/kmdf/queries/wfp/ConnectRedirectHandleCreation/ConnectRedirectMultipleCallsHandleCreation.md
new file mode 100644
index 00000000..3af5db71
--- /dev/null
+++ b/src/drivers/kmdf/queries/wfp/ConnectRedirectHandleCreation/ConnectRedirectMultipleCallsHandleCreation.md
@@ -0,0 +1 @@
+# Connect Redirect Callouts
diff --git a/src/drivers/kmdf/queries/wfp/ConnectRedirectPendClassify/ConnectRedirectPendClassify.md b/src/drivers/kmdf/queries/wfp/ConnectRedirectPendClassify/ConnectRedirectPendClassify.md
new file mode 100644
index 00000000..258583ab
--- /dev/null
+++ b/src/drivers/kmdf/queries/wfp/ConnectRedirectPendClassify/ConnectRedirectPendClassify.md
@@ -0,0 +1 @@
+# Connect Redirect Callout Pend Classify
diff --git a/src/drivers/kmdf/queries/wfp/FlowLayerCalloutReturnsBlock/FlowLayerCalloutReturnsBlock.md b/src/drivers/kmdf/queries/wfp/FlowLayerCalloutReturnsBlock/FlowLayerCalloutReturnsBlock.md
new file mode 100644
index 00000000..7d1f4891
--- /dev/null
+++ b/src/drivers/kmdf/queries/wfp/FlowLayerCalloutReturnsBlock/FlowLayerCalloutReturnsBlock.md
@@ -0,0 +1 @@
+# Flow Layer Callouts
diff --git a/src/drivers/kmdf/queries/wfp/InlineConnectRedirect/InlineConnectRedirectCalloutShouldNotSetReauthorize.md b/src/drivers/kmdf/queries/wfp/InlineConnectRedirect/InlineConnectRedirectCalloutShouldNotSetReauthorize.md
new file mode 100644
index 00000000..b6bb41c7
--- /dev/null
+++ b/src/drivers/kmdf/queries/wfp/InlineConnectRedirect/InlineConnectRedirectCalloutShouldNotSetReauthorize.md
@@ -0,0 +1 @@
+# Connect Redirect Inline Callout cannot set reauth
diff --git a/src/drivers/kmdf/queries/wfp/OobStreamInjection/OobStreamInjectionReturnsBlock.md b/src/drivers/kmdf/queries/wfp/OobStreamInjection/OobStreamInjectionReturnsBlock.md
new file mode 100644
index 00000000..158a9955
--- /dev/null
+++ b/src/drivers/kmdf/queries/wfp/OobStreamInjection/OobStreamInjectionReturnsBlock.md
@@ -0,0 +1 @@
+# Stream Injection Action Type explicitly set to FWP_ACTION_BLOCK
diff --git a/src/drivers/kmdf/queries/wfp/StreamCalloutsSetActionType/StreamCalloutsSetActionType.md b/src/drivers/kmdf/queries/wfp/StreamCalloutsSetActionType/StreamCalloutsSetActionType.md
new file mode 100644
index 00000000..57c3dcb9
--- /dev/null
+++ b/src/drivers/kmdf/queries/wfp/StreamCalloutsSetActionType/StreamCalloutsSetActionType.md
@@ -0,0 +1 @@
+# For non-inspection (injection) Stream callouts must set the actionType regardless
diff --git a/src/drivers/kmdf/queries/wfp/StreamInspectionCallViolation/StreamInspectionFunctionCallViolation.md b/src/drivers/kmdf/queries/wfp/StreamInspectionCallViolation/StreamInspectionFunctionCallViolation.md
new file mode 100644
index 00000000..e7e4eb1d
--- /dev/null
+++ b/src/drivers/kmdf/queries/wfp/StreamInspectionCallViolation/StreamInspectionFunctionCallViolation.md
@@ -0,0 +1 @@
+# Stream Inspection OOB (Out of Band) functional contract
diff --git a/src/drivers/kmdf/queries/wfp/TransportLayerCannotInjectCloneDuringClassify/TransportLayerCannotInjectCloneDuringClassify.md b/src/drivers/kmdf/queries/wfp/TransportLayerCannotInjectCloneDuringClassify/TransportLayerCannotInjectCloneDuringClassify.md
new file mode 100644
index 00000000..cbf4dbf8
--- /dev/null
+++ b/src/drivers/kmdf/queries/wfp/TransportLayerCannotInjectCloneDuringClassify/TransportLayerCannotInjectCloneDuringClassify.md
@@ -0,0 +1 @@
+# Transport Layer Cannot Inject Clone During Classify
diff --git a/src/drivers/test/TestTemplates/QueryTemplate/QueryTemplate.qhelp b/src/drivers/test/TestTemplates/QueryTemplate/QueryTemplate.qhelp
index f44c2856..5e53ca8a 100644
--- a/src/drivers/test/TestTemplates/QueryTemplate/QueryTemplate.qhelp
+++ b/src/drivers/test/TestTemplates/QueryTemplate/QueryTemplate.qhelp
@@ -16,14 +16,14 @@
+ ]]>
TODO example 2
+ ]]>
diff --git a/src/drivers/wdm/queries/IllegalFieldAccess/IllegalFieldAccess.md b/src/drivers/wdm/queries/IllegalFieldAccess/IllegalFieldAccess.md
new file mode 100644
index 00000000..f76e102f
--- /dev/null
+++ b/src/drivers/wdm/queries/IllegalFieldAccess/IllegalFieldAccess.md
@@ -0,0 +1,30 @@
+# Incorrect access to protected field (C28128)
+Assignments to private fields of DeviceObjects, DPCs, and IRPs should not be made directly.
+
+The MSDN documentation for the Code Analysis version of this check is not consistent with the behavior of the check; it states that the check looks for incorrect assignments to an IRP's CancelRoutine field, while the check actually looks for incorrect assignments to DPCs or DPC fields. This verison of the check implements both these behaviors.
+
+
+## Recommendation
+Instead of making direct assignments, refer to MSDN and the output of running this query for the correct API to use.
+
+
+## Example
+In this example, the driver directly edits an IRP's CancelRoutine, which is not supported.
+
+```c
+
+ irp->CancelRoutine = myCancelRoutine;
+
+
+```
+The driver should instead call IoSetCancelRoutine:
+
+```c
+
+ oldCancel = IoSetCancelRoutine(irp, myCancelRoutine);
+
+
+```
+
+## References
+* [ C28128 warning - Windows Drivers ](https://learn.microsoft.com/en-us/windows-hardware/drivers/devtest/28128-structure-member-directly-accessed)
diff --git a/src/drivers/wdm/queries/IllegalFieldAccess2/IllegalFieldAccess2.md b/src/drivers/wdm/queries/IllegalFieldAccess2/IllegalFieldAccess2.md
new file mode 100644
index 00000000..c0088b4a
--- /dev/null
+++ b/src/drivers/wdm/queries/IllegalFieldAccess2/IllegalFieldAccess2.md
@@ -0,0 +1,37 @@
+# Illegal access to a protected field (C28175)
+Drivers should not read inaccessible fields of driver structs.
+
+
+## Recommendation
+Driver developers should avoid reading these fields in their drivers.
+
+
+## Example
+In this example, the driver directly reads a DeviceObject's "Size" field.
+
+```c
+
+ NTSTATUS CompletionRoutine(
+ PDEVICE_OBJECT DeviceObject,
+ PIRP Irp,
+ PVOID Context
+ )
+ {
+ if (DeviceObject->Size > 0x10)
+ {
+ // Do some logic
+ }
+ return;
+ }
+
+
+```
+The driver should not access this field.
+
+
+## References
+* [ C28175 warning - Windows Drivers ](https://learn.microsoft.com/en-us/windows-hardware/drivers/devtest/28175struct-member-should-not-be-accessed-by-driver)
+
+## Semmle-specific notes
+It is legal for filesystem drivers to access some fields that should not be accessed by other drivers; this case is not accounted for in the rule at this time.
+
diff --git a/src/drivers/wdm/queries/IllegalFieldWrite/IllegalFieldWrite.md b/src/drivers/wdm/queries/IllegalFieldWrite/IllegalFieldWrite.md
new file mode 100644
index 00000000..415c1bda
--- /dev/null
+++ b/src/drivers/wdm/queries/IllegalFieldWrite/IllegalFieldWrite.md
@@ -0,0 +1,31 @@
+# Illegal write to a protected field (C28176)
+The driver is writing to a read-only field of a driver struct.
+
+Note that this check only reports violations when the field is explicitly read-only, and not completely inaccessible. For finding reads of inaccessible fields, use IllegalFieldAccess and IllegalFieldAccess2.
+
+
+## Recommendation
+Driver writers should not make changes to these fields except in specific contexts.
+
+
+## Example
+In this example, the driver directly edits a DriverObject's flags in a DriverUnload callback, which is not supported.
+
+```c
+
+ VOID
+ DriverUnload (
+ PDRIVER_OBJECT DriverObject
+ )
+ {
+ DriverObject->Flags &= 0x100000;
+ return;
+ }
+
+
+```
+The driver should only adjust the Flags field in DriverEntry.
+
+
+## References
+* [ C28176 warning - Windows Drivers ](https://learn.microsoft.com/en-us/windows-hardware/drivers/devtest/28176-struct-member-should-not-be-modified-by-driver)
diff --git a/src/drivers/wdm/queries/InconsistentDispatchAnnotations.md b/src/drivers/wdm/queries/InconsistentDispatchAnnotations.md
new file mode 100644
index 00000000..c7b55079
--- /dev/null
+++ b/src/drivers/wdm/queries/InconsistentDispatchAnnotations.md
@@ -0,0 +1 @@
+# Inconsistent annotation of WDM dispatch routine.
diff --git a/src/drivers/wdm/queries/InitNotCleared/InitNotCleared.md b/src/drivers/wdm/queries/InitNotCleared/InitNotCleared.md
new file mode 100644
index 00000000..2bf882a9
--- /dev/null
+++ b/src/drivers/wdm/queries/InitNotCleared/InitNotCleared.md
@@ -0,0 +1,136 @@
+# Failure to clear DO_DEVICE_INITIALIZING (C28152)
+A WDM AddDevice routine must clear the DO_DEVICE_INITIALIZING flag of the filter device object or functional device object it creates.
+
+
+## Recommendation
+Clear the DO_DEVICE_INITIALIZING flag of the FDO with code like "FunctionalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;"
+
+
+## Example
+
+```c
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+//
+// driver_snippet.c
+//
+
+#define SET_DISPATCH 1
+
+DRIVER_ADD_DEVICE AddDevice_Pass1;
+DRIVER_ADD_DEVICE AddDevice_Pass2;
+DRIVER_ADD_DEVICE AddDevice_Fail1;
+DRIVER_ADD_DEVICE AddDevice_Fail2;
+
+// Template. Not called in this test.
+void top_level_call() {}
+
+// PASS: Directly creates the FDO and clears flags
+
+NTSTATUS
+AddDevice_Pass1 (
+ PDRIVER_OBJECT DriverObject,
+ PDEVICE_OBJECT PhysicalDeviceObject
+ )
+{
+ PDEVICE_OBJECT device;
+ PDEVICE_OBJECT TopOfStack;
+ NTSTATUS status;
+
+ UNREFERENCED_PARAMETER(PhysicalDeviceObject);
+
+ PAGED_CODE();
+
+ status = IoCreateDevice(DriverObject,
+ sizeof(DRIVER_DEVICE_EXTENSION),
+ NULL,
+ FILE_DEVICE_DISK,
+ 0,
+ FALSE,
+ &device
+ );
+ if(status==STATUS_SUCCESS)
+ {
+ device->Flags &= ~DO_DEVICE_INITIALIZING;
+ }
+
+ return status;
+}
+
+// PASS: Indirectly creates the FDO and clears flags
+NTSTATUS
+AddDevice_Pass2 (
+ PDRIVER_OBJECT DriverObject,
+ PDEVICE_OBJECT PhysicalDeviceObject
+ )
+{
+ NTSTATUS status;
+
+ UNREFERENCED_PARAMETER(PhysicalDeviceObject);
+
+ PAGED_CODE();
+
+ status = AddDevice_Pass1(DriverObject, PhysicalDeviceObject);
+
+ return status;
+}
+
+// FAIL: Creates the FDO but doesn't clear flags
+NTSTATUS
+AddDevice_Fail1 (
+ PDRIVER_OBJECT DriverObject,
+ PDEVICE_OBJECT PhysicalDeviceObject
+ )
+{
+ PDEVICE_OBJECT device;
+ PDEVICE_OBJECT TopOfStack;
+ NTSTATUS status;
+
+ UNREFERENCED_PARAMETER(PhysicalDeviceObject);
+
+ PAGED_CODE();
+
+ status = IoCreateDevice(DriverObject,
+ sizeof(DRIVER_DEVICE_EXTENSION),
+ NULL,
+ FILE_DEVICE_DISK,
+ 0,
+ FALSE,
+ &device
+ );
+ return status;
+}
+
+// FAIL: Creates the FDO but doesn't clear the correct flags
+NTSTATUS
+AddDevice_Fail2 (
+ PDRIVER_OBJECT DriverObject,
+ PDEVICE_OBJECT PhysicalDeviceObject
+ )
+{
+ PDEVICE_OBJECT device;
+ PDEVICE_OBJECT TopOfStack;
+ NTSTATUS status;
+
+ UNREFERENCED_PARAMETER(PhysicalDeviceObject);
+
+ PAGED_CODE();
+
+ status = IoCreateDevice(DriverObject,
+ sizeof(DRIVER_DEVICE_EXTENSION),
+ NULL,
+ FILE_DEVICE_DISK,
+ 0,
+ FALSE,
+ &device
+ );
+ if(status==STATUS_SUCCESS)
+ {
+ device->Flags &= ~DO_POWER_PAGABLE;
+ }
+ return status;
+}
+```
+
+## References
+* [ C28152 warning - Windows Drivers ](https://learn.microsoft.com/en-us/windows-hardware/drivers/devtest/28152-do-device-initializing-flag-not-cleared)
diff --git a/src/drivers/wdm/queries/KeWaitLocal/KeWaitLocal.md b/src/drivers/wdm/queries/KeWaitLocal/KeWaitLocal.md
new file mode 100644
index 00000000..d596d968
--- /dev/null
+++ b/src/drivers/wdm/queries/KeWaitLocal/KeWaitLocal.md
@@ -0,0 +1,37 @@
+# Use of local variable and UserMode in call to KeWaitSingleObject
+If the first argument to KeWaitForSingleObject is a local variable, the Mode parameter must be KernelMode The driver is waiting in user mode. As such, the kernel stack can be swapped out during the wait. If the driver attempts to pass parameters on the stack, a system crash can result.
+
+
+## Recommendation
+If the first argument to KeWaitForSingleObject is a local variable, the Mode parameter must be KernelMode.
+
+
+## Example
+
+```c
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+
+//Macros to enable or disable a code section that may or maynot conflict with this test.
+#define SET_DISPATCH 1
+
+void good_use(){
+ //Raises Warning
+ KEVENT kevent1;
+ KeWaitForSingleObject(&kevent1, UserRequest, UserMode, FALSE, NULL);
+}
+
+void bad_use(){
+ //Avoids warning as it's AccessMode is KernelMode for a local first argument, kevent2.
+ KEVENT kevent2;
+ KeWaitForSingleObject(&kevent2, UserRequest, KernelMode, FALSE, NULL);
+}
+
+void top_level_call() {
+ good_use();
+ bad_use();
+}
+```
+
+## References
+* [ C28135 warning - Windows Drivers ](https://docs.microsoft.com/en-us/windows-hardware/drivers/devtest/28135-first-argument-to-kewaitforsingleobject)
diff --git a/src/drivers/wdm/queries/MultiplePagedCode/MultiplePagedCode.md b/src/drivers/wdm/queries/MultiplePagedCode/MultiplePagedCode.md
new file mode 100644
index 00000000..2b561625
--- /dev/null
+++ b/src/drivers/wdm/queries/MultiplePagedCode/MultiplePagedCode.md
@@ -0,0 +1,74 @@
+# Multiple instances of PAGED_CODE or PAGED_CODE_LOCKED
+The function has more than one instance of PAGED_CODE or PAGED_CODE_LOCKED. This warning indicates that there is more than one instance of the PAGED_CODE or PAGED_CODE_LOCKED macro in a function. This error is reported at the second or subsequent instances of the PAGED_CODE or PAGED_CODE_LOCKED macro.
+
+
+## Recommendation
+Remove all but one PAGED_CODE OR PAGED_CODE_LOCKED macro.
+
+
+## Example
+
+```c
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+
+
+//Macros to enable or disable a code section that may or maynot conflict with this test.
+#define SET_DISPATCH 1
+#define SET_PAGE_CODE 1
+
+
+_Dispatch_type_(IRP_MJ_CLEANUP)
+DRIVER_DISPATCH DispatchCleanup;
+
+_Dispatch_type_(IRP_MJ_SHUTDOWN)
+DRIVER_DISPATCH DispatchShutdown;
+
+#ifndef __cplusplus
+#pragma alloc_text (PAGE, DispatchCleanup)
+#pragma alloc_text (PAGE, DispatchShutdown)
+#endif
+
+
+//Template
+void top_level_call(){
+}
+
+//Passes
+NTSTATUS
+DispatchCleanup (
+ PDEVICE_OBJECT DriverObject,
+ PIRP Irp
+ )
+{
+ UNREFERENCED_PARAMETER(DriverObject);
+ UNREFERENCED_PARAMETER(Irp);
+ PAGED_CODE();
+
+ return STATUS_SUCCESS;
+}
+
+//Fails
+NTSTATUS
+DispatchShutdown (
+ PDEVICE_OBJECT DriverObject,
+ PIRP Irp
+ )
+{
+ UNREFERENCED_PARAMETER(DriverObject);
+ UNREFERENCED_PARAMETER(Irp);
+ PAGED_CODE();
+ PAGED_CODE();
+
+ return STATUS_SUCCESS;
+}
+
+
+
+
+
+
+```
+
+## References
+* [ C28171 warning - Windows Drivers ](https://docs.microsoft.com/en-us/windows-hardware/drivers/devtest/28171-function-has-more-than-one-page-macro-instance)
diff --git a/src/drivers/wdm/queries/NoPagedCode/NoPagedCode.md b/src/drivers/wdm/queries/NoPagedCode/NoPagedCode.md
new file mode 100644
index 00000000..abd7f263
--- /dev/null
+++ b/src/drivers/wdm/queries/NoPagedCode/NoPagedCode.md
@@ -0,0 +1,89 @@
+# No PAGED_CODE invocation
+The function has been declared to be in a paged segment, but neither PAGED_CODE nor PAGED_CODE_LOCKED was found.
+
+
+## Recommendation
+The functions in pageable code must contain a PAGED_CODE or PAGED_CODE_LOCKED macro at the beginning of the function. The PAGED_CODE macro ensures that the calling thread is running at an IRQL that is low enough to permit paging.
+
+
+## Example
+
+```c
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+
+
+//Macros to enable or disable a code section that may or maynot conflict with this test.
+#define SET_DISPATCH 1
+#define SET_PAGE_CODE 1
+
+
+_Dispatch_type_(IRP_MJ_CLEANUP)
+DRIVER_DISPATCH DispatchCleanup;
+
+_Dispatch_type_(IRP_MJ_SHUTDOWN)
+DRIVER_DISPATCH DispatchShutdown;
+
+#ifndef __cplusplus
+#pragma alloc_text (PAGE, DispatchCleanup)
+#pragma alloc_text (PAGE, DispatchShutdown)
+#endif
+
+
+//Template
+void top_level_call(){
+}
+
+//Passes
+NTSTATUS
+DispatchCleanup (
+ PDEVICE_OBJECT DriverObject,
+ PIRP Irp
+ )
+{
+ UNREFERENCED_PARAMETER(DriverObject);
+ UNREFERENCED_PARAMETER(Irp);
+ PAGED_CODE();
+
+ return STATUS_SUCCESS;
+}
+
+//Fails
+NTSTATUS
+DispatchShutdown (
+ PDEVICE_OBJECT DriverObject,
+ PIRP Irp
+ )
+{
+ UNREFERENCED_PARAMETER(DriverObject);
+ UNREFERENCED_PARAMETER(Irp);
+
+ return STATUS_SUCCESS;
+}
+
+
+#pragma code_seg("PAGE")
+//Fails
+NTSTATUS func1(){
+ if(TRUE){
+
+ }
+ return STATUS_SUCCESS;
+}
+#pragma code_seg()
+
+//Passes
+NTSTATUS func2(){
+ return STATUS_SUCCESS;
+}
+
+#define PAGED_CODE_SEG __declspec(code_seg("PAGE"))
+//Fails
+PAGED_CODE_SEG
+NTSTATUS func3(){
+ return STATUS_SUCCESS;
+}
+```
+
+## References
+* [ C28170 warning - Windows Drivers ](https://docs.microsoft.com/en-us/windows-hardware/drivers/devtest/28170-pageable-code-macro-not-found)
diff --git a/src/drivers/wdm/queries/NoPagingSegment/NoPagingSegment.md b/src/drivers/wdm/queries/NoPagingSegment/NoPagingSegment.md
new file mode 100644
index 00000000..cd31eb87
--- /dev/null
+++ b/src/drivers/wdm/queries/NoPagingSegment/NoPagingSegment.md
@@ -0,0 +1,91 @@
+# No paging segment for PAGED_CODE macro invocation
+The function has PAGED_CODE or PAGED_CODE_LOCKED but is not declared to be in a paged segment. A function that contains a PAGED_CODE or PAGED_CODE_LOCKED macro has not been placed in paged memory by using \#pragma alloc_text or \#pragma code_seg.
+
+
+## Recommendation
+Put a function/routine that calls PAGED_CODE in a paged section using \#pragma alloc_text or \#pragma code_seg.
+
+
+## Example
+
+```c
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+
+
+//Macros to enable or disable a code section that may or maynot conflict with this test.
+#define SET_DISPATCH 1
+#define SET_PAGE_CODE 1
+
+
+_Dispatch_type_(IRP_MJ_CLEANUP)
+DRIVER_DISPATCH DispatchCleanup;
+
+_Dispatch_type_(IRP_MJ_SHUTDOWN)
+DRIVER_DISPATCH DispatchShutdown;
+
+#ifndef __cplusplus
+#pragma alloc_text (PAGE, DispatchCleanup)
+#endif
+
+
+//Template
+void top_level_call(){
+}
+
+//Passes
+NTSTATUS
+DispatchCleanup (
+ PDEVICE_OBJECT DriverObject,
+ PIRP Irp
+ )
+{
+ UNREFERENCED_PARAMETER(DriverObject);
+ UNREFERENCED_PARAMETER(Irp);
+ PAGED_CODE();
+
+ return STATUS_SUCCESS;
+}
+
+//Fails
+NTSTATUS
+DispatchShutdown (
+ PDEVICE_OBJECT DriverObject,
+ PIRP Irp
+ )
+{
+ UNREFERENCED_PARAMETER(DriverObject);
+ UNREFERENCED_PARAMETER(Irp);
+ PAGED_CODE();
+
+ return STATUS_SUCCESS;
+}
+
+
+#pragma code_seg("PAGE")
+//Passes
+NTSTATUS func1(){
+ PAGED_CODE();
+ if(TRUE){
+ }
+ return STATUS_SUCCESS;
+}
+#pragma code_seg()
+
+//Fails
+NTSTATUS func2(){
+ PAGED_CODE();
+ return STATUS_SUCCESS;
+}
+
+#define PAGED_CODE_SEG __declspec(code_seg("PAGE"))
+//Passes
+PAGED_CODE_SEG
+NTSTATUS func3(){
+ PAGED_CODE();
+ return STATUS_SUCCESS;
+}
+```
+
+## References
+* [ C28172 warning - Windows Drivers ](https://docs.microsoft.com/en-us/windows-hardware/drivers/devtest/28172-function-macros-not-in-paged-segment)
diff --git a/src/drivers/wdm/queries/ObReferenceMode/ObReferenceMode.md b/src/drivers/wdm/queries/ObReferenceMode/ObReferenceMode.md
new file mode 100644
index 00000000..86978a1e
--- /dev/null
+++ b/src/drivers/wdm/queries/ObReferenceMode/ObReferenceMode.md
@@ -0,0 +1,45 @@
+# The AccessMode parameter to ObReferenceObject* should be IRP->RequestorMode (C28126)
+In a dispatch routine call to ObReferenceObjectByHandle or ObReferenceObjectByPointer, the driver is passing UserMode or KernelMode for the AccessMode parameter, instead of using Irp->RequestorMode.
+
+This check applies only to the top driver in the stack. It can be ignored or suppressed otherwise.
+
+
+## Recommendation
+The top-level driver in the driver stack should use Irp->RequestorMode, rather than specifying UserMode or KernelMode. This allows the senders of kernel-mode IRP to supply kernel-mode handles safely.
+
+
+## Example
+
+```c
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+//
+// driver_snippet.c
+//
+
+#define SET_DISPATCH 1
+#define SET_CUSTOM_CREATE
+
+_Dispatch_type_(IRP_MJ_PNP)
+DRIVER_DISPATCH DispatchPnp;
+_Dispatch_type_(IRP_MJ_READ)
+DRIVER_DISPATCH DispatchRead;
+
+// Template. Not called in this test.
+void top_level_call() {}
+
+_Dispatch_type_(IRP_MJ_CREATE)
+NTSTATUS
+DispatchCreate (
+ PDEVICE_OBJECT DeviceObject,
+ PIRP Irp
+ )
+{
+ ObReferenceObjectByPointer(NULL, 0, 0, KernelMode); // ERROR
+ ObReferenceObjectByPointer(NULL, 0, 0, Irp->RequestorMode); // GOOD
+ return STATUS_SUCCESS;
+}
+```
+
+## References
+* [ C28126 warning - Windows Drivers ](https://learn.microsoft.com/en-us/windows-hardware/drivers/devtest/28126-accessmode-param-incorrect)
diff --git a/src/drivers/wdm/queries/OpaqueMdlUse/OpaqueMdlUse.md b/src/drivers/wdm/queries/OpaqueMdlUse/OpaqueMdlUse.md
new file mode 100644
index 00000000..7f635f4d
--- /dev/null
+++ b/src/drivers/wdm/queries/OpaqueMdlUse/OpaqueMdlUse.md
@@ -0,0 +1,54 @@
+# Direct access of opaque MDL field
+Direct access of opaque MDL fields should be avoided, as opaque struct layouts may change without warning.
+
+
+## Recommendation
+Instead of accessing MDL fields directly, driver writers should make use of the [MmGetMdlVirtualAddress](https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-mmgetmdlvirtualaddress), [MmGetMdlByteCount](https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-mmgetmdlbytecount), [MmGetMdlByteOffset](https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-mmgetmdlbyteoffset), and [MmGetSystemAddressForMdlSafe](https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-mmgetsystemaddressformdlsafe) macros.
+
+
+## Example
+In this example, the driver directly accesses the ByteCount field of an MDL.
+
+```c
+
+ VOID DummyMdlFunction(PMDL Mdl)
+ {
+ PMDL currentMdl, nextMdl;
+
+ for (currentMdl = Mdl; currentMdl != NULL; currentMdl = nextMdl)
+ {
+ nextMdl = currentMdl->Next;
+ if (currentMdl->MdlFlags & MDL_PAGES_LOCKED && currentMdl->ByteCount > 0)
+ {
+ MmUnlockPages(currentMdl);
+ }
+ IoFreeMdl(currentMdl);
+ }
+ }
+
+
+```
+The driver should instead use the MmGetMdlByteCount function.
+
+```c
+
+ VOID DummyMdlFunction(PMDL Mdl)
+ {
+ PMDL currentMdl, nextMdl;
+
+ for (currentMdl = Mdl; currentMdl != NULL; currentMdl = nextMdl)
+ {
+ nextMdl = currentMdl->Next;
+ if (currentMdl->MdlFlags & MDL_PAGES_LOCKED && MmGetMdlByteCount(currentMdl) > 0)
+ {
+ MmUnlockPages(currentMdl);
+ }
+ IoFreeMdl(currentMdl);
+ }
+ }
+
+
+```
+
+## References
+* [ Using MDLs (MSDN) ](https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/using-mdls)
diff --git a/src/drivers/wdm/queries/OpaqueMdlWrite/OpaqueMdlWrite.md b/src/drivers/wdm/queries/OpaqueMdlWrite/OpaqueMdlWrite.md
new file mode 100644
index 00000000..4958e177
--- /dev/null
+++ b/src/drivers/wdm/queries/OpaqueMdlWrite/OpaqueMdlWrite.md
@@ -0,0 +1,34 @@
+# Write to opaque MDL field (C28145)
+Drivers should not write to opaque MDL fields.
+
+
+## Recommendation
+If the driver is using an MDL in an NDIS driver, you can call the [NdisAdjustMdlLength](https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ndis/nf-ndis-ndisadjustmdllength) macro to modify the length of the data that is associated with an MDL. Otherwise, you should avoid modifying MDL fields after creation.
+
+
+## Example
+In this example, the driver directly edits the ByteCount field of the MDL. This should not be directly edited.
+
+```c
+
+ VOID DummyMdlFunction(PMDL Mdl)
+ {
+ PMDL currentMdl, nextMdl;
+
+ for (currentMdl = Mdl; currentMdl != NULL; currentMdl = nextMdl)
+ {
+ nextMdl = currentMdl->Next;
+ if (currentMdl->MdlFlags & MDL_PAGES_LOCKED && currentMdl->ByteCount > 0)
+ {
+ MmUnlockPages(currentMdl);
+ }
+ IoFreeMdl(currentMdl);
+ }
+ }
+
+
+```
+
+## References
+* [ Using MDLs (MSDN) ](https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/using-mdls)
+* [ C28145 (Code Analysis for Drivers) ](https://docs.microsoft.com/en-us/windows-hardware/drivers/devtest/28145-opaque-mdl-structure-should-not-be-modified)
diff --git a/src/drivers/wdm/queries/PendingStatusError/PendingStatusError.md b/src/drivers/wdm/queries/PendingStatusError/PendingStatusError.md
new file mode 100644
index 00000000..3310a84c
--- /dev/null
+++ b/src/drivers/wdm/queries/PendingStatusError/PendingStatusError.md
@@ -0,0 +1,32 @@
+# Did not return STATUS_PENDING after IoMarkIrpPending call
+A dispatch routine that calls IoMarkIrpPending must also return STATUS_PENDING
+
+
+## Recommendation
+A dispatch routine that calls IoMarkIrpPending includes at least one path in which the driver returns a value other than STATUS_PENDING. The IoMarkIrpPending routine marks the specified IRP, indicating that a driver's dispatch routine subsequently returned STATUS_PENDING because further processing is required by other driver routines.
+
+
+## Example
+In this example, the driver marks an IRP pending but returns STATUS_SUCCESS.
+
+```c
+
+ IoMarkIrpPending(Irp);
+ ...
+ return STATUS_SUCCESS;
+
+
+```
+The driver should instead ensure that it returns STATUS_PENDING.
+
+```c
+
+ IoMarkIrpPending(Irp);
+ ...
+ return STATUS_PENDING;
+
+
+```
+
+## References
+* [ C28143 warning - Windows Drivers ](https://docs.microsoft.com/en-us/windows-hardware/drivers/devtest/28143-iomarkirppending-must-return-statuspending)
diff --git a/src/drivers/wdm/queries/WrongDispatchTableAssignment/WrongDispatchTableAssignment.md b/src/drivers/wdm/queries/WrongDispatchTableAssignment/WrongDispatchTableAssignment.md
new file mode 100644
index 00000000..0a8576b7
--- /dev/null
+++ b/src/drivers/wdm/queries/WrongDispatchTableAssignment/WrongDispatchTableAssignment.md
@@ -0,0 +1,33 @@
+# Incorrect dispatch table assignment
+The dispatch table assignment satisfies any of these 3 scenarios: 1) The dispatch table assignment has a function whose type is not DRIVER_DISPATCH, or 2) The dispatch table assignment has a DRIVER_DISPATCH function at its right-hand side but the function doesn't have a driver dispatch type annotation, or 3) The dispatch function satisfies both of the above conditions but its dispatch type doesn't match the expected type for the dispatch table entry.
+
+
+## Recommendation
+This defect can be corrected either using a DRIVER_DISPATCH type function or by adding a _Dispatch_type_ annotation to the function or correcting the dispatch table entry being used.
+
+
+## Example
+In this example, the driver has a DRIVER_DISPATCH routine that is not annotated with the type(s) of IRP it handles.
+
+```c
+
+ DRIVER_DISPATCH SampleCreate;
+ ...
+ pDo->MajorFunction[IRP_MJ_CREATE] = SampleCreate;
+
+
+```
+The driver should instead annotate its dispatch routines appropriately.
+
+```c
+
+ _Dispatch_type_(IRP_MJ_CREATE) DRIVER_DISPATCH SampleCreate;
+ ...
+ pDo->MajorFunction[IRP_MJ_CREATE] = SampleCreate;...
+
+
+```
+
+## References
+* [ C28168 warning - Windows Drivers ](https://docs.microsoft.com/en-us/windows-hardware/drivers/devtest/28168-dispatch-function-dispatch-annotation)
+* [ C28169 warning - Windows Drivers ](https://docs.microsoft.com/en-us/windows-hardware/drivers/devtest/28169-dispatch-function-does-not-have-proper-annotation)
diff --git a/src/microsoft/Likely Bugs/Boundary Violations/PaddingByteInformationDisclosure.md b/src/microsoft/Likely Bugs/Boundary Violations/PaddingByteInformationDisclosure.md
new file mode 100644
index 00000000..a7ba501e
--- /dev/null
+++ b/src/microsoft/Likely Bugs/Boundary Violations/PaddingByteInformationDisclosure.md
@@ -0,0 +1,46 @@
+# Possible information leakage from uninitialized padding bytes.
+A newly allocated struct or class that is initialized member-by-member may leak information if it includes padding bytes.
+
+
+## Recommendation
+Make sure that all padding bytes in the struct or class are initialized.
+
+If possible, use `memset` to initialize the whole structure/class.
+
+
+## Example
+The following example shows a scenario where padding between the first and second elements are not initialized.
+
+
+```c
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+
+typedef enum { Unknown = 0, Known = 1, Other = 2 } MyStructType;
+struct MyStruct { MyStructType type; UINT64 id; };
+
+MyStruct testReturn()
+{
+ // BAD: Padding between the first and second elements not initialized.
+ MyStruct myBadStackStruct = { Unknown };
+ return myBadStackStruct;
+}
+```
+To correct it, we will initialize all bytes using `memset`.
+
+
+```c
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+
+typedef enum { Unknown = 0, Known = 1, Other = 2 } MyStructType;
+struct MyStruct { MyStructType type; UINT64 id; };
+
+MyStruct testReturn()
+{
+ // GOOD: All padding bytes initialized
+ MyStruct* myGoodHeapStruct = (struct MyStruct*)malloc(sizeof(struct MyStruct));
+ memset(myGoodHeapStruct, 0, sizeof(struct MyStruct));
+ return *myGoodHeapStruct;
+}
+```
diff --git a/src/microsoft/Likely Bugs/Conversion/BadOverflowGuard.md b/src/microsoft/Likely Bugs/Conversion/BadOverflowGuard.md
new file mode 100644
index 00000000..23b81aed
--- /dev/null
+++ b/src/microsoft/Likely Bugs/Conversion/BadOverflowGuard.md
@@ -0,0 +1,44 @@
+# Bad overflow check
+Checking for overflow of an addition by comparing against one of the arguments of the addition fails if the size of all the argument types are smaller than 4 bytes. This is because the result of the addition is promoted to a 4 byte int.
+
+
+## Recommendation
+Check the overflow by comparing the addition against a value that is at least 4 bytes.
+
+
+## Example
+In this example, the result of the comparison will result in an integer overflow.
+
+
+```c
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+
+unsigned short CheckForInt16OverflowBadCode(unsigned short v, unsigned short b)
+{
+ if (v + b < v) // BUG: "v + b" will be promoted to 32 bits
+ {
+ // ... do something
+ }
+
+ return v + b;
+}
+
+```
+To fix the bug, check the overflow by comparing the addition against a value that is at least 4 bytes.
+
+
+```c
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+
+unsigned short CheckForInt16OverflowCorrectCode(unsigned short v, unsigned short b)
+{
+ if (v + b > 0x00FFFF)
+ {
+ // ... do something
+ }
+
+ return v + b;
+}
+```
diff --git a/src/microsoft/Likely Bugs/Conversion/InfiniteLoop.md b/src/microsoft/Likely Bugs/Conversion/InfiniteLoop.md
new file mode 100644
index 00000000..c52e4e8c
--- /dev/null
+++ b/src/microsoft/Likely Bugs/Conversion/InfiniteLoop.md
@@ -0,0 +1,40 @@
+# Comparison of narrow type with wide type in loop condition
+Comparisons between types of different widths in a loop condition can cause the loop to fail to terminate.
+
+
+## Recommendation
+Use appropriate types in the loop condition.
+
+
+## Example
+In this example, the result of the comparison may result in an infinite loop if the value for argument `a` is larger than `SHRT_MAX`.
+
+
+```c
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+
+void InfiniteLoop(int a)
+{
+ for (short i = 0; i < a; i++) // BUG: infinite loop
+ {
+ // ...
+ }
+}
+
+```
+To fix the bug, we are changing the type for the variable `i` to match the width of `a`.
+
+
+```c
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+
+void NotInfiniteLoop(int a)
+{
+ for (int i = 0; i < a; i++)
+ {
+ // ...
+ }
+}
+```
diff --git a/src/microsoft/Likely Bugs/Memory Management/UseAfterFree/ProbableUseAfterFree.md b/src/microsoft/Likely Bugs/Memory Management/UseAfterFree/ProbableUseAfterFree.md
new file mode 100644
index 00000000..4dd8b81b
--- /dev/null
+++ b/src/microsoft/Likely Bugs/Memory Management/UseAfterFree/ProbableUseAfterFree.md
@@ -0,0 +1,66 @@
+# Potential use after free (low precision, for drivers)
+This version of the query has lower precision than `cpp/use-after-free-high-precision`. It detects some additional scenarios, but also has a higher rate of false positives.
+
+An allocated memory block is used after it has been freed (also known as dangling pointer).
+
+Behavior in such cases is undefined and in practice can have many unintended consequences including memory corruption, use incorrect values, or arbitrary code execution.
+
+
+## Recommendation
+If possible set the pointers to NULL immediately after they are freed.
+
+
+## Example
+In the following example, `pSomePointer` is freed only if `Status` value was not zero, and before deferrencing `pSomePointer` to call `Method`, we check again `Status`; unfortunately `Status` was changed between the two references to `pSomePointer`, which allows for the possiblity that the call to `pSomePointer->Method()` is being performed over a previously freed pointer.
+
+
+```c
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+
+NTSTATUS Status = x();
+
+if (Status != 0)
+{
+ // Release pSomePointer if the call to x() failed
+
+ ExFreePool(pSomePointer);
+}
+
+Status = y();
+
+if (Status == 0)
+{
+ // Because Status may no longer be the same value than it was before the pointer was released,
+ // this code may be using pSomePointer after it was freed, potentially executing arbitrary code.
+
+ Status = pSomePointer->Method();
+}
+```
+In the corrected example, `pSomePointer` is set to `NULL` immediately after being freed, and the condition to check if it is safe to call `pSomePointer->Method()` checks for this additional condition to prevent the possible bug.
+
+
+```c
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+
+NTSTATUS Status = x();
+
+if (Status != 0)
+{
+ // Release pSomePointer if the call to x() failed
+
+ ExFreePool(pSomePointer);
+
+ // Setting pSomePointer to NULL after being freed
+ pSomePointer = NULL;
+}
+
+Status = y();
+
+// If pSomePointer was freed above, its value must have been set to NULL
+if (Status == 0 && pSomePointer != NULL)
+{
+ Status = pSomePointer->Method();
+}
+```
diff --git a/src/microsoft/Likely Bugs/Memory Management/UseAfterFree/UseAfterFree.md b/src/microsoft/Likely Bugs/Memory Management/UseAfterFree/UseAfterFree.md
new file mode 100644
index 00000000..9435d166
--- /dev/null
+++ b/src/microsoft/Likely Bugs/Memory Management/UseAfterFree/UseAfterFree.md
@@ -0,0 +1,66 @@
+# Potential use after free (high precision, for drivers)
+This version of the query has high precision, which helps in bug automation, but there are some limitations and therefore it will not be able to detect some cases.
+
+An allocated memory block is used after it has been freed (also known as dangling pointer).
+
+Behavior in such cases is undefined and in practice can have many unintended consequences including memory corruption, use incorrect values, or arbitrary code execution.
+
+
+## Recommendation
+If possible set the pointers to NULL immediately after they are freed.
+
+
+## Example
+In the following example, `pSomePointer` is freed only if `Status` value was not zero, and before deferrencing `pSomePointer` to call `Method`, we check again `Status`; unfortunately `Status` was changed between the two references to `pSomePointer`, which allows for the possiblity that the call to `pSomePointer->Method()` is being performed over a previously freed pointer.
+
+
+```c
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+
+NTSTATUS Status = x();
+
+if (Status != 0)
+{
+ // Release pSomePointer if the call to x() failed
+
+ ExFreePool(pSomePointer);
+}
+
+Status = y();
+
+if (Status == 0)
+{
+ // Because Status may no longer be the same value than it was before the pointer was released,
+ // this code may be using pSomePointer after it was freed, potentially executing arbitrary code.
+
+ Status = pSomePointer->Method();
+}
+```
+In the corrected example, `pSomePointer` is set to `NULL` immediately after being freed, and the condition to check if it is safe to call `pSomePointer->Method()` checks for this additional condition to prevent the possible bug.
+
+
+```c
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+
+NTSTATUS Status = x();
+
+if (Status != 0)
+{
+ // Release pSomePointer if the call to x() failed
+
+ ExFreePool(pSomePointer);
+
+ // Setting pSomePointer to NULL after being freed
+ pSomePointer = NULL;
+}
+
+Status = y();
+
+// If pSomePointer was freed above, its value must have been set to NULL
+if (Status == 0 && pSomePointer != NULL)
+{
+ Status = pSomePointer->Method();
+}
+```
diff --git a/src/microsoft/Likely Bugs/UninitializedPtrField.md b/src/microsoft/Likely Bugs/UninitializedPtrField.md
new file mode 100644
index 00000000..cf55d277
--- /dev/null
+++ b/src/microsoft/Likely Bugs/UninitializedPtrField.md
@@ -0,0 +1,122 @@
+# Dereference of potentially uninitialized pointer field
+A pointer field which was not initialized during or since class construction will cause a null pointer dereference.
+
+
+## Recommendation
+Make sure to initialize all pointer fields before usage.
+
+
+## Example
+The following example shows a scenario where the field `ptr_` is not initialzied and later dereferenced.
+
+
+```c
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+
+template
+class ComPtr
+{
+public:
+ T* ptr_;
+
+ ComPtr() throw() : ptr_(nullptr)
+ {
+ }
+
+ ComPtr(T* ptr) throw() : ptr_(ptr)
+ {
+ }
+
+ T* operator->() const throw()
+ {
+ return ptr_;
+ }
+
+ void set(T* ptr) {
+ ptr_ = ptr;
+ }
+
+ T** addr() {
+ return &ptr_;
+ }
+};
+
+class Test
+{
+public:
+ int it_;
+ int it() {
+ return it_;
+ }
+};
+
+void test() {
+ Test t;
+ int val;
+
+ ComPtr ptr;
+ // BAD: pointer is not initialized here
+ val = ptr->it();
+}
+
+```
+To correct the problem, we set the field before usage.
+
+
+```c
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+
+template
+class ComPtr
+{
+public:
+ T* ptr_;
+
+ ComPtr() throw() : ptr_(nullptr)
+ {
+ }
+
+ ComPtr(T* ptr) throw() : ptr_(ptr)
+ {
+ }
+
+ T* operator->() const throw()
+ {
+ return ptr_;
+ }
+
+ void set(T* ptr) {
+ ptr_ = ptr;
+ }
+
+ T** addr() {
+ return &ptr_;
+ }
+};
+
+class Test
+{
+public:
+ int it_;
+ int it() {
+ return it_;
+ }
+};
+
+void test() {
+ Test t;
+ int val;
+
+ ComPtr ptr2(&t);
+ // GOOD: pointer was initialized
+ val = ptr2->it();
+
+ ComPtr ptr3;
+ ptr3.set(&t);
+ // GOOD: pointer was set in between
+ val = ptr3->it();
+}
+
+```
diff --git a/src/microsoft/Security/CWE/CWE-704/WcharCharConversionLimited.md b/src/microsoft/Security/CWE/CWE-704/WcharCharConversionLimited.md
new file mode 100644
index 00000000..a31600b0
--- /dev/null
+++ b/src/microsoft/Security/CWE/CWE-704/WcharCharConversionLimited.md
@@ -0,0 +1,32 @@
+# Cast from char* to wchar_t* (ignore PUCHAR casts)
+This rule indicates a potentially incorrect cast from an byte string (`char *`) to a wide-character string (`wchar_t *`).
+
+This cast might yield strings that are not correctly terminated; including potential buffer overruns when using such strings with some dangerous APIs.
+
+This version of the query is a subset of the GitHub query with ID `>cpp/incorrect-string-type-conversion` that limits the detection of `PUCHAR` casting to avoid certain commonly used patterns.
+
+
+## Recommendation
+Do not explicitly cast byte strings to wide-character strings.
+
+For string literals, prepend the literal string with the letter "L" to indicate that the string is a wide-character string (`wchar_t *`).
+
+For converting a byte literal to a wide-character string literal, you would need to use the appropriate conversion function for the platform you are using. Please see the references section for options according to your platform.
+
+
+## Example
+In the following example, an byte string literal (`"a"`) is cast to a wide-character string.
+
+
+```cpp
+wchar_t* pSrc;
+
+pSrc = (wchar_t*)"a"; // casting a byte-string literal "a" to a wide-character string
+```
+To fix this issue, prepend the literal with the letter "L" (`L"a"`) to define it as a wide-character string.
+
+
+## References
+* General resources: [std::mbstowcs](https://en.cppreference.com/w/cpp/string/multibyte/mbstowcs)
+* Microsoft specific resources: [Security Considerations: International Features](https://docs.microsoft.com/en-us/windows/desktop/Intl/security-considerations--international-features)
+* Common Weakness Enumeration: [CWE-704](https://cwe.mitre.org/data/definitions/704.html).
diff --git a/src/microsoft/Security/Crytpography/HardcodedIVCNG.md b/src/microsoft/Security/Crytpography/HardcodedIVCNG.md
new file mode 100644
index 00000000..69a68e71
--- /dev/null
+++ b/src/microsoft/Security/Crytpography/HardcodedIVCNG.md
@@ -0,0 +1,15 @@
+# Weak cryptography
+An initialization vector (IV) is an input to a cryptographic primitive being used to provide the initial state. The IV is typically required to be random or pseudorandom (randomized scheme), but sometimes an IV only needs to be unpredictable or unique (stateful scheme).
+
+Randomization is crucial for some encryption schemes to achieve semantic security, a property whereby repeated usage of the scheme under the same key does not allow an attacker to infer relationships between (potentially similar) segments of the encrypted message.
+
+
+## Recommendation
+All symmetric block ciphers must also be used with an appropriate initialization vector (IV) according to the mode of operation being used.
+
+If using a randomized scheme such as CBC, it is recommended to use cryptographically secure pseudorandom number generator such as `BCryptGenRandom`.
+
+
+## References
+* [BCryptEncrypt function (bcrypt.h)](https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptencrypt) [BCryptGenRandom function (bcrypt.h)](https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom) [Initialization vector (Wikipedia)](https://en.wikipedia.org/wiki/Initialization_vector)
+* Common Weakness Enumeration: [CWE-327](https://cwe.mitre.org/data/definitions/327.html).